convert :timezone option into two new ones
:database_timezone - the timezone (:utc or :local) Mysql2 will assume time/datetime fields are stored in the db. This modifies what initial timezone your Time objects will be in when creating them from libmysql in C and :application_timezone - the timezone (:utc or :local) you'd finally like the Time objects converted to before you get them
This commit is contained in:
parent
1bdf44ce7f
commit
ad34357e57
@ -8,9 +8,10 @@ VALUE cMysql2Result;
|
|||||||
VALUE cBigDecimal, cDate, cDateTime;
|
VALUE cBigDecimal, cDate, cDateTime;
|
||||||
extern VALUE mMysql2, cMysql2Client, cMysql2Error;
|
extern VALUE mMysql2, cMysql2Client, cMysql2Error;
|
||||||
static VALUE intern_encoding_from_charset;
|
static VALUE intern_encoding_from_charset;
|
||||||
static ID intern_new, intern_utc, intern_local, intern_encoding_from_charset_code;
|
static ID intern_new, intern_utc, intern_local, intern_encoding_from_charset_code,
|
||||||
static ID sym_symbolize_keys, sym_as, sym_array, sym_timezone, sym_local, sym_utc,
|
intern_localtime;
|
||||||
sym_cast_booleans;
|
static ID sym_symbolize_keys, sym_as, sym_array, sym_database_timezone, sym_application_timezone,
|
||||||
|
sym_local, sym_utc, sym_cast_booleans;
|
||||||
static ID intern_merge;
|
static ID intern_merge;
|
||||||
|
|
||||||
static void rb_mysql_result_mark(void * wrapper) {
|
static void rb_mysql_result_mark(void * wrapper) {
|
||||||
@ -87,7 +88,7 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, short int
|
|||||||
return rb_field;
|
return rb_field;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE rb_mysql_result_fetch_row(VALUE self, ID timezone, int symbolizeKeys, int asArray, int castBool) {
|
static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezone, int symbolizeKeys, int asArray, int castBool) {
|
||||||
VALUE rowVal;
|
VALUE rowVal;
|
||||||
mysql2_result_wrapper * wrapper;
|
mysql2_result_wrapper * wrapper;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
@ -154,7 +155,14 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID timezone, int symbolizeKey
|
|||||||
case MYSQL_TYPE_TIME: { // TIME field
|
case MYSQL_TYPE_TIME: { // TIME field
|
||||||
int hour, min, sec, tokens;
|
int hour, min, sec, tokens;
|
||||||
tokens = sscanf(row[i], "%2d:%2d:%2d", &hour, &min, &sec);
|
tokens = sscanf(row[i], "%2d:%2d:%2d", &hour, &min, &sec);
|
||||||
val = rb_funcall(rb_cTime, timezone, 6, INT2NUM(2000), INT2NUM(1), INT2NUM(1), INT2NUM(hour), INT2NUM(min), INT2NUM(sec));
|
val = rb_funcall(rb_cTime, db_timezone, 6, INT2NUM(2000), INT2NUM(1), INT2NUM(1), INT2NUM(hour), INT2NUM(min), INT2NUM(sec));
|
||||||
|
if (!NIL_P(app_timezone)) {
|
||||||
|
if (app_timezone == intern_local) {
|
||||||
|
val = rb_funcall(val, intern_localtime, 0);
|
||||||
|
} else { // utc
|
||||||
|
val = rb_funcall(val, intern_utc, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_TIMESTAMP: // TIMESTAMP field
|
case MYSQL_TYPE_TIMESTAMP: // TIMESTAMP field
|
||||||
@ -168,7 +176,14 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID timezone, int symbolizeKey
|
|||||||
rb_raise(cMysql2Error, "Invalid date: %s", row[i]);
|
rb_raise(cMysql2Error, "Invalid date: %s", row[i]);
|
||||||
val = Qnil;
|
val = Qnil;
|
||||||
} else {
|
} else {
|
||||||
val = rb_funcall(rb_cTime, timezone, 6, INT2NUM(year), INT2NUM(month), INT2NUM(day), INT2NUM(hour), INT2NUM(min), INT2NUM(sec));
|
val = rb_funcall(rb_cTime, db_timezone, 6, INT2NUM(year), INT2NUM(month), INT2NUM(day), INT2NUM(hour), INT2NUM(min), INT2NUM(sec));
|
||||||
|
if (!NIL_P(app_timezone)) {
|
||||||
|
if (app_timezone == intern_local) {
|
||||||
|
val = rb_funcall(val, intern_localtime, 0);
|
||||||
|
} else { // utc
|
||||||
|
val = rb_funcall(val, intern_utc, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -267,8 +282,8 @@ static VALUE rb_mysql_result_fetch_fields(VALUE self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
||||||
VALUE defaults, opts, block, timezoneVal;
|
VALUE defaults, opts, block;
|
||||||
ID timezone;
|
ID db_timezone, app_timezone, dbTz, appTz;
|
||||||
mysql2_result_wrapper * wrapper;
|
mysql2_result_wrapper * wrapper;
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
int symbolizeKeys = 0, asArray = 0, castBool = 0;
|
int symbolizeKeys = 0, asArray = 0, castBool = 0;
|
||||||
@ -294,14 +309,28 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
|||||||
castBool = 1;
|
castBool = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
timezoneVal = rb_hash_aref(opts, sym_timezone);
|
dbTz = rb_hash_aref(opts, sym_database_timezone);
|
||||||
if (timezoneVal == sym_local) {
|
if (dbTz == sym_local) {
|
||||||
timezone = intern_local;
|
db_timezone = intern_local;
|
||||||
} else if (timezoneVal == sym_utc) {
|
} else if (dbTz == sym_utc) {
|
||||||
timezone = intern_utc;
|
db_timezone = intern_utc;
|
||||||
} else {
|
} else {
|
||||||
rb_warn(":timezone config option must be :utc or :local - defaulting to :local");
|
if (!NIL_P(dbTz)) {
|
||||||
timezone = intern_local;
|
rb_warn(":database_timezone option must be :utc or :local - defaulting to :local");
|
||||||
|
}
|
||||||
|
db_timezone = intern_local;
|
||||||
|
}
|
||||||
|
|
||||||
|
appTz = rb_hash_aref(opts, sym_application_timezone);
|
||||||
|
if (appTz == sym_local) {
|
||||||
|
app_timezone = intern_local;
|
||||||
|
} else if (appTz == sym_utc) {
|
||||||
|
app_timezone = intern_utc;
|
||||||
|
} else {
|
||||||
|
if (!NIL_P(appTz)) {
|
||||||
|
rb_warn(":application_timezone option must be :utc or :local - defaulting to :local");
|
||||||
|
}
|
||||||
|
app_timezone = intern_local;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wrapper->lastRowProcessed == 0) {
|
if (wrapper->lastRowProcessed == 0) {
|
||||||
@ -327,7 +356,7 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
|||||||
if (i < rowsProcessed) {
|
if (i < rowsProcessed) {
|
||||||
row = rb_ary_entry(wrapper->rows, i);
|
row = rb_ary_entry(wrapper->rows, i);
|
||||||
} else {
|
} else {
|
||||||
row = rb_mysql_result_fetch_row(self, timezone, symbolizeKeys, asArray, castBool);
|
row = rb_mysql_result_fetch_row(self, db_timezone, app_timezone, symbolizeKeys, asArray, castBool);
|
||||||
rb_ary_store(wrapper->rows, i, row);
|
rb_ary_store(wrapper->rows, i, row);
|
||||||
wrapper->lastRowProcessed++;
|
wrapper->lastRowProcessed++;
|
||||||
}
|
}
|
||||||
@ -383,14 +412,16 @@ void init_mysql2_result() {
|
|||||||
intern_utc = rb_intern("utc");
|
intern_utc = rb_intern("utc");
|
||||||
intern_local = rb_intern("local");
|
intern_local = rb_intern("local");
|
||||||
intern_merge = rb_intern("merge");
|
intern_merge = rb_intern("merge");
|
||||||
|
intern_localtime = rb_intern("localtime");
|
||||||
|
|
||||||
sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
|
sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
|
||||||
sym_as = ID2SYM(rb_intern("as"));
|
sym_as = ID2SYM(rb_intern("as"));
|
||||||
sym_array = ID2SYM(rb_intern("array"));
|
sym_array = ID2SYM(rb_intern("array"));
|
||||||
sym_timezone = ID2SYM(rb_intern("timezone"));
|
|
||||||
sym_local = ID2SYM(rb_intern("local"));
|
sym_local = ID2SYM(rb_intern("local"));
|
||||||
sym_utc = ID2SYM(rb_intern("utc"));
|
sym_utc = ID2SYM(rb_intern("utc"));
|
||||||
sym_cast_booleans = ID2SYM(rb_intern("cast_booleans"));
|
sym_cast_booleans = ID2SYM(rb_intern("cast_booleans"));
|
||||||
|
sym_database_timezone = ID2SYM(rb_intern("database_timezone"));
|
||||||
|
sym_application_timezone = ID2SYM(rb_intern("application_timezone"));
|
||||||
|
|
||||||
#ifdef HAVE_RUBY_ENCODING_H
|
#ifdef HAVE_RUBY_ENCODING_H
|
||||||
binaryEncoding = rb_enc_find("binary");
|
binaryEncoding = rb_enc_find("binary");
|
||||||
|
@ -2,11 +2,12 @@ module Mysql2
|
|||||||
class Client
|
class Client
|
||||||
attr_reader :query_options
|
attr_reader :query_options
|
||||||
@@default_query_options = {
|
@@default_query_options = {
|
||||||
:symbolize_keys => false,
|
|
||||||
:async => false,
|
|
||||||
:as => :hash,
|
:as => :hash,
|
||||||
:timezone => :local,
|
:async => false,
|
||||||
:cast_booleans => false
|
:cast_booleans => false,
|
||||||
|
:symbolize_keys => false,
|
||||||
|
:database_timezone => :local, # timezone Mysql2 will assume datetime objects are stored in
|
||||||
|
:application_timezone => :local # timezone Mysql2 will convert to before handing the object back to the caller
|
||||||
}
|
}
|
||||||
|
|
||||||
def initialize(opts = {})
|
def initialize(opts = {})
|
||||||
|
Loading…
Reference in New Issue
Block a user