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

Commit fd1ace03 by Jan Aagaard Meier

Changes to raw query handling

1 parent edb18238
......@@ -8,6 +8,7 @@
- [FEATURE] Validations are now enabled by default for upsert.
- [FEATURE] Preliminary support for `include.through.where`
- [SECURITY/BUG] Fixed injection issue in direction param for order
- [FEATURE/BUG] Raw queries always return all results (including affected rows etc).
# 2.0.0-rc7
- [FEATURE] Throw an error if no where clause is given to `Model.destroy()`.
......
......@@ -83,6 +83,10 @@ module.exports = (function() {
}
};
AbstractQuery.prototype.isRawQuery = function () {
return this.options.type === QueryTypes.RAW;
};
AbstractQuery.prototype.isVersionQuery = function () {
return this.options.type === QueryTypes.VERSION;
};
......@@ -150,6 +154,10 @@ module.exports = (function() {
};
AbstractQuery.prototype.isUpdateQuery = function() {
if (this.options.type === QueryTypes.UPDATE) {
return true;
}
return (this.sql.toLowerCase().indexOf('update') === 0);
};
......
......@@ -98,6 +98,9 @@ module.exports = (function() {
result = data.affectedRows;
} else if (this.isVersionQuery()) {
result = data[0].version;
} else if (this.isRawQuery()) {
// MySQL returns row data and metadata (affected rows etc) in a single object - let's standarize it, sorta
result = [data, data];
}
return result;
......
......@@ -243,6 +243,8 @@ module.exports = (function() {
return self.callee || (rows && ((self.options.plain && rows[0]) || rows)) || undefined;
} else if (self.isVersionQuery()) {
return results[0].version;
} else if (self.isRawQuery()) {
return [rows, result];
} else {
return results;
}
......
......@@ -139,6 +139,8 @@ module.exports = (function() {
result = undefined;
} else if (self.options.type === QueryTypes.VERSION) {
result = results[0].version;
} else if (self.options.type === QueryTypes.RAW) {
result = [results, metaData];
}
resolve(result);
......
......@@ -831,7 +831,7 @@ module.exports = (function() {
* @param {Integer} [options.by=1] The number to increment by
* @param {Transaction} [options.transaction]
*
* @return {Promise}
* @return {Promise<this>}
*/
Instance.prototype.increment = function(fields, countOrOptions) {
Utils.validateParameter(countOrOptions, Object, {
......@@ -895,7 +895,7 @@ module.exports = (function() {
}
}, this);
return this.QueryInterface.increment(this, this.Model.getTableName(countOrOptions), values, where, countOrOptions);
return this.QueryInterface.increment(this, this.Model.getTableName(countOrOptions), values, where, countOrOptions).return(this);
};
/**
......
......@@ -725,7 +725,6 @@ module.exports = (function() {
}
}).then(function() {
return this.QueryInterface.select(this, this.getTableName(options), options, Utils._.defaults({
type: QueryTypes.SELECT,
hasJoin: hasJoin,
tableNames: Object.keys(tableNames)
}, queryOptions, { transaction: options.transaction }));
......@@ -743,9 +742,7 @@ module.exports = (function() {
// whereCollection is used for non-primary key updates
this.options.whereCollection = options.where || null;
return this.QueryInterface.select(this, [[this.getTableName(options), this.name], joinTableName], options, Utils._.defaults({
type: QueryTypes.SELECT
}, queryOptions, { transaction: (options || {}).transaction }));
return this.QueryInterface.select(this, [[this.getTableName(options), this.name], joinTableName], options, Utils._.defaults(queryOptions, { transaction: (options || {}).transaction }));
};
/**
......@@ -1449,7 +1446,6 @@ module.exports = (function() {
options.type = QueryTypes.BULKDELETE;
mapFieldNames.call(this, options, this);
return Promise.try(function() {
......
......@@ -443,7 +443,7 @@ module.exports = (function() {
}
return Utils.Promise.map(tableNames, function(tableName) {
return self.sequelize.query(self.QueryGenerator.getForeignKeysQuery(tableName, self.sequelize.config.database));
return self.sequelize.query(self.QueryGenerator.getForeignKeysQuery(tableName, self.sequelize.config.database)).get(0);
}).then(function(results) {
var result = {};
......@@ -556,6 +556,9 @@ module.exports = (function() {
, restrict = false
, sql = self.QueryGenerator.updateQuery(tableName, values, identifier, options, dao.Model.rawAttributes);
options = options || {};
options.type = QueryTypes.UPDATE;
// Check for a restrict field
if (!!dao.Model && !!dao.Model.associations) {
var keys = Object.keys(dao.Model.associations)
......@@ -689,13 +692,14 @@ module.exports = (function() {
var sql = this.QueryGenerator.selectQuery(tableName, options, model);
queryOptions = Utils._.extend({}, queryOptions, {
type: QueryTypes.SELECT,
include: options.include,
includeNames: options.includeNames,
includeMap: options.includeMap,
hasSingleAssociation: options.hasSingleAssociation,
hasMultiAssociation: options.hasMultiAssociation,
attributes: options.attributes,
originalAttributes: options.originalAttributes
originalAttributes: options.originalAttributes,
});
return this.sequelize.query(sql, model, queryOptions);
......
......@@ -3,10 +3,12 @@
module.exports = {
SELECT: 'SELECT',
INSERT: 'INSERT',
UPDATE: 'UPDATE',
BULKUPDATE: 'BULKUPDATE',
BULKDELETE: 'BULKDELETE',
UPSERT: 'UPSERT',
VERSION: 'VERSION',
SHOWTABLES: 'SHOWTABLES',
SHOWINDEXES: 'SHOWINDEXES'
SHOWINDEXES: 'SHOWINDEXES',
RAW: 'RAW',
};
......@@ -660,7 +660,7 @@ module.exports = (function() {
options = Utils._.extend(Utils._.clone(this.options.query), options);
options = Utils._.defaults(options, {
logging: this.options.hasOwnProperty('logging') ? this.options.logging : console.log,
type: (sql.toLowerCase().indexOf('select') === 0) ? QueryTypes.SELECT : false
type: QueryTypes.RAW
});
if (options.transaction === undefined && Sequelize.cls) {
......
......@@ -18,7 +18,7 @@ chai.use(datetime);
chai.config.includeStack = true;
describe(Support.getTestDialectTeaser('Model'), function() {
beforeEach(function(done) {
beforeEach(function() {
this.User = this.sequelize.define('User', {
username: DataTypes.STRING,
secretValue: DataTypes.STRING,
......@@ -28,25 +28,21 @@ describe(Support.getTestDialectTeaser('Model'), function() {
aBool: DataTypes.BOOLEAN
});
this.User.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true });
});
describe('constructor', function() {
it('uses the passed dao name as tablename if freezeTableName', function(done) {
it('uses the passed dao name as tablename if freezeTableName', function() {
var User = this.sequelize.define('FrozenUser', {}, { freezeTableName: true });
expect(User.tableName).to.equal('FrozenUser');
done();
});
it('uses the pluralized dao name as tablename unless freezeTableName', function(done) {
it('uses the pluralized dao name as tablename unless freezeTableName', function() {
var User = this.sequelize.define('SuperUser', {}, { freezeTableName: false });
expect(User.tableName).to.equal('SuperUsers');
done();
});
it('uses checks to make sure dao factory isnt leaking on multiple define', function(done) {
it('uses checks to make sure dao factory isnt leaking on multiple define', function() {
this.sequelize.define('SuperUser', {}, { freezeTableName: false });
var factorySize = this.sequelize.daoFactoryManager.all.length;
......@@ -54,10 +50,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
var factorySize2 = this.sequelize.daoFactoryManager.all.length;
expect(factorySize).to.equal(factorySize2);
done();
});
it('attaches class and instance methods', function(done) {
it('attaches class and instance methods', function() {
var User = this.sequelize.define('UserWithClassAndInstanceMethods', {}, {
classMethods: { doSmth: function() { return 1; } },
instanceMethods: { makeItSo: function() { return 2; } }
......@@ -70,10 +65,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(User.build().doSmth).not.to.exist;
expect(User.build().makeItSo).to.exist;
expect(User.build().makeItSo()).to.equal(2);
done();
});
it('allows us us to predefine the ID column with our own specs', function(done) {
it('allows us us to predefine the ID column with our own specs', function() {
var User = this.sequelize.define('UserCol', {
id: {
type: Sequelize.STRING,
......@@ -82,15 +76,12 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
User.sync({ force: true }).success(function() {
User.create({id: 'My own ID!'}).success(function(user) {
expect(user.id).to.equal('My own ID!');
done();
});
return User.sync({ force: true }).then(function() {
return expect(User.create({id: 'My own ID!'})).to.eventually.have.property('id', 'My own ID!');
});
});
it('throws an error if 2 autoIncrements are passed', function(done) {
it('throws an error if 2 autoIncrements are passed', function() {
var self = this;
expect(function() {
self.sequelize.define('UserWithTwoAutoIncrements', {
......@@ -98,10 +89,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
userscore: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }
});
}).to.throw(Error, 'Invalid Instance definition. Only one autoincrement field allowed.');
done();
});
it('throws an error if a custom model-wide validation is not a function', function(done) {
it('throws an error if a custom model-wide validation is not a function', function() {
var self = this;
expect(function() {
self.sequelize.define('Foo', {
......@@ -112,10 +102,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
}).to.throw(Error, 'Members of the validate option must be functions. Model: Foo, error with validate member notFunction');
done();
});
it('throws an error if a custom model-wide validation has the same name as a field', function(done) {
it('throws an error if a custom model-wide validation has the same name as a field', function() {
var self = this;
expect(function() {
self.sequelize.define('Foo', {
......@@ -126,7 +115,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
}).to.throw(Error, 'A model validator function must not have the same name as a field. Model: Foo, field/validation name: field');
done();
});
it('should allow me to set a default value for createdAt and updatedAt', function(done) {
......@@ -1239,8 +1227,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('sets deletedAt to the current timestamp if paranoid is true', function(done) {
it('sets deletedAt to the current timestamp if paranoid is true', function() {
var self = this
, qi = this.sequelize.queryInterface.QueryGenerator.quoteIdentifier
, ParanoidUser = self.sequelize.define('ParanoidUser', {
username: Sequelize.STRING,
secretValue: Sequelize.STRING,
......@@ -1253,26 +1242,25 @@ describe(Support.getTestDialectTeaser('Model'), function() {
{ username: 'Paul', secretValue: '42' },
{ username: 'Bob', secretValue: '43' }];
ParanoidUser.sync({ force: true }).success(function() {
ParanoidUser.bulkCreate(data).success(function() {
// since we save in UTC, let's format to UTC time
var date = moment().utc().format('YYYY-MM-DD h:mm');
ParanoidUser.destroy({where: {secretValue: '42'}}).success(function() {
ParanoidUser.findAll({order: 'id'}).success(function(users) {
expect(users.length).to.equal(1);
expect(users[0].username).to.equal('Bob');
return ParanoidUser.sync({ force: true }).then(function() {
return ParanoidUser.bulkCreate(data);
}).bind({}).then(function() {
// since we save in UTC, let's format to UTC time
this.date = moment().utc().format('YYYY-MM-DD h:mm');
return ParanoidUser.destroy({where: {secretValue: '42'}});
}).then(function() {
return ParanoidUser.findAll({order: 'id'});
}).then(function(users) {
expect(users.length).to.equal(1);
expect(users[0].username).to.equal('Bob');
self.sequelize.query('SELECT * FROM ' + self.sequelize.queryInterface.QueryGenerator.quoteIdentifier('ParanoidUsers') + ' WHERE ' + self.sequelize.queryInterface.QueryGenerator.quoteIdentifier('deletedAt') + ' IS NOT NULL ORDER BY ' + self.sequelize.queryInterface.QueryGenerator.quoteIdentifier('id'), null, {raw: true}).success(function(users) {
expect(users[0].username).to.equal('Peter');
expect(users[1].username).to.equal('Paul');
return self.sequelize.query('SELECT * FROM ' + qi('ParanoidUsers') + ' WHERE ' + qi('deletedAt') + ' IS NOT NULL ORDER BY ' + qi('id'));
}).spread(function(users) {
expect(users[0].username).to.equal('Peter');
expect(users[1].username).to.equal('Paul');
expect(moment(new Date(users[0].deletedAt)).utc().format('YYYY-MM-DD h:mm')).to.equal(date);
expect(moment(new Date(users[1].deletedAt)).utc().format('YYYY-MM-DD h:mm')).to.equal(date);
done();
});
});
});
});
expect(moment(new Date(users[0].deletedAt)).utc().format('YYYY-MM-DD h:mm')).to.equal(this.date);
expect(moment(new Date(users[1].deletedAt)).utc().format('YYYY-MM-DD h:mm')).to.equal(this.date);
});
});
......@@ -1381,46 +1369,44 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('should delete a paranoid record if I set force to true', function(done) {
it('should delete a paranoid record if I set force to true', function() {
var self = this;
var User = this.sequelize.define('paranoiduser', {
username: Sequelize.STRING
}, { paranoid: true });
User.sync({ force: true }).success(function() {
User.bulkCreate([
return User.sync({ force: true }).then(function() {
return User.bulkCreate([
{username: 'Bob'},
{username: 'Tobi'},
{username: 'Max'},
{username: 'Tony'}
]).success(function() {
User.find({where: {username: 'Bob'}}).success(function(user) {
user.destroy({force: true}).success(function() {
User.find({where: {username: 'Bob'}}).success(function(user) {
expect(user).to.be.null;
User.find({where: {username: 'Tobi'}}).success(function(tobi) {
tobi.destroy().success(function() {
self.sequelize.query('SELECT * FROM paranoidusers WHERE username=\'Tobi\'', null, {raw: true, plain: true}).success(function(result) {
expect(result.username).to.equal('Tobi');
User.destroy({where: {username: 'Tony'}}).success(function() {
self.sequelize.query('SELECT * FROM paranoidusers WHERE username=\'Tony\'', null, {raw: true, plain: true}).success(function(result) {
expect(result.username).to.equal('Tony');
User.destroy({where: {username: ['Tony', 'Max']}, force: true}).success(function() {
self.sequelize.query('SELECT * FROM paranoidusers', null, {raw: true}).success(function(users) {
expect(users).to.have.length(1);
expect(users[0].username).to.equal('Tobi');
done();
});
});
});
});
});
});
});
});
});
});
});
]);
}).then(function() {
return User.find({where: {username: 'Bob'}});
}).then(function(user) {
return user.destroy({force: true});
}).then(function() {
return expect(User.find({where: {username: 'Bob'}})).to.eventually.be.null;
}).then(function(user) {
return User.find({where: {username: 'Tobi'}});
}).then(function(tobi) {
return tobi.destroy();
}).then(function() {
return self.sequelize.query('SELECT * FROM paranoidusers WHERE username=\'Tobi\'');
}).spread(function(result) {
expect(result[0].username).to.equal('Tobi');
return User.destroy({where: {username: 'Tony'}});
}).then(function() {
return self.sequelize.query('SELECT * FROM paranoidusers WHERE username=\'Tony\'');
}).spread(function(result) {
expect(result[0].username).to.equal('Tony');
return User.destroy({where: {username: ['Tony', 'Max']}, force: true});
}).spread(function() {
return self.sequelize.query('SELECT * FROM paranoidusers', null, {raw: true});
}).then(function(users) {
expect(users).to.have.length(1);
expect(users[0].username).to.equal('Tobi');
});
});
......
......@@ -1300,7 +1300,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
it('sorts the results via a date column', function(done) {
var self = this;
self.User.create({username: 'user3', data: 'bar', theDate: moment().add('hours', 2).toDate()}).success(function() {
self.User.create({username: 'user3', data: 'bar', theDate: moment().add(2, 'hours').toDate()}).success(function() {
self.User.findAll({ order: [['theDate', 'DESC']] }).success(function(users) {
expect(users[0].id).to.be.above(users[2].id);
done();
......
......@@ -246,61 +246,46 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
});
});
it('executes select queries correctly', function(done) {
it('executes select queries correctly', function() {
var self = this;
self.sequelize.query(this.insertQuery).success(function() {
self.sequelize
.query('select * from ' + qq(self.User.tableName) + '')
.complete(function(err, users) {
expect(err).to.be.null;
expect(users.map(function(u) { return u.username; })).to.include('john');
done();
});
return self.sequelize.query(this.insertQuery).then(function() {
return self.sequelize.query('select * from ' + qq(self.User.tableName) + '');
}).spread(function(users) {
expect(users.map(function(u) { return u.username; })).to.include('john');
});
});
it('executes select queries correctly when quoteIdentifiers is false', function(done) {
it('executes select queries correctly when quoteIdentifiers is false', function() {
var self = this
, seq = Object.create(self.sequelize);
, seq = Object.create(self.sequelize);
seq.options.quoteIdentifiers = false;
seq.query(this.insertQuery).success(function() {
seq.query('select * from ' + qq(self.User.tableName) + '')
.complete(function(err, users) {
expect(err).to.be.null;
expect(users.map(function(u) { return u.username; })).to.include('john');
done();
});
return seq.query(this.insertQuery).then(function() {
return seq.query('select * from ' + qq(self.User.tableName) + '');
}).spread(function(users) {
expect(users.map(function(u) { return u.username; })).to.include('john');
});
});
it('executes select query with dot notation results', function(done) {
it('executes select query with dot notation results', function() {
var self = this;
self.sequelize.query('DELETE FROM ' + qq(self.User.tableName)).complete(function() {
self.sequelize.query(self.insertQuery).success(function() {
self.sequelize
.query('select username as ' + qq('user.username') + ' from ' + qq(self.User.tableName) + '')
.complete(function(err, users) {
expect(err).to.be.null;
expect(users).to.deep.equal([{'user.username': 'john'}]);
done();
});
});
return self.sequelize.query('DELETE FROM ' + qq(self.User.tableName)).then(function() {
return self.sequelize.query(self.insertQuery);
}).then(function() {
return self.sequelize.query('select username as ' + qq('user.username') + ' from ' + qq(self.User.tableName) + '');
}).spread(function( users) {
expect(users).to.deep.equal([{'user.username': 'john'}]);
});
});
it('executes select query with dot notation results and nest it', function(done) {
it('executes select query with dot notation results and nest it', function() {
var self = this;
self.sequelize.query('DELETE FROM ' + qq(self.User.tableName)).complete(function() {
self.sequelize.query(self.insertQuery).success(function() {
self.sequelize
.query('select username as ' + qq('user.username') + ' from ' + qq(self.User.tableName) + '', null, { raw: true, nest: true })
.complete(function(err, users) {
expect(err).to.be.null;
expect(users.map(function(u) { return u.user; })).to.deep.equal([{'username': 'john'}]);
done();
});
});
return self.sequelize.query('DELETE FROM ' + qq(self.User.tableName)).then(function() {
return self.sequelize.query(self.insertQuery);
}).then(function() {
return self.sequelize.query('select username as ' + qq('user.username') + ' from ' + qq(self.User.tableName) + '', null, { raw: true, nest: true });
}).spread(function(users) {
expect(users.map(function(u) { return u.user; })).to.deep.equal([{'username': 'john'}]);
});
});
......@@ -334,14 +319,11 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
});
});
it('dot separated attributes when doing a raw query without nest', function(done) {
it('dot separated attributes when doing a raw query without nest', function() {
var tickChar = (dialect === 'postgres' || dialect === 'mssql') ? '"' : '`'
, sql = 'select 1 as ' + Sequelize.Utils.addTicks('foo.bar.baz', tickChar);
this.sequelize.query(sql, null, { raw: true, nest: false }).success(function(result) {
expect(result).to.deep.equal([{ 'foo.bar.baz': 1 }]);
done();
});
return expect(this.sequelize.query(sql, null, { raw: true, nest: false }).get(0)).to.eventually.deep.equal([{ 'foo.bar.baz': 1 }]);
});
it('destructs dot separated attributes when doing a raw query using nest', function(done) {
......@@ -361,72 +343,59 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
});
});
it('replaces named parameters with the passed object', function(done) {
this.sequelize.query('select :one as foo, :two as bar', null, { raw: true }, { one: 1, two: 2 }).success(function(result) {
expect(result).to.deep.equal([{ foo: 1, bar: 2 }]);
done();
});
it('replaces named parameters with the passed object', function() {
return expect(this.sequelize.query('select :one as foo, :two as bar', null, { raw: true }, { one: 1, two: 2 }).get(0))
.to.eventually.deep.equal([{ foo: 1, bar: 2 }]);
});
it('replaces named parameters with the passed object and ignore those which does not qualify', function(done) {
this.sequelize.query('select :one as foo, :two as bar, \'00:00\' as baz', null, { raw: true }, { one: 1, two: 2 }).success(function(result) {
expect(result).to.deep.equal([{ foo: 1, bar: 2, baz: '00:00' }]);
done();
});
it('replaces named parameters with the passed object and ignore those which does not qualify', function() {
return expect(this.sequelize.query('select :one as foo, :two as bar, \'00:00\' as baz', null, { raw: true }, { one: 1, two: 2 }).get(0))
.to.eventually.deep.equal([{ foo: 1, bar: 2, baz: '00:00' }]);
});
it('replaces named parameters with the passed object using the same key twice', function(done) {
this.sequelize.query('select :one as foo, :two as bar, :one as baz', null, { raw: true }, { one: 1, two: 2 }).success(function(result) {
expect(result).to.deep.equal([{ foo: 1, bar: 2, baz: 1 }]);
done();
});
it('replaces named parameters with the passed object using the same key twice', function() {
return expect(this.sequelize.query('select :one as foo, :two as bar, :one as baz', null, { raw: true }, { one: 1, two: 2 }).get(0))
.to.eventually.deep.equal([{ foo: 1, bar: 2, baz: 1 }]);
});
it('replaces named parameters with the passed object having a null property', function(done) {
this.sequelize.query('select :one as foo, :two as bar', null, { raw: true }, { one: 1, two: null }).success(function(result) {
expect(result).to.deep.equal([{ foo: 1, bar: null }]);
done();
});
it('replaces named parameters with the passed object having a null property', function() {
return expect(this.sequelize.query('select :one as foo, :two as bar', null, { raw: true }, { one: 1, two: null }).get(0))
.to.eventually.deep.equal([{ foo: 1, bar: null }]);
});
it('throw an exception when key is missing in the passed object', function(done) {
it('throw an exception when key is missing in the passed object', function() {
var self = this;
expect(function() {
self.sequelize.query('select :one as foo, :two as bar, :three as baz', null, { raw: true }, { one: 1, two: 2 });
}).to.throw(Error, /Named parameter ":\w+" has no value in the given object\./g);
done();
});
it('throw an exception with the passed number', function(done) {
it('throw an exception with the passed number', function() {
var self = this;
expect(function() {
self.sequelize.query('select :one as foo, :two as bar', null, { raw: true }, 2);
}).to.throw(Error, /Named parameter ":\w+" has no value in the given object\./g);
done();
});
it('throw an exception with the passed empty object', function(done) {
it('throw an exception with the passed empty object', function() {
var self = this;
expect(function() {
self.sequelize.query('select :one as foo, :two as bar', null, { raw: true }, {});
}).to.throw(Error, /Named parameter ":\w+" has no value in the given object\./g);
done();
});
it('throw an exception with the passed string', function(done) {
it('throw an exception with the passed string', function() {
var self = this;
expect(function() {
self.sequelize.query('select :one as foo, :two as bar', null, { raw: true }, 'foobar');
}).to.throw(Error, /Named parameter ":\w+" has no value in the given object\./g);
done();
});
it('throw an exception with the passed date', function(done) {
it('throw an exception with the passed date', function() {
var self = this;
expect(function() {
self.sequelize.query('select :one as foo, :two as bar', null, { raw: true }, new Date());
}).to.throw(Error, /Named parameter ":\w+" has no value in the given object\./g);
done();
});
it('handles AS in conjunction with functions just fine', function(done) {
......@@ -435,28 +404,20 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
datetime = 'GETDATE()';
}
this.sequelize.query('SELECT ' + datetime + ' AS t').success(function(result) {
return this.sequelize.query('SELECT ' + datetime + ' AS t').spread(function(result) {
expect(moment(result[0].t).isValid()).to.be.true;
done();
});
});
if (Support.getTestDialect() === 'postgres') {
it('replaces named parameters with the passed object and ignores casts', function(done) {
this.sequelize.query('select :one as foo, :two as bar, \'1000\'::integer as baz', null, { raw: true }, { one: 1, two: 2 }).success(function(result) {
expect(result).to.deep.equal([{ foo: 1, bar: 2, baz: 1000 }]);
done();
});
it('replaces named parameters with the passed object and ignores casts', function() {
return expect(this.sequelize.query('select :one as foo, :two as bar, \'1000\'::integer as baz', null, { raw: true }, { one: 1, two: 2 }).get(0))
.to.eventually.deep.equal([{ foo: 1, bar: 2, baz: 1000 }]);
});
it('supports WITH queries', function(done) {
this
.sequelize
.query('WITH RECURSIVE t(n) AS ( VALUES (1) UNION ALL SELECT n+1 FROM t WHERE n < 100) SELECT sum(n) FROM t')
.success(function(results) {
expect(results).to.deep.equal([{ 'sum': '5050' }]);
done();
});
it('supports WITH queries', function() {
return expect(this.sequelize.query('WITH RECURSIVE t(n) AS ( VALUES (1) UNION ALL SELECT n+1 FROM t WHERE n < 100) SELECT sum(n) FROM t').get(0))
.to.eventually.deep.equal([{ 'sum': '5050' }]);
});
}
});
......@@ -924,7 +885,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
self
.sequelizeWithTransaction
.query(sql, null, { plain: true, raw: true, transaction: transaction })
.success(function(result) { callback(result.cnt); });
.spread(function(result) { callback(result.cnt); });
};
TransactionTest.sync({ force: true }).success(function() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!