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

Commit 52916fb8 by Jan Aagaard Meier

Merge pull request #3041 from seegno-forks/enhancement/upgrade-pg-and-pg-native

Add support for postgres on io.js
2 parents ea30ef61 dd4fc8ec
...@@ -95,7 +95,7 @@ ConnectionManager.prototype.connect = function(config) { ...@@ -95,7 +95,7 @@ ConnectionManager.prototype.connect = function(config) {
}).tap(function (connection) { }).tap(function (connection) {
if (self.sequelize.config.keepDefaultTimezone) return; if (self.sequelize.config.keepDefaultTimezone) return;
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
connection.query("SET TIME ZONE INTERVAL '" + self.sequelize.options.timezone + "' HOUR TO MINUTE").on('error', function (err) { connection.query("SET client_min_messages TO warning; SET TIME ZONE INTERVAL '" + self.sequelize.options.timezone + "' HOUR TO MINUTE").on('error', function (err) {
reject(err); reject(err);
}).on('end', function () { }).on('end', function () {
resolve(); resolve();
......
...@@ -207,7 +207,7 @@ module.exports = (function() { ...@@ -207,7 +207,7 @@ module.exports = (function() {
return results; return results;
} else if (QueryTypes.BULKUPDATE === self.options.type) { } else if (QueryTypes.BULKUPDATE === self.options.type) {
if (!self.options.returning) { if (!self.options.returning) {
return result.rowCount; return parseInt(result.rowCount, 10);
} }
if (!!self.callee && !!self.callee._hasHstoreAttributes) { if (!!self.callee && !!self.callee._hasHstoreAttributes) {
...@@ -218,7 +218,7 @@ module.exports = (function() { ...@@ -218,7 +218,7 @@ module.exports = (function() {
return self.handleSelectQuery(rows); return self.handleSelectQuery(rows);
} else if (QueryTypes.BULKDELETE === self.options.type) { } else if (QueryTypes.BULKDELETE === self.options.type) {
return result.rowCount; return parseInt(result.rowCount, 10);
} else if (self.isUpsertQuery()) { } else if (self.isUpsertQuery()) {
return rows[0].sequelize_upsert; return rows[0].sequelize_upsert;
} else if (self.isInsertQuery() || self.isUpdateQuery()) { } else if (self.isInsertQuery() || self.isUpdateQuery()) {
...@@ -256,10 +256,14 @@ module.exports = (function() { ...@@ -256,10 +256,14 @@ module.exports = (function() {
, table , table
, index; , index;
switch (err.code) { var code = err.code || err.sqlState
, errMessage = err.message || err.messagePrimary
, errDetail = err.detail || err.messageDetail;
switch (code) {
case '23503': case '23503':
index = err.message.match(/violates foreign key constraint \"(.+?)\"/)[1]; index = errMessage.match(/violates foreign key constraint \"(.+?)\"/)[1];
table = err.message.match(/on table \"(.+?)\"/)[1]; table = errMessage.match(/on table \"(.+?)\"/)[1];
return new sequelizeErrors.ForeignKeyConstraintError({ return new sequelizeErrors.ForeignKeyConstraintError({
fields: null, fields: null,
...@@ -270,7 +274,7 @@ module.exports = (function() { ...@@ -270,7 +274,7 @@ module.exports = (function() {
case '23505': case '23505':
// there are multiple different formats of error messages for this error code // there are multiple different formats of error messages for this error code
// this regex should check at least two // this regex should check at least two
match = err.detail.match(/Key \((.*?)\)=\((.*?)\)/); match = errDetail.match(/Key \((.*?)\)=\((.*?)\)/);
if (match) { if (match) {
var fields = Utils._.zipObject(match[1].split(', '), match[2].split(', ')) var fields = Utils._.zipObject(match[1].split(', '), match[2].split(', '))
...@@ -299,7 +303,7 @@ module.exports = (function() { ...@@ -299,7 +303,7 @@ module.exports = (function() {
}); });
} else { } else {
return new sequelizeErrors.UniqueConstraintError({ return new sequelizeErrors.UniqueConstraintError({
message: err.message, message: errMessage,
parent: err parent: err
}); });
} }
......
...@@ -47,7 +47,8 @@ ...@@ -47,7 +47,8 @@
"chai-as-promised": "^4.1.1", "chai-as-promised": "^4.1.1",
"sqlite3": "~3.0.0", "sqlite3": "~3.0.0",
"mysql": "~2.5.0", "mysql": "~2.5.0",
"pg": "~3.6.0", "pg": "^4.2.0",
"pg-native": "^1.8.0",
"pg-hstore": "^2.3.1", "pg-hstore": "^2.3.1",
"tedious": "^1.7.0", "tedious": "^1.7.0",
"watchr": "~2.4.11", "watchr": "~2.4.11",
......
...@@ -22,7 +22,7 @@ describe(Support.getTestDialectTeaser('Configuration'), function() { ...@@ -22,7 +22,7 @@ describe(Support.getTestDialectTeaser('Configuration'), function() {
if (dialect === 'sqlite') { if (dialect === 'sqlite') {
// SQLite doesn't have a breakdown of error codes, so we are unable to discern between the different types of errors. // SQLite doesn't have a breakdown of error codes, so we are unable to discern between the different types of errors.
return expect(seq.query('select 1 as hello')).to.eventually.be.rejectedWith(seq.ConnectionError, 'SQLITE_CANTOPEN: unable to open database file'); return expect(seq.query('select 1 as hello')).to.eventually.be.rejectedWith(seq.ConnectionError, 'SQLITE_CANTOPEN: unable to open database file');
} else if (dialect === 'mssql') { } else if (dialect === 'mssql' || dialect === 'postgres') {
return expect(seq.query('select 1 as hello')).to.eventually.be.rejectedWith([seq.HostNotReachableError, seq.InvalidConnectionError]); return expect(seq.query('select 1 as hello')).to.eventually.be.rejectedWith([seq.HostNotReachableError, seq.InvalidConnectionError]);
} else { } else {
return expect(seq.query('select 1 as hello')).to.eventually.be.rejectedWith(seq.InvalidConnectionError, 'connect EINVAL'); return expect(seq.query('select 1 as hello')).to.eventually.be.rejectedWith(seq.InvalidConnectionError, 'connect EINVAL');
......
...@@ -999,8 +999,6 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -999,8 +999,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
{ username: 'Paul', secretValue: '42' }, { username: 'Paul', secretValue: '42' },
{ username: 'Bob', secretValue: '43' }]; { username: 'Bob', secretValue: '43' }];
this.clock = sinon.useFakeTimers();
return this.User.bulkCreate(data).bind(this).then(function() { return this.User.bulkCreate(data).bind(this).then(function() {
return this.User.findAll({order: 'id'}); return this.User.findAll({order: 'id'});
}).then(function(users) { }).then(function(users) {
...@@ -1010,9 +1008,9 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -1010,9 +1008,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(this.updatedAt).to.equalTime(users[2].updatedAt); // All users should have the same updatedAt expect(this.updatedAt).to.equalTime(users[2].updatedAt); // All users should have the same updatedAt
// Pass the time so we can actually see a change // Pass the time so we can actually see a change
this.clock.tick(1000); return this.sequelize.Promise.delay(1000).bind(this).then(function() {
return this.User.update({username: 'Bill'}, {where: {secretValue: '42'}});
return this.User.update({username: 'Bill'}, {where: {secretValue: '42'}}); });
}).then(function() { }).then(function() {
return this.User.findAll({order: 'id'}); return this.User.findAll({order: 'id'});
}).then(function(users) { }).then(function(users) {
...@@ -1022,8 +1020,6 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -1022,8 +1020,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(users[0].updatedAt).to.be.afterTime(this.updatedAt); expect(users[0].updatedAt).to.be.afterTime(this.updatedAt);
expect(users[2].updatedAt).to.equalTime(this.updatedAt); expect(users[2].updatedAt).to.equalTime(this.updatedAt);
this.clock.restore();
}); });
}); });
......
...@@ -99,7 +99,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -99,7 +99,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
username: 'gottlieb' username: 'gottlieb'
} }
}).then(function () { }).then(function () {
throw new Error('I should have ben rejected'); throw new Error('I should have been rejected');
}, function (err) { }, function (err) {
expect(err instanceof Sequelize.UniqueConstraintError).to.be.ok; expect(err instanceof Sequelize.UniqueConstraintError).to.be.ok;
expect(err.fields).to.be.ok; expect(err.fields).to.be.ok;
......
...@@ -18,8 +18,6 @@ chai.config.includeStack = true; ...@@ -18,8 +18,6 @@ chai.config.includeStack = true;
describe(Support.getTestDialectTeaser('Model'), function() { describe(Support.getTestDialectTeaser('Model'), function() {
beforeEach(function() { beforeEach(function() {
this.clock = sinon.useFakeTimers();
this.User = this.sequelize.define('user', { this.User = this.sequelize.define('user', {
username: DataTypes.STRING, username: DataTypes.STRING,
foo: { foo: {
...@@ -35,10 +33,6 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -35,10 +33,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
return this.sequelize.sync({ force: true }); return this.sequelize.sync({ force: true });
}); });
afterEach(function() {
this.clock.restore();
});
if (current.dialect.supports.upserts) { if (current.dialect.supports.upserts) {
describe('upsert', function() { describe('upsert', function() {
it('works with upsert on id', function() { it('works with upsert on id', function() {
...@@ -49,8 +43,9 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -49,8 +43,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(created).to.be.ok; expect(created).to.be.ok;
} }
this.clock.tick(2000); // Make sure to pass some time so updatedAt != createdAt return this.sequelize.Promise.delay(1000).bind(this).then(function() {
return this.User.upsert({ id: 42, username: 'doe' }); return this.User.upsert({ id: 42, username: 'doe' });
});
}).then(function(created) { }).then(function(created) {
if (dialect === 'sqlite') { if (dialect === 'sqlite') {
expect(created).not.to.be.defined; expect(created).not.to.be.defined;
...@@ -74,8 +69,9 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -74,8 +69,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(created).to.be.ok; expect(created).to.be.ok;
} }
this.clock.tick(2000); // Make sure to pass some time so updatedAt != createdAt return this.sequelize.Promise.delay(1000).bind(this).then(function() {
return this.User.upsert({ foo: 'baz', bar: 19, username: 'doe' }); return this.User.upsert({ foo: 'baz', bar: 19, username: 'doe' });
});
}).then(function(created) { }).then(function(created) {
if (dialect === 'sqlite') { if (dialect === 'sqlite') {
expect(created).not.to.be.defined; expect(created).not.to.be.defined;
......
...@@ -119,7 +119,8 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() { ...@@ -119,7 +119,8 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
} else if (dialect === 'postgres') { } else if (dialect === 'postgres') {
expect( expect(
err.message.match(/connect ECONNREFUSED/) || err.message.match(/connect ECONNREFUSED/) ||
err.message.match(/invalid port number/) err.message.match(/invalid port number/) ||
err.message.match(/RangeError: Port should be > 0 and < 65536/)
).to.be.ok; ).to.be.ok;
} else if (dialect === 'mssql') { } else if (dialect === 'mssql') {
expect( expect(
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!