ext/swift.cc in swift-0.4.2 vs ext/swift.cc in swift-0.4.3

- old
+ new

@@ -25,11 +25,11 @@ static VALUE fNew; static VALUE fRead; static VALUE fWrite; size_t tzoffset; -char errstr[8192]; +char errstr[8192]; #define CSTRING(v) RSTRING_PTR(TYPE(v) == T_STRING ? v : rb_funcall(v, fStringify, 0)) #define OBJ2STRING(v) (TYPE(v) == T_STRING ? v : rb_funcall(v, fStringify, 0)) #define EXCEPTION(type) (dbi::ConnectionError &e) { \ @@ -418,12 +418,12 @@ VALUE rb_field_typecast(VALUE adapter, int type, const char *data, ulong len) { time_t epoch, offset; struct tm tm; - char datetime[512], tzsign = ' '; - int hour = 0, min = 0, sec = 0, tzhour = 0, tzmin = 0; + char tzsign = ' '; + int tzhour = 0, tzmin = 0; double usec = 0; switch(type) { case DBI_TYPE_BOOLEAN: return strcmp(data, "t") == 0 || strcmp(data, "1") == 0 ? Qtrue : Qfalse; @@ -434,21 +434,28 @@ // forcing UTF8 convention here - do we really care about people using non utf8 // client encodings and databases ? case DBI_TYPE_TEXT: return rb_enc_str_new(data, len, rb_utf8_encoding()); case DBI_TYPE_TIME: - // if timestamp field has usec resolution, parse it. - if (strlen(data) > 19 && data[19] == '.') { - sscanf(data, "%s %d:%d:%d%lf%c%02d:%02d", - datetime, &hour, &min, &sec, &usec, &tzsign, &tzhour, &tzmin); + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + NOTE Flexibility sacrificed for performance. + Timestamp parser is very unforgiving and only parses + YYYY-MM-DD HH:MM:SS.ms[+-]HH:MM + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + memset(&tm, 0, sizeof(struct tm)); + if (strchr(data, '.')) { + sscanf(data, "%04d-%02d-%02d %02d:%02d:%02d%lf%c%02d:%02d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, + &usec, &tzsign, &tzhour, &tzmin); } else { - sscanf(data, "%s %d:%d:%d%c%02d:%02d", - datetime, &hour, &min, &sec, &tzsign, &tzhour, &tzmin); + sscanf(data, "%04d-%02d-%02d %02d:%02d:%02d%c%02d:%02d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, + &tzsign, &tzhour, &tzmin); } - sprintf(datetime, "%s %02d:%02d:%02d", datetime, hour, min, sec); - memset(&tm, 0, sizeof(struct tm)); - if (strptime(datetime, "%F %T", &tm)) { + tm.tm_year -= 1900; + tm.tm_mon -= 1; + if (tm.tm_mday > 0) { offset = tzoffset; epoch = mktime(&tm); if (tzsign == '+' || tzsign == '-') { offset += tzsign == '+' ? (time_t)tzhour * -3600 + (time_t)tzmin * -60