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

Commit 9b1ca37b by Gareth Oakley Committed by Sushant

feat(query-generator): Generate UPDATEs using bind parameters (#9492)

1 parent 6f158490
......@@ -107,7 +107,7 @@ class QueryGenerator {
const fields = [];
const values = [];
const bind = [];
const bindParam = this.bindParam(bind);
const bindParam = options.bindParam === undefined ? this.bindParam(bind) : options.bindParam;
let query;
let valueQuery = '<%= tmpTable %>INSERT<%= ignoreDuplicates %> INTO <%= table %> (<%= attributes %>)<%= output %> VALUES (<%= values %>)';
let emptyQuery = '<%= tmpTable %>INSERT<%= ignoreDuplicates %> INTO <%= table %><%= output %>';
......@@ -343,6 +343,8 @@ class QueryGenerator {
attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, options.omitNull, options);
const values = [];
const bind = [];
const bindParam = options.bindParam === undefined ? this.bindParam(bind) : options.bindParam;
const modelAttributeMap = {};
let query = '<%= tmpTable %>UPDATE <%= table %> SET <%= values %><%= output %> <%= where %>';
let outputFragment;
......@@ -414,14 +416,20 @@ class QueryGenerator {
}
const value = attrValueHash[key];
values.push(this.quoteIdentifier(key) + '=' + this.escape(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'UPDATE' }));
if (value instanceof Utils.SequelizeMethod || options.bindParam === false) {
values.push(this.quoteIdentifier(key) + '=' + this.escape(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'UPDATE' }));
} else {
values.push(this.quoteIdentifier(key) + '=' + this.format(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'UPDATE' }, bindParam));
}
}
const whereOptions = _.defaults({ bindParam }, options);
const replacements = {
table: this.quoteTable(tableName),
values: values.join(','),
output: outputFragment,
where: this.whereQuery(where, options),
where: this.whereQuery(where, whereOptions),
tmpTable
};
......@@ -429,7 +437,13 @@ class QueryGenerator {
return '';
}
return _.template(query, this._templateSettings)(replacements).trim();
query = _.template(query, this._templateSettings)(replacements).trim();
// Used by Postgres upsertQuery and calls to here with options.exception set to true
const result = { query };
if (options.bindParam !== false) {
result.bind = bind;
}
return result;
}
/**
......@@ -2106,8 +2120,14 @@ class QueryGenerator {
}
}
if (value === null) {
const opValue = options.bindParam ? 'NULL' : this.escape(value, field);
return this._joinKeyValue(key, opValue, this.OperatorMap[Op.is], options.prefix);
}
if (!value) {
return this._joinKeyValue(key, this.escape(value, field), value === null ? this.OperatorMap[Op.is] : this.OperatorMap[Op.eq], options.prefix);
const opValue = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);
return this._joinKeyValue(key, opValue, this.OperatorMap[Op.eq], options.prefix);
}
if (value instanceof Utils.SequelizeMethod && !(key !== undefined && value instanceof Utils.Fn)) {
......@@ -2137,7 +2157,8 @@ class QueryGenerator {
}
if (isArray && fieldType instanceof DataTypes.ARRAY) {
return this._joinKeyValue(key, this.escape(value, field), this.OperatorMap[Op.eq], options.prefix);
const opValue = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);
return this._joinKeyValue(key, opValue, this.OperatorMap[Op.eq], options.prefix);
}
if (isPlainObject && fieldType instanceof DataTypes.JSON && options.json !== false) {
......@@ -2160,10 +2181,12 @@ class QueryGenerator {
}
if (key === Op.placeholder) {
return this._joinKeyValue(this.OperatorMap[key], this.escape(value, field), this.OperatorMap[Op.eq], options.prefix);
const opValue = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);
return this._joinKeyValue(this.OperatorMap[key], opValue, this.OperatorMap[Op.eq], options.prefix);
}
return this._joinKeyValue(key, this.escape(value, field), this.OperatorMap[Op.eq], options.prefix);
const opValue = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);
return this._joinKeyValue(key, opValue, this.OperatorMap[Op.eq], options.prefix);
}
_findField(key, options) {
......
......@@ -78,6 +78,9 @@ module.exports = BaseTypes => {
return options.escape(value);
}
};
STRING.prototype._bindParam = function _bindParam(value, options) {
return options.bindParam(this._binary ? Buffer.from(value) : value);
};
function TEXT(length) {
if (!(this instanceof TEXT)) return new TEXT(length);
......
......@@ -350,10 +350,10 @@ class MSSQLQueryGenerator extends AbstractQueryGenerator {
}
updateQuery(tableName, attrValueHash, where, options, attributes) {
let sql = super.updateQuery(tableName, attrValueHash, where, options, attributes);
const sql = super.updateQuery(tableName, attrValueHash, where, options, attributes);
if (options.limit) {
const updateArgs = `UPDATE TOP(${this.escape(options.limit)})`;
sql = sql.replace('UPDATE', updateArgs);
sql.query = sql.query.replace('UPDATE', updateArgs);
}
return sql;
}
......
......@@ -344,19 +344,19 @@ class PostgresQueryGenerator extends AbstractQueryGenerator {
upsertQuery(tableName, insertValues, updateValues, where, model, options) {
const primaryField = this.quoteIdentifier(model.primaryKeyField);
const insertOptions = _.defaults({ bindParam: false }, options);
const insert = this.insertQuery(tableName, insertValues, model.rawAttributes, insertOptions);
let update = this.updateQuery(tableName, updateValues, where, options, model.rawAttributes);
const upsertOptions = _.defaults({ bindParam: false }, options);
const insert = this.insertQuery(tableName, insertValues, model.rawAttributes, upsertOptions);
const update = this.updateQuery(tableName, updateValues, where, upsertOptions, model.rawAttributes);
insert.query = insert.query.replace('RETURNING *', `RETURNING ${primaryField} INTO primary_key`);
update = update.replace('RETURNING *', `RETURNING ${primaryField} INTO primary_key`);
update.query = update.query.replace('RETURNING *', `RETURNING ${primaryField} INTO primary_key`);
return this.exceptionFn(
'sequelize_upsert',
tableName,
'OUT created boolean, OUT primary_key text',
`${insert.query} created := true;`,
`${update}; created := false`
`${update.query}; created := false`
);
}
......
......@@ -200,11 +200,14 @@ class SQLiteQueryGenerator extends MySqlQueryGenerator {
upsertQuery(tableName, insertValues, updateValues, where, model, options) {
options.ignoreDuplicates = true;
const insert = this.insertQuery(tableName, insertValues, model.rawAttributes, options);
const update = this.updateQuery(tableName, updateValues, where, options, model.rawAttributes);
const bind = [];
const bindParam = this.bindParam(bind);
const query = insert.query + ' ' + update;
const bind = insert.bind;
const upsertOptions = _.defaults({ bindParam }, options);
const insert = this.insertQuery(tableName, insertValues, model.rawAttributes, upsertOptions);
const update = this.updateQuery(tableName, updateValues, where, upsertOptions, model.rawAttributes);
const query = insert.query + ' ' + update.query;
return { query, bind };
}
......@@ -217,6 +220,8 @@ class SQLiteQueryGenerator extends MySqlQueryGenerator {
const modelAttributeMap = {};
const values = [];
const bind = [];
const bindParam = options.bindParam || this.bindParam(bind);
if (attributes) {
_.each(attributes, (attribute, key) => {
......@@ -229,14 +234,24 @@ class SQLiteQueryGenerator extends MySqlQueryGenerator {
for (const key in attrValueHash) {
const value = attrValueHash[key];
values.push(this.quoteIdentifier(key) + '=' + this.escape(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'UPDATE' }));
if (value instanceof Utils.SequelizeMethod || options.bindParam === false) {
values.push(this.quoteIdentifier(key) + '=' + this.escape(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'UPDATE' }));
} else {
values.push(this.quoteIdentifier(key) + '=' + this.format(value, modelAttributeMap && modelAttributeMap[key] || undefined, { context: 'UPDATE' }, bindParam));
}
}
let query;
const whereOptions = _.defaults({ bindParam }, options);
if (options.limit) {
return `UPDATE ${this.quoteTable(tableName)} SET ${values.join(',')} WHERE rowid IN (SELECT rowid FROM ${this.quoteTable(tableName)} ${this.whereQuery(where, options)} LIMIT ${this.escape(options.limit)})`;
query = `UPDATE ${this.quoteTable(tableName)} SET ${values.join(',')} WHERE rowid IN (SELECT rowid FROM ${this.quoteTable(tableName)} ${this.whereQuery(where, whereOptions)} LIMIT ${this.escape(options.limit)})`;
} else {
return `UPDATE ${this.quoteTable(tableName)} SET ${values.join(',')} ${this.whereQuery(where, options)}`;
query = `UPDATE ${this.quoteTable(tableName)} SET ${values.join(',')} ${this.whereQuery(where, whereOptions)}`;
}
return { query, bind };
}
truncateTableQuery(tableName) {
......
......@@ -81,7 +81,7 @@ class Query extends AbstractQuery {
const method = this.getDatabaseMethod();
if (method === 'exec') {
// exec does not support bind parameter
sql = AbstractQuery.formatBindParameters(sql, this.options.bind, this.options.dialect, { skipUnescape: true })[0];
sql = AbstractQuery.formatBindParameters(sql, this.options.bind, this.options.dialect || 'sqlite', { skipUnescape: true })[0];
this.sql = sql;
}
......
......@@ -2763,7 +2763,7 @@ class Model {
attrValueHash[deletedAtAttribute.field || deletedAtCol] = deletedAtDefaultValue;
options.omitNull = false;
return this.QueryInterface.bulkUpdate(this.getTableName(options), attrValueHash, options.where, options, this._timestampAttributes.deletedAt);
return this.QueryInterface.bulkUpdate(this.getTableName(options), attrValueHash, options.where, options, this.rawAttributes);
}).tap(() => {
// Run afterDestroy hook on each record individually
if (options.individualHooks) {
......
......@@ -175,9 +175,15 @@ describe(Support.getTestDialectTeaser('DataTypes'), () => {
return testSuccess(Type, 'foobar');
});
it('calls parse and stringify for STRING', () => {
it('calls parse and stringify/bindParam for STRING', () => {
const Type = new Sequelize.STRING();
// mssql has a _bindParam function that checks if STRING was created with
// the boolean param (if so it outputs a Buffer bind param). This override
// isn't needed for other dialects
if (dialect === 'mssql') {
return testSuccess(Type, 'foobar', { useBindParam: true });
}
return testSuccess(Type, 'foobar');
});
......
......@@ -878,7 +878,7 @@ describe(Support.getTestDialectTeaser('Model'), () => {
if (dialect === 'mssql') {
expect(sql).to.not.contain('createdAt');
} else {
expect(sql).to.match(/UPDATE\s+[`"]+User1s[`"]+\s+SET\s+[`"]+secretValue[`"]='43',[`"]+updatedAt[`"]+='[^`",]+'\s+WHERE [`"]+id[`"]+\s=\s1/);
expect(sql).to.match(/UPDATE\s+[`"]+User1s[`"]+\s+SET\s+[`"]+secretValue[`"]=(\$1|\?),[`"]+updatedAt[`"]+=(\$2|\?)\s+WHERE [`"]+id[`"]+\s=\s(\$3|\?)/);
}
}
});
......
......@@ -940,59 +940,49 @@ describe(Support.getTestDialectTeaser('Model'), () => {
}
});
it('does not cast arrays for postgresql insert', function() {
if (dialect !== 'postgres') {
expect('').to.equal('');
return void 0;
}
const User = this.sequelize.define('UserWithArray', {
myvals: { type: Sequelize.ARRAY(Sequelize.INTEGER) },
mystr: { type: Sequelize.ARRAY(Sequelize.STRING) }
});
let test = false;
return User.sync({force: true}).then(() => {
return User.create({myvals: [], mystr: []}, {
logging(sql) {
test = true;
expect(sql).not.to.contain('ARRAY[]::INTEGER[]');
expect(sql).not.to.contain('ARRAY[]::VARCHAR(255)[]');
}
if (dialect === 'postgres') {
it('does not cast arrays for postgresql insert', function() {
const User = this.sequelize.define('UserWithArray', {
myvals: { type: Sequelize.ARRAY(Sequelize.INTEGER) },
mystr: { type: Sequelize.ARRAY(Sequelize.STRING) }
});
}).then(() => {
expect(test).to.be.true;
});
});
it('casts empty array correct for postgres update', function() {
if (dialect !== 'postgres') {
expect('').to.equal('');
return void 0;
}
const User = this.sequelize.define('UserWithArray', {
myvals: { type: Sequelize.ARRAY(Sequelize.INTEGER) },
mystr: { type: Sequelize.ARRAY(Sequelize.STRING) }
});
let test = false;
return User.sync({force: true}).then(() => {
return User.create({myvals: [1, 2, 3, 4], mystr: ['One', 'Two', 'Three', 'Four']}).then(user => {
user.myvals = [];
user.mystr = [];
return user.save({
let test = false;
return User.sync({force: true}).then(() => {
return User.create({myvals: [], mystr: []}, {
logging(sql) {
test = true;
expect(sql).to.contain('ARRAY[]::INTEGER[]');
expect(sql).to.contain('ARRAY[]::VARCHAR(255)[]');
expect(sql).to.contain('INSERT INTO "UserWithArrays" ("id","myvals","mystr","createdAt","updatedAt") VALUES (DEFAULT,$1,$2,$3,$4)');
}
});
}).then(() => {
expect(test).to.be.true;
});
}).then(() => {
expect(test).to.be.true;
});
});
it('does not cast arrays for postgres update', function() {
const User = this.sequelize.define('UserWithArray', {
myvals: { type: Sequelize.ARRAY(Sequelize.INTEGER) },
mystr: { type: Sequelize.ARRAY(Sequelize.STRING) }
});
let test = false;
return User.sync({force: true}).then(() => {
return User.create({myvals: [1, 2, 3, 4], mystr: ['One', 'Two', 'Three', 'Four']}).then(user => {
user.myvals = [];
user.mystr = [];
return user.save({
logging(sql) {
test = true;
expect(sql).to.contain('UPDATE "UserWithArrays" SET "myvals"=$1,"mystr"=$2,"updatedAt"=$3 WHERE "id" = $4');
}
});
});
}).then(() => {
expect(test).to.be.true;
});
});
}
it("doesn't allow duplicated records with unique:true", function() {
const self = this,
......
......@@ -569,40 +569,71 @@ if (dialect === 'mysql') {
updateQuery: [
{
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: {
query: 'UPDATE `myTable` SET `name`=$1,`birthday`=$2 WHERE `id` = $3',
bind: ['foo', 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))}, {id: 2}],
expectation: "UPDATE `myTable` SET `name`='foo',`birthday`='2011-03-27 10:01:55' WHERE `id` = 2"
expectation: {
query: 'UPDATE `myTable` SET `name`=$1,`birthday`=$2 WHERE `id` = $3',
bind: ['foo', new Date(Date.UTC(2011, 2, 27, 10, 1, 55)), 2]
}
}, {
arguments: ['myTable', {bar: 2}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `bar`=2 WHERE `name` = 'foo'"
expectation: {
query: 'UPDATE `myTable` SET `bar`=$1 WHERE `name` = $2',
bind: [2, 'foo']
}
}, {
arguments: ['myTable', {name: "foo';DROP TABLE myTable;"}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `name`='foo\\';DROP TABLE myTable;' WHERE `name` = 'foo'"
expectation: {
query: 'UPDATE `myTable` SET `name`=$1 WHERE `name` = $2',
bind: ["foo';DROP TABLE myTable;", 'foo']
}
}, {
arguments: ['myTable', {bar: 2, nullValue: null}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `bar`=2,`nullValue`=NULL WHERE `name` = 'foo'"
expectation: {
query: 'UPDATE `myTable` SET `bar`=$1,`nullValue`=$2 WHERE `name` = $3',
bind: [2, null, 'foo']
}
}, {
arguments: ['myTable', {bar: 2, nullValue: null}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `bar`=2,`nullValue`=NULL WHERE `name` = 'foo'",
expectation: {
query: 'UPDATE `myTable` SET `bar`=$1,`nullValue`=$2 WHERE `name` = $3',
bind: [2, null, 'foo']
},
context: {options: {omitNull: false}}
}, {
arguments: ['myTable', {bar: 2, nullValue: null}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `bar`=2 WHERE `name` = 'foo'",
expectation: {
query: 'UPDATE `myTable` SET `bar`=$1 WHERE `name` = $2',
bind: [2, 'foo']
},
context: {options: {omitNull: true}}
}, {
arguments: ['myTable', {bar: false}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `bar`=false WHERE `name` = 'foo'"
expectation: {
query: 'UPDATE `myTable` SET `bar`=$1 WHERE `name` = $2',
bind: [false, 'foo']
}
}, {
arguments: ['myTable', {bar: true}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `bar`=true WHERE `name` = 'foo'"
expectation: {
query: 'UPDATE `myTable` SET `bar`=$1 WHERE `name` = $2',
bind: [true, 'foo']
}
}, {
arguments: ['myTable', function(sequelize) {
return {
bar: sequelize.fn('NOW')
};
}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `bar`=NOW() WHERE `name` = 'foo'",
expectation: {
query: 'UPDATE `myTable` SET `bar`=NOW() WHERE `name` = $1',
bind: ['foo']
},
needsSequelize: true
}, {
arguments: ['myTable', function(sequelize) {
......@@ -610,7 +641,10 @@ if (dialect === 'mysql') {
bar: sequelize.col('foo')
};
}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `bar`=`foo` WHERE `name` = 'foo'",
expectation: {
query: 'UPDATE `myTable` SET `bar`=`foo` WHERE `name` = $1',
bind: ['foo']
},
needsSequelize: true
}
],
......
......@@ -497,38 +497,71 @@ if (dialect === 'sqlite') {
updateQuery: [
{
arguments: ['myTable', {name: 'foo', birthday: moment('2011-03-27 10:01:55 +0000', 'YYYY-MM-DD HH:mm:ss Z').toDate()}, {id: 2}],
expectation: "UPDATE `myTable` SET `name`='foo',`birthday`='2011-03-27 10:01:55.000 +00:00' WHERE `id` = 2"
expectation: {
query: 'UPDATE `myTable` SET `name`=$1,`birthday`=$2 WHERE `id` = $3',
bind: ['foo', moment('2011-03-27 10:01:55 +0000', 'YYYY-MM-DD HH:mm:ss Z').toDate(), 2]
}
}, {
arguments: ['myTable', {name: 'foo', birthday: moment('2011-03-27 10:01:55 +0000', 'YYYY-MM-DD HH:mm:ss Z').toDate()}, {id: 2}],
expectation: "UPDATE `myTable` SET `name`='foo',`birthday`='2011-03-27 10:01:55.000 +00:00' WHERE `id` = 2"
expectation: {
query: 'UPDATE `myTable` SET `name`=$1,`birthday`=$2 WHERE `id` = $3',
bind: ['foo', moment('2011-03-27 10:01:55 +0000', 'YYYY-MM-DD HH:mm:ss Z').toDate(), 2]
}
}, {
arguments: ['myTable', { name: 'foo' }, { id: 2 }],
expectation: "UPDATE `myTable` SET `name`='foo' WHERE `id` = 2"
expectation: {
query: 'UPDATE `myTable` SET `name`=$1 WHERE `id` = $2',
bind: ['foo', 2]
}
}, {
arguments: ['myTable', { name: "'bar'" }, { id: 2 }],
expectation: "UPDATE `myTable` SET `name`='''bar''' WHERE `id` = 2"
expectation: {
query: 'UPDATE `myTable` SET `name`=$1 WHERE `id` = $2',
bind: ["'bar'", 2]
}
}, {
arguments: ['myTable', { name: 'bar', value: null }, { id: 2 }],
expectation: "UPDATE `myTable` SET `name`='bar',`value`=NULL WHERE `id` = 2"
expectation: {
query: 'UPDATE `myTable` SET `name`=$1,`value`=$2 WHERE `id` = $3',
bind: ['bar', null, 2]
}
}, {
arguments: ['myTable', { name: 'bar', value: undefined }, { id: 2 }],
expectation: "UPDATE `myTable` SET `name`='bar',`value`=NULL WHERE `id` = 2"
expectation: {
query: 'UPDATE `myTable` SET `name`=$1,`value`=$2 WHERE `id` = $3',
bind: ['bar', undefined, 2]
}
}, {
arguments: ['myTable', { flag: true }, { id: 2 }],
expectation: 'UPDATE `myTable` SET `flag`=1 WHERE `id` = 2'
expectation: {
query: 'UPDATE `myTable` SET `flag`=$1 WHERE `id` = $2',
bind: [true, 2]
}
}, {
arguments: ['myTable', { flag: false }, { id: 2 }],
expectation: 'UPDATE `myTable` SET `flag`=0 WHERE `id` = 2'
expectation: {
query: 'UPDATE `myTable` SET `flag`=$1 WHERE `id` = $2',
bind: [false, 2]
}
}, {
arguments: ['myTable', {bar: 2, nullValue: null}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `bar`=2,`nullValue`=NULL WHERE `name` = 'foo'"
expectation: {
query: 'UPDATE `myTable` SET `bar`=$1,`nullValue`=$2 WHERE `name` = $3',
bind: [2, null, 'foo']
}
}, {
arguments: ['myTable', {bar: 2, nullValue: null}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `bar`=2,`nullValue`=NULL WHERE `name` = 'foo'",
expectation: {
query: 'UPDATE `myTable` SET `bar`=$1,`nullValue`=$2 WHERE `name` = $3',
bind: [2, null, 'foo']
},
context: {options: {omitNull: false}}
}, {
arguments: ['myTable', {bar: 2, nullValue: null}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `bar`=2 WHERE `name` = 'foo'",
expectation: {
query: 'UPDATE `myTable` SET `bar`=$1 WHERE `name` = $2',
bind: [2, 'foo']
},
context: {options: {omitNull: true}}
}, {
arguments: ['myTable', function(sequelize) {
......@@ -536,7 +569,10 @@ if (dialect === 'sqlite') {
bar: sequelize.fn('NOW')
};
}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `bar`=NOW() WHERE `name` = 'foo'",
expectation: {
query: 'UPDATE `myTable` SET `bar`=NOW() WHERE `name` = $1',
bind: ['foo']
},
needsSequelize: true
}, {
arguments: ['myTable', function(sequelize) {
......@@ -544,7 +580,10 @@ if (dialect === 'sqlite') {
bar: sequelize.col('foo')
};
}, {name: 'foo'}],
expectation: "UPDATE `myTable` SET `bar`=`foo` WHERE `name` = 'foo'",
expectation: {
query: 'UPDATE `myTable` SET `bar`=`foo` WHERE `name` = $1',
bind: ['foo']
},
needsSequelize: true
}
],
......
......@@ -27,9 +27,14 @@ describe(Support.getTestDialectTeaser('SQL'), () => {
};
expectsql(sql.updateQuery(User.tableName, {user_name: 'triggertest'}, {id: 2}, options, User.rawAttributes),
{
mssql: 'declare @tmp table ([id] INTEGER,[user_name] NVARCHAR(255));UPDATE [users] SET [user_name]=N\'triggertest\' OUTPUT INSERTED.[id],INSERTED.[user_name] into @tmp WHERE [id] = 2;select * from @tmp',
postgres: 'UPDATE "users" SET "user_name"=\'triggertest\' WHERE "id" = 2 RETURNING *',
default: "UPDATE `users` SET `user_name`=\'triggertest\' WHERE `id` = 2"
query: {
mssql: 'declare @tmp table ([id] INTEGER,[user_name] NVARCHAR(255));UPDATE [users] SET [user_name]=$1 OUTPUT INSERTED.[id],INSERTED.[user_name] into @tmp WHERE [id] = $2;select * from @tmp',
postgres: 'UPDATE "users" SET "user_name"=$1 WHERE "id" = $2 RETURNING *',
default: 'UPDATE `users` SET `user_name`=$1 WHERE `id` = $2'
},
bind: {
default: ['triggertest', 2]
}
});
});
......@@ -47,10 +52,15 @@ describe(Support.getTestDialectTeaser('SQL'), () => {
});
expectsql(sql.updateQuery(User.tableName, { username: 'new.username' }, { username: 'username' }, { limit: 1 }), {
mssql: "UPDATE TOP(1) [Users] SET [username]=N'new.username' OUTPUT INSERTED.* WHERE [username] = N'username'",
mysql: "UPDATE `Users` SET `username`='new.username' WHERE `username` = 'username' LIMIT 1",
sqlite: "UPDATE `Users` SET `username`='new.username' WHERE rowid IN (SELECT rowid FROM `Users` WHERE `username` = 'username' LIMIT 1)",
default: "UPDATE [Users] SET [username]='new.username' WHERE [username] = 'username'"
query: {
mssql: 'UPDATE TOP(1) [Users] SET [username]=$1 OUTPUT INSERTED.* WHERE [username] = $2',
mysql: 'UPDATE `Users` SET `username`=$1 WHERE `username` = $2 LIMIT 1',
sqlite: 'UPDATE `Users` SET `username`=$1 WHERE rowid IN (SELECT rowid FROM `Users` WHERE `username` = $2 LIMIT 1)',
default: 'UPDATE [Users] SET [username]=$1 WHERE [username] = $2'
},
bind: {
default: ['new.username', 'username']
}
});
});
});
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!