不要怂,就是干,撸起袖子干!

Commit c15977e3 by Jan Aagaard Meier

first attempt at converting all dates to utc

1 parent b37f5ff5
# v2.0.0 #
- [DEPENDENCIES] upgrade mysql to alpha7. You *MUST* use this version or newer for DATETIMEs to work
# v1.6.0 # # v1.6.0 #
- [DEPENDENCIES] upgraded most dependencies. most important: mysql was upgraded to 2.0.0-alpha-3 - [DEPENDENCIES] upgraded most dependencies. most important: mysql was upgraded to 2.0.0-alpha-3
- [REFACTORING] separated tests for dialects - [REFACTORING] separated tests for dialects
......
...@@ -56,7 +56,7 @@ module.exports = (function() { ...@@ -56,7 +56,7 @@ module.exports = (function() {
* *
* @param {Array} data - The result of the query execution. * @param {Array} data - The result of the query execution.
*/ */
AbstractQuery.prototype.formatResults = function(data) { AbstractQuery.prototype.formatResults = function(data, metaData) {
var result = this.callee var result = this.callee
if (isInsertQuery.call(this, data)) { if (isInsertQuery.call(this, data)) {
...@@ -64,7 +64,7 @@ module.exports = (function() { ...@@ -64,7 +64,7 @@ module.exports = (function() {
} }
if (isSelectQuery.call(this)) { if (isSelectQuery.call(this)) {
result = handleSelectQuery.call(this, data) result = handleSelectQuery.call(this, data, metaData)
} else if (isShowTableQuery.call(this)) { } else if (isShowTableQuery.call(this)) {
result = handleShowTableQuery.call(this, data) result = handleShowTableQuery.call(this, data)
} else if (isShowOrDescribeQuery.call(this)) { } else if (isShowOrDescribeQuery.call(this)) {
...@@ -226,12 +226,12 @@ module.exports = (function() { ...@@ -226,12 +226,12 @@ module.exports = (function() {
return (this.sql.toLowerCase().indexOf('update') === 0) return (this.sql.toLowerCase().indexOf('update') === 0)
} }
var handleSelectQuery = function(results) { var handleSelectQuery = function(results, metaData) {
var result = null, self = this; var result = null, self = this;
if (this.options.raw) { if (this.options.raw) {
result = results result = results
} else if (this.options.hasJoin === true) { } else if (this.options.hasJoin === true) {
result = prepareJoinData.call(this, results) result = prepareJoinData.call(this, results)
result = groupDataByCalleeFactory.call(this, result).map(function(result) { result = groupDataByCalleeFactory.call(this, result).map(function(result) {
// let's build the actual dao instance first... // let's build the actual dao instance first...
...@@ -251,7 +251,7 @@ module.exports = (function() { ...@@ -251,7 +251,7 @@ module.exports = (function() {
return this.callee.build(result, { isNewRecord: false }) return this.callee.build(result, { isNewRecord: false })
}.bind(this)) }.bind(this))
} }
// return the first real model instance if options.plain is set (e.g. Model.find) // return the first real model instance if options.plain is set (e.g. Model.find)
if (this.options.plain) { if (this.options.plain) {
result = (result.length === 0) ? null : result[0] result = (result.length === 0) ? null : result[0]
......
...@@ -243,6 +243,7 @@ module.exports = (function() { ...@@ -243,6 +243,7 @@ module.exports = (function() {
password: config.password, password: config.password,
database: config.database database: config.database
}) })
connection.query("SET time_zone = '+0:00'");
// client.setMaxListeners(self.maxConcurrentQueries) // client.setMaxListeners(self.maxConcurrentQueries)
this.isConnecting = false this.isConnecting = false
......
...@@ -23,13 +23,21 @@ module.exports = (function() { ...@@ -23,13 +23,21 @@ module.exports = (function() {
this.options.logging('Executing: ' + this.sql) this.options.logging('Executing: ' + this.sql)
} }
this.client.query(this.sql, function(err, results, fields) { this.client.query({
sql: this.sql,
typeCast: function (field, next) {
if (field.type == 'DATETIME') {
return new Date(field.string()+'Z')
}
return next();
}
}, function(err, results, fields) {
this.emit('sql', this.sql) this.emit('sql', this.sql)
if (err) { if (err) {
this.emit('error', err, this.callee) this.emit('error', err, this.callee)
} else { } else {
this.emit('success', this.formatResults(results)) this.emit('success', this.formatResults(results, fields))
} }
}.bind(this)).setMaxListeners(100) }.bind(this)).setMaxListeners(100)
return this return this
...@@ -37,3 +45,5 @@ module.exports = (function() { ...@@ -37,3 +45,5 @@ module.exports = (function() {
return Query return Query
})() })()
...@@ -51,7 +51,7 @@ function padInt(i) { ...@@ -51,7 +51,7 @@ function padInt(i) {
function pgSqlDate(dt) { function pgSqlDate(dt) {
var date = [ dt.getUTCFullYear(), padInt(dt.getUTCMonth()+1), padInt(dt.getUTCDate()) ].join('-') var date = [ dt.getUTCFullYear(), padInt(dt.getUTCMonth()+1), padInt(dt.getUTCDate()) ].join('-')
var time = [ dt.getUTCHours(), padInt(dt.getUTCMinutes()), padInt(dt.getUTCSeconds())].join(':') var time = [ dt.getUTCHours(), padInt(dt.getUTCMinutes()), padInt(dt.getUTCSeconds())].join(':')
return date + ' ' + time + '.' + ((dt.getTime() % 1000) * 1000) return date + ' ' + time + '.' + ((dt.getTime() % 1000) * 1000) + 'Z'
} }
function pgDataTypeMapping(tableName, attr, dataType) { function pgDataTypeMapping(tableName, attr, dataType) {
...@@ -65,7 +65,7 @@ function pgDataTypeMapping(tableName, attr, dataType) { ...@@ -65,7 +65,7 @@ function pgDataTypeMapping(tableName, attr, dataType) {
} }
if (Utils._.includes(dataType, 'DATETIME')) { if (Utils._.includes(dataType, 'DATETIME')) {
dataType = dataType.replace(/DATETIME/, 'TIMESTAMP') dataType = dataType.replace(/DATETIME/, 'TIMESTAMP WITH TIME ZONE')
} }
if (Utils._.includes(dataType, 'SERIAL')) { if (Utils._.includes(dataType, 'SERIAL')) {
...@@ -514,7 +514,7 @@ module.exports = (function() { ...@@ -514,7 +514,7 @@ module.exports = (function() {
} }
if (dataType.type === "DATETIME") { if (dataType.type === "DATETIME") {
dataType.type = 'TIMESTAMP' dataType.type = 'TIMESTAMP WITH TIME ZONE'
} }
if (dataType.hasOwnProperty('allowNull') && (!dataType.allowNull)) { if (dataType.hasOwnProperty('allowNull') && (!dataType.allowNull)) {
......
...@@ -92,7 +92,7 @@ module.exports = (function() { ...@@ -92,7 +92,7 @@ module.exports = (function() {
results = results.map(function(result) { results = results.map(function(result) {
for (var name in result) { for (var name in result) {
if (result.hasOwnProperty(name) && (metaData.columnTypes[name] === 'DATETIME')) { if (result.hasOwnProperty(name) && (metaData.columnTypes[name] === 'DATETIME')) {
result[name] = new Date(result[name]); result[name] = new Date(result[name]+'Z'); // Z means UTC
} }
} }
return result return result
......
var util = require("util") var mysql = require("mysql")
, connection = mysql.createConnection({})
, util = require("util")
, DataTypes = require("./data-types") , DataTypes = require("./data-types")
, SqlString = require("./SqlString")
var Utils = module.exports = { var Utils = module.exports = {
_: (function() { _: (function() {
...@@ -43,23 +44,39 @@ var Utils = module.exports = { ...@@ -43,23 +44,39 @@ var Utils = module.exports = {
return s.replace(new RegExp(Utils.TICK_CHAR, 'g'), "") return s.replace(new RegExp(Utils.TICK_CHAR, 'g'), "")
}, },
escape: function(s) { escape: function(s) {
return SqlString.escape(s, true, "local").replace(/\\"/g, '"') return connection.escape(s).replace(/\\"/g, '"')
}, },
format: function(arr) { format: function(arr) {
return SqlString.format(arr.shift(), arr) return connection.format.apply(connection, [arr.shift(), arr])
}, },
isHash: function(obj) { isHash: function(obj) {
return Utils._.isObject(obj) && !Array.isArray(obj); return Utils._.isObject(obj) && !Array.isArray(obj);
}, },
isEmptyObject: function( obj ) {
for ( var name in obj ) {
return false;
}
return true;
},
pad: function (s) {
return s < 10 ? '0' + s : s
},
toSqlDate: function(date) { toSqlDate: function(date) {
return [ // return [
[ // [
date.getFullYear(), // date.getFullYear(),
((date.getMonth() < 9 ? '0' : '') + (date.getMonth()+1)), // ((date.getMonth() < 9 ? '0' : '') + (date.getMonth()+1)),
((date.getDate() < 10 ? '0' : '') + date.getDate()) // ((date.getDate() < 10 ? '0' : '') + date.getDate())
].join("-"), // ].join("-"),
date.toLocaleTimeString() // date.toLocaleTimeString()
].join(" ") // ].join(" ")
return date.getUTCFullYear() + '-' +
this.pad(date.getUTCMonth()+1) + '-' +
this.pad(date.getUTCDate()) + ' ' +
this.pad(date.getUTCHours()) + ':' +
this.pad(date.getUTCMinutes()) + ':' +
this.pad(date.getUTCSeconds())
}, },
argsArePrimaryKeys: function(args, primaryKeys) { argsArePrimaryKeys: function(args, primaryKeys) {
var result = (args.length == Object.keys(primaryKeys).length) var result = (args.length == Object.keys(primaryKeys).length)
...@@ -148,14 +165,6 @@ var Utils = module.exports = { ...@@ -148,14 +165,6 @@ var Utils = module.exports = {
} }
}, },
firstValueOfHash: function(obj) {
for (var key in obj) {
if (obj.hasOwnProperty(key))
return obj[key]
}
return null
},
inherit: function(subClass, superClass) { inherit: function(subClass, superClass) {
if (superClass.constructor == Function) { if (superClass.constructor == Function) {
// Normal Inheritance // Normal Inheritance
...@@ -171,7 +180,6 @@ var Utils = module.exports = { ...@@ -171,7 +180,6 @@ var Utils = module.exports = {
return subClass; return subClass;
} }
} }
Utils.CustomEventEmitter = require("./emitters/custom-event-emitter") Utils.CustomEventEmitter = require("./emitters/custom-event-emitter")
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
"devDependencies": { "devDependencies": {
"jasmine-node": "1.0.17", "jasmine-node": "1.0.17",
"sqlite3": "~2.1.5", "sqlite3": "~2.1.5",
"mysql": "~2.0.0-alpha3", "mysql": "~2.0.0-alpha7",
"pg": "~0.10.2", "pg": "~0.10.2",
"buster": "~0.6.0", "buster": "~0.6.0",
"dox-foundation": "~0.3.0", "dox-foundation": "~0.3.0",
......
...@@ -181,7 +181,7 @@ describe('DAO', function() { ...@@ -181,7 +181,7 @@ describe('DAO', function() {
expect(users.length).toEqual(1) expect(users.length).toEqual(1)
expect(users[0].username).toEqual(username) expect(users[0].username).toEqual(username)
expect(users[0].birthDate instanceof Date).toBe(true) expect(users[0].birthDate instanceof Date).toBe(true)
expect(users[0].birthDate.getTime()).toEqual(new Date(1984, 8, 23).getTime()) expect(users[0].birthDate).toEqual(new Date(1984, 8, 23))
done() done()
}) })
}) })
......
...@@ -105,7 +105,7 @@ describe('QueryGenerator', function() { ...@@ -105,7 +105,7 @@ describe('QueryGenerator', function() {
arguments: ['myTable', {name: "foo';DROP TABLE myTable;"}], arguments: ['myTable', {name: "foo';DROP TABLE myTable;"}],
expectation: "INSERT INTO `myTable` (`name`) VALUES ('foo\\';DROP TABLE myTable;');" expectation: "INSERT INTO `myTable` (`name`) VALUES ('foo\\';DROP TABLE myTable;');"
}, { }, {
arguments: ['myTable', {name: 'foo', birthday: new Date(2011, 2, 27, 10, 1, 55)}], arguments: ['myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}],
expectation: "INSERT INTO `myTable` (`name`,`birthday`) VALUES ('foo','2011-03-27 10:01:55');" expectation: "INSERT INTO `myTable` (`name`,`birthday`) VALUES ('foo','2011-03-27 10:01:55');"
}, { }, {
arguments: ['myTable', {name: 'foo', foo: 1}], arguments: ['myTable', {name: 'foo', foo: 1}],
...@@ -130,10 +130,10 @@ describe('QueryGenerator', function() { ...@@ -130,10 +130,10 @@ describe('QueryGenerator', function() {
updateQuery: [ updateQuery: [
{ {
arguments: ['myTable', {name: 'foo', birthday: new Date(2011, 2, 27, 10, 1, 55)}, {id: 2}], arguments: ['myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}, {id: 2}],
expectation: "UPDATE `myTable` SET `name`='foo',`birthday`='2011-03-27 10:01:55' WHERE `id`=2" expectation: "UPDATE `myTable` SET `name`='foo',`birthday`='2011-03-27 10:01:55' WHERE `id`=2"
}, { }, {
arguments: ['myTable', {name: 'foo', birthday: new Date(2011, 2, 27, 10, 1, 55)}, 2], arguments: ['myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}, 2],
expectation: "UPDATE `myTable` SET `name`='foo',`birthday`='2011-03-27 10:01:55' WHERE `id`=2" expectation: "UPDATE `myTable` SET `name`='foo',`birthday`='2011-03-27 10:01:55' WHERE `id`=2"
}, { }, {
arguments: ['myTable', {bar: 2}, {name: 'foo'}], arguments: ['myTable', {bar: 2}, {name: 'foo'}],
...@@ -226,7 +226,7 @@ describe('QueryGenerator', function() { ...@@ -226,7 +226,7 @@ describe('QueryGenerator', function() {
Sequelize.Utils._.each(suites, function(tests, suiteTitle) { Sequelize.Utils._.each(suites, function(tests, suiteTitle) {
describe(suiteTitle, function() { describe(suiteTitle, function() {
tests.forEach(function(test) { tests.forEach(function(test) {
var title = test.title || 'correctly returns ' + test.expectation + ' for ' + util.inspect(test.arguments) var title = test.title || 'MySQL correctly returns ' + test.expectation + ' for ' + util.inspect(test.arguments)
it(title, function() { it(title, function() {
// Options would normally be set by the query interface that instantiates the query-generator, but here we specify it explicitly // Options would normally be set by the query interface that instantiates the query-generator, but here we specify it explicitly
var context = test.context || {options: {}}; var context = test.context || {options: {}};
......
...@@ -99,7 +99,7 @@ describe('QueryGenerator', function() { ...@@ -99,7 +99,7 @@ describe('QueryGenerator', function() {
expectation: "INSERT INTO \"myTable\" (\"name\") VALUES ('foo'';DROP TABLE myTable;') RETURNING *;" expectation: "INSERT INTO \"myTable\" (\"name\") VALUES ('foo'';DROP TABLE myTable;') RETURNING *;"
}, { }, {
arguments: ['myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}], arguments: ['myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}],
expectation: "INSERT INTO \"myTable\" (\"name\",\"birthday\") VALUES ('foo','2011-03-27 10:01:55.0') RETURNING *;" expectation: "INSERT INTO \"myTable\" (\"name\",\"birthday\") VALUES ('foo','2011-03-27 10:01:55.0Z') RETURNING *;"
}, { }, {
arguments: ['myTable', {name: 'foo', foo: 1}], arguments: ['myTable', {name: 'foo', foo: 1}],
expectation: "INSERT INTO \"myTable\" (\"name\",\"foo\") VALUES ('foo',1) RETURNING *;" expectation: "INSERT INTO \"myTable\" (\"name\",\"foo\") VALUES ('foo',1) RETURNING *;"
...@@ -133,10 +133,10 @@ describe('QueryGenerator', function() { ...@@ -133,10 +133,10 @@ describe('QueryGenerator', function() {
updateQuery: [ updateQuery: [
{ {
arguments: ['myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}, {id: 2}], arguments: ['myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}, {id: 2}],
expectation: "UPDATE \"myTable\" SET \"name\"='foo',\"birthday\"='2011-03-27 10:01:55.0' WHERE \"id\"=2 RETURNING *" expectation: "UPDATE \"myTable\" SET \"name\"='foo',\"birthday\"='2011-03-27 10:01:55.0Z' WHERE \"id\"=2 RETURNING *"
}, { }, {
arguments: ['myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}, 2], arguments: ['myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}, 2],
expectation: "UPDATE \"myTable\" SET \"name\"='foo',\"birthday\"='2011-03-27 10:01:55.0' WHERE \"id\"=2 RETURNING *" expectation: "UPDATE \"myTable\" SET \"name\"='foo',\"birthday\"='2011-03-27 10:01:55.0Z' WHERE \"id\"=2 RETURNING *"
}, { }, {
arguments: ['myTable', {bar: 2}, {name: 'foo'}], arguments: ['myTable', {bar: 2}, {name: 'foo'}],
expectation: "UPDATE \"myTable\" SET \"bar\"=2 WHERE \"name\"='foo' RETURNING *" expectation: "UPDATE \"myTable\" SET \"bar\"=2 WHERE \"name\"='foo' RETURNING *"
...@@ -160,7 +160,7 @@ describe('QueryGenerator', function() { ...@@ -160,7 +160,7 @@ describe('QueryGenerator', function() {
context: {options: {omitNull: true}} context: {options: {omitNull: true}}
}, { }, {
arguments: ['mySchema.myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}, {id: 2}], arguments: ['mySchema.myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}, {id: 2}],
expectation: "UPDATE \"mySchema\".\"myTable\" SET \"name\"='foo',\"birthday\"='2011-03-27 10:01:55.0' WHERE \"id\"=2 RETURNING *" expectation: "UPDATE \"mySchema\".\"myTable\" SET \"name\"='foo',\"birthday\"='2011-03-27 10:01:55.0Z' WHERE \"id\"=2 RETURNING *"
}, { }, {
arguments: ['mySchema.myTable', {name: "foo';DROP TABLE mySchema.myTable;"}, {name: 'foo'}], arguments: ['mySchema.myTable', {name: "foo';DROP TABLE mySchema.myTable;"}, {name: 'foo'}],
expectation: "UPDATE \"mySchema\".\"myTable\" SET \"name\"='foo'';DROP TABLE mySchema.myTable;' WHERE \"name\"='foo' RETURNING *" expectation: "UPDATE \"mySchema\".\"myTable\" SET \"name\"='foo'';DROP TABLE mySchema.myTable;' WHERE \"name\"='foo' RETURNING *"
...@@ -251,7 +251,7 @@ describe('QueryGenerator', function() { ...@@ -251,7 +251,7 @@ describe('QueryGenerator', function() {
Sequelize.Utils._.each(suites, function(tests, suiteTitle) { Sequelize.Utils._.each(suites, function(tests, suiteTitle) {
describe(suiteTitle, function() { describe(suiteTitle, function() {
tests.forEach(function(test) { tests.forEach(function(test) {
var title = test.title || 'correctly returns ' + test.expectation + ' for ' + util.inspect(test.arguments) var title = test.title || 'Postgres correctly returns ' + test.expectation + ' for ' + util.inspect(test.arguments)
it(title, function() { it(title, function() {
// Options would normally be set by the query interface that instantiates the query-generator, but here we specify it explicitly // Options would normally be set by the query interface that instantiates the query-generator, but here we specify it explicitly
var context = test.context || {options: {}}; var context = test.context || {options: {}};
......
...@@ -76,7 +76,7 @@ describe('Sequelize', function() { ...@@ -76,7 +76,7 @@ describe('Sequelize', function() {
Photo.sync({ force: true }).success(function() { Photo.sync({ force: true }).success(function() {
sequelize.getQueryInterface().showAllTables().success(function(tableNames) { sequelize.getQueryInterface().showAllTables().success(function(tableNames) {
expect(tableNames.indexOf('photos') !== -1).toBeTruthy() expect(tableNames.indexOf('photos') !== -1).toBeTruthy()
done done();
}) })
}) })
}) })
......
...@@ -83,7 +83,7 @@ describe('QueryGenerator', function() { ...@@ -83,7 +83,7 @@ describe('QueryGenerator', function() {
Sequelize.Utils._.each(suites, function(tests, suiteTitle) { Sequelize.Utils._.each(suites, function(tests, suiteTitle) {
describe(suiteTitle, function() { describe(suiteTitle, function() {
tests.forEach(function(test) { tests.forEach(function(test) {
var title = test.title || 'correctly returns ' + test.expectation + ' for ' + util.inspect(test.arguments) var title = test.title || 'SQLite correctly returns ' + test.expectation + ' for ' + util.inspect(test.arguments)
it(title, function() { it(title, function() {
// Options would normally be set by the query interface that instantiates the query-generator, but here we specify it explicitly // Options would normally be set by the query interface that instantiates the query-generator, but here we specify it explicitly
var context = test.context || {options: {}}; var context = test.context || {options: {}};
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!