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

Commit f9061a1d by Sascha Depold

Merge branch 'master' into refactorings/eager_loading

2 parents 1532dad2 c1fc9165
# 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
- [DEPENDENCIES] mysql is now an optional dependency. #355 (thanks to clkao)
- [REFACTORING] separated tests for dialects - [REFACTORING] separated tests for dialects
- [REFACTORING] reduced number of sql queries used for adding an element to a N:M association #449 (thanks to innofluence/janmeier) - [REFACTORING] reduced number of sql queries used for adding an element to a N:M association. #449 (thanks to innofluence/janmeier)
- [OTHERS] code was formatted to fit the latest code style guidelines (thanks to durango) - [OTHERS] code was formatted to fit the latest code style guidelines (thanks to durango)
- [OTHERS] Explicitly target ./docs folder for generate-docs script. #444 (thanks to carsondarling) - [OTHERS] Explicitly target ./docs folder for generate-docs script. #444 (thanks to carsondarling)
- [BUG] fixed wrong version in sequelize binary - [BUG] fixed wrong version in sequelize binary
...@@ -28,7 +32,7 @@ ...@@ -28,7 +32,7 @@
- [FEATURE] allow definition of a models table name (thanks to slamkajs) - [FEATURE] allow definition of a models table name (thanks to slamkajs)
- [FEATURE] allow usage of enums. #440 (thanks to KevinMartin) - [FEATURE] allow usage of enums. #440 (thanks to KevinMartin)
- [FEATURE] allows updateAttributes to target specific fields only (thanks to Pasvaz) - [FEATURE] allows updateAttributes to target specific fields only (thanks to Pasvaz)
- [DEPENDENCIES] mysql is now an optional dependency - [FEATURE] timestamps are now stored as UTC. #461 (thanks to innofluence/janmeier)
# v1.5.0 # # v1.5.0 #
- [REFACTORING] use underscore functions for Utils.isHash (thanks to Mick-Hansen/innofluence) - [REFACTORING] use underscore functions for Utils.isHash (thanks to Mick-Hansen/innofluence)
......
...@@ -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]
......
...@@ -241,8 +241,10 @@ module.exports = (function() { ...@@ -241,8 +241,10 @@ module.exports = (function() {
port: config.port, port: config.port,
user: config.username, user: config.username,
password: config.password, password: config.password,
database: config.database database: config.database,
timezone: 'Z'
}) })
connection.query("SET time_zone = '+0:00'");
// client.setMaxListeners(self.maxConcurrentQueries) // client.setMaxListeners(self.maxConcurrentQueries)
this.isConnecting = false this.isConnecting = false
......
...@@ -37,3 +37,5 @@ module.exports = (function() { ...@@ -37,3 +37,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')) {
...@@ -492,7 +492,7 @@ module.exports = (function() { ...@@ -492,7 +492,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
......
...@@ -51,15 +51,16 @@ var Utils = module.exports = { ...@@ -51,15 +51,16 @@ var Utils = module.exports = {
isHash: function(obj) { isHash: function(obj) {
return Utils._.isObject(obj) && !Array.isArray(obj); return Utils._.isObject(obj) && !Array.isArray(obj);
}, },
pad: function (s) {
return s < 10 ? '0' + s : s
},
toSqlDate: function(date) { toSqlDate: function(date) {
return [ return date.getUTCFullYear() + '-' +
[ this.pad(date.getUTCMonth()+1) + '-' +
date.getFullYear(), this.pad(date.getUTCDate()) + ' ' +
((date.getMonth() < 9 ? '0' : '') + (date.getMonth()+1)), this.pad(date.getUTCHours()) + ':' +
((date.getDate() < 10 ? '0' : '') + date.getDate()) this.pad(date.getUTCMinutes()) + ':' +
].join("-"), this.pad(date.getUTCSeconds())
date.toLocaleTimeString()
].join(" ")
}, },
argsArePrimaryKeys: function(args, primaryKeys) { argsArePrimaryKeys: function(args, primaryKeys) {
var result = (args.length == Object.keys(primaryKeys).length) var result = (args.length == Object.keys(primaryKeys).length)
...@@ -171,7 +172,6 @@ var Utils = module.exports = { ...@@ -171,7 +172,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",
"watchr": "~2.2.0", "watchr": "~2.2.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: {}};
......
...@@ -352,7 +352,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -352,7 +352,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
}) })
;(dialect.match(/^postgres/) ? itEventually : it)('stores the current date in createdAt', function(done) { it('stores the current date in createdAt', function(done) {
this.User.create({ username: 'foo' }).success(function(user) { this.User.create({ username: 'foo' }).success(function(user) {
expect(parseInt(+user.createdAt/5000)).toEqual(parseInt(+new Date()/5000)) expect(parseInt(+user.createdAt/5000)).toEqual(parseInt(+new Date()/5000))
done() done()
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!