Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sannis/807678 to your computer and use it in GitHub Desktop.
Save Sannis/807678 to your computer and use it in GitHub Desktop.
Patch for node-mysql-libmysqlclient
From d4c7910b800fb5d521b9b870ee396a858e1d01b5 Mon Sep 17 00:00:00 2001
From: Oleg Efimov <efimovov@gmail.com>
Date: Wed, 2 Feb 2011 16:19:48 +0300
Subject: [PATCH] Fix wrong gmt_delta calculation in datetime casting, closes #72
---
src/mysql_bindings_result.cc | 20 ++++++++++++++++----
tests/complex/test-datatypes-cast.js | 32 ++++++++++++++++++++++++--------
2 files changed, 40 insertions(+), 12 deletions(-)
diff --git a/src/mysql_bindings_result.cc b/src/mysql_bindings_result.cc
index db2ea4c..f7ad0ba 100644
--- a/src/mysql_bindings_result.cc
+++ b/src/mysql_bindings_result.cc
@@ -133,7 +133,7 @@ Local<Value> MysqlResult::GetFieldValue(MYSQL_FIELD field, char* field_value, un
int h1 = 0, h2 = 0, m1 = 0, m2 = 0;
sscanf(field_value, "%d-%d-%d %d:%d:%d",
&year, &month, &day, &hour, &min, &sec);
- time_t rawtime, gmt_delta;
+ time_t rawtime;
struct tm timeinfo;
time(&rawtime);
if (!localtime_r(&rawtime, &timeinfo)) {
@@ -148,7 +148,13 @@ Local<Value> MysqlResult::GetFieldValue(MYSQL_FIELD field, char* field_value, un
}
h2 = timeinfo.tm_hour;
m2 = timeinfo.tm_min;
- gmt_delta = (((h1 - h2)%24)*60 + (m1-m2))*60;
+ int gmt_delta = ((h1 - h2)*60 + (m1-m2))*60;
+ if (gmt_delta <= -12*60*60) {
+ gmt_delta += 24*60*60;
+ }
+ if (gmt_delta > 12*60*60) {
+ gmt_delta -= 24*60*60;
+ }
timeinfo.tm_year = year - 1900;
timeinfo.tm_mon = month - 1;
timeinfo.tm_mday = day;
@@ -166,7 +172,7 @@ Local<Value> MysqlResult::GetFieldValue(MYSQL_FIELD field, char* field_value, un
int year = 0, month = 0, day = 0;
int h1 = 0, h2 = 0, m1 = 0, m2 = 0;
sscanf(field_value, "%d-%d-%d", &year, &month, &day);
- time_t rawtime, gmt_delta;
+ time_t rawtime;
struct tm timeinfo;
time(&rawtime);
if (!localtime_r(&rawtime, &timeinfo)) {
@@ -181,7 +187,13 @@ Local<Value> MysqlResult::GetFieldValue(MYSQL_FIELD field, char* field_value, un
}
h2 = timeinfo.tm_hour;
m2 = timeinfo.tm_min;
- gmt_delta = (((h1 - h2)%24)*60 + (m1-m2))*60;
+ int gmt_delta = ((h1 - h2)*60 + (m1-m2))*60;
+ if (gmt_delta <= -12*60*60) {
+ gmt_delta += 24*60*60;
+ }
+ if (gmt_delta > 12*60*60) {
+ gmt_delta -= 24*60*60;
+ }
timeinfo.tm_year = year - 1900;
timeinfo.tm_mon = month - 1;
timeinfo.tm_mday = day;
diff --git a/tests/complex/test-datatypes-cast.js b/tests/complex/test-datatypes-cast.js
index 9664ef1..38669f9 100644
--- a/tests/complex/test-datatypes-cast.js
+++ b/tests/complex/test-datatypes-cast.js
@@ -13,7 +13,7 @@ var
mysql_libmysqlclient = require("../../mysql-libmysqlclient");
exports.fetchDateAndTimeValues = function (test) {
- test.expect(9);
+ test.expect(17);
var
conn = mysql_libmysqlclient.createConnectionSync(cfg.host, cfg.user, cfg.password, cfg.database),
@@ -24,19 +24,35 @@ exports.fetchDateAndTimeValues = function (test) {
rows = conn.querySync("SELECT CAST('2 2:50' AS TIME) as time;").fetchAllSync();
test.ok(rows[0].time instanceof Date, "SELECT CAST('2 2:50' AS TIME) is Date");
test.equals(rows[0].time.toUTCString(), "Sat, 03 Jan 1970 02:50:00 GMT", "SELECT CAST('2 2:50' AS TIME) is correct");
-
+
rows = conn.querySync("SELECT CAST('2000-01-01' AS DATE) as date;").fetchAllSync();
test.ok(rows[0].date instanceof Date, "SELECT CAST('2000-01-01' AS DATE) is Date");
test.equals(rows[0].date.toUTCString(), "Sat, 01 Jan 2000 00:00:00 GMT", "SELECT CAST('2000-01-01' AS DATE) is correct");
-
+
rows = conn.querySync("SELECT CAST('1988-10-25 06:34' AS DATETIME) as datetime;").fetchAllSync();
test.ok(rows[0].datetime instanceof Date, "SELECT CAST('1988-10-25 06:34' AS DATETIME) is Date");
test.equals(rows[0].datetime.toUTCString(), "Tue, 25 Oct 1988 06:34:00 GMT", "SELECT CAST('1988-10-25 06:34' AS DATETIME) is correct");
-
+
rows = conn.querySync("SELECT CAST('1988-10-25' AS DATETIME) as datetime;").fetchAllSync();
test.ok(rows[0].datetime instanceof Date, "SELECT CAST('1988-10-25' AS DATETIME) is Date");
test.equals(rows[0].datetime.toUTCString(), "Tue, 25 Oct 1988 00:00:00 GMT", "SELECT CAST('1988-10-25' AS DATETIME) is correct");
-
+
+ rows = conn.querySync("SELECT CAST('1988-10-25 2:50' AS DATETIME) as datetime;").fetchAllSync();
+ test.ok(rows[0].datetime instanceof Date, "SELECT CAST('1988-10-25 2:50' AS DATETIME) is Date");
+ test.equals(rows[0].datetime.toUTCString(), "Tue, 25 Oct 1988 02:50:00 GMT", "SELECT CAST('1988-10-25 2:50' AS TIME) is correct");
+
+ rows = conn.querySync("SELECT CAST('1988-10-25 3:50' AS DATETIME) as datetime;").fetchAllSync();
+ test.ok(rows[0].datetime instanceof Date, "SELECT CAST('1988-10-25 3:50' AS DATETIME) is Date");
+ test.equals(rows[0].datetime.toUTCString(), "Tue, 25 Oct 1988 03:50:00 GMT", "SELECT CAST('1988-10-25 3:50' AS TIME) is correct");
+
+ rows = conn.querySync("SELECT CAST('1988-10-25 23:50' AS DATETIME) as datetime;").fetchAllSync();
+ test.ok(rows[0].datetime instanceof Date, "SELECT CAST('1988-10-25 23:50' AS DATETIME) is Date");
+ test.equals(rows[0].datetime.toUTCString(), "Tue, 25 Oct 1988 23:50:00 GMT", "SELECT CAST('1988-10-25 23:50' AS TIME) is correct");
+
+ rows = conn.querySync("SELECT CAST('1988-10-25 18:50' AS DATETIME) as datetime;").fetchAllSync();
+ test.ok(rows[0].datetime instanceof Date, "SELECT CAST('1988-10-25 18:50' AS DATETIME) is Date");
+ test.equals(rows[0].datetime.toUTCString(), "Tue, 25 Oct 1988 18:50:00 GMT", "SELECT CAST('1988-10-25 18:50' AS TIME) is correct");
+
conn.closeSync();
test.done();
@@ -50,15 +66,15 @@ exports.fetchSetValues = function (test) {
rows;
test.ok(conn, "mysql_libmysqlclient.createConnectionSync(host, user, password, database)");
-
+
rows = conn.querySync("SELECT size, colors FROM " + cfg.test_table + " WHERE size='small';").fetchAllSync();
test.ok(rows[0].colors instanceof Array, "SET fetched result is Array");
test.same(rows[0].colors, ['red'], "SET fetched result is correct");
-
+
rows = conn.querySync("SELECT size, colors FROM " + cfg.test_table + " WHERE size='medium';").fetchAllSync();
test.ok(rows[0].colors instanceof Array, "SET fetched result is Array");
test.same(rows[0].colors, ['red', 'green', 'blue'], "SET fetched result is correct");
-
+
conn.closeSync();
test.done();
--
1.7.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment