import { DataTypes, literal } from '@sequelize/core'; import { expect } from 'chai'; import { beforeAll2, expectsql, sequelize } from '../../support'; describe('QueryGenerator#updateQuery', () => { const queryGenerator = sequelize.queryGenerator; const vars = beforeAll2(() => { const User = sequelize.define( 'User', { firstName: DataTypes.STRING, }, { timestamps: false }, ); return { User }; }); // you'll find more replacement tests in query-generator tests it('parses named replacements in literals', async () => { const { User } = vars; const { query, bind } = queryGenerator.updateQuery( User.table, { firstName: literal(':name'), }, literal('name = :name'), { replacements: { name: 'Zoe', }, }, ); expectsql(query, { default: `UPDATE [Users] SET [firstName]='Zoe' WHERE name = 'Zoe'`, mssql: `UPDATE [Users] SET [firstName]=N'Zoe' WHERE name = N'Zoe'`, db2: `SELECT * FROM FINAL TABLE (UPDATE "Users" SET "firstName"='Zoe' WHERE name = 'Zoe');`, }); expect(bind).to.deep.eq({}); }); it('generates extra bind params', async () => { const { User } = vars; const { query, bind } = queryGenerator.updateQuery( User.table, { firstName: 'John', lastName: literal('$1'), username: 'jd', }, {}, ); // lastName's bind position being changed from $1 to $2 is intentional expectsql(query, { default: 'UPDATE [Users] SET [firstName]=$sequelize_1,[lastName]=$1,[username]=$sequelize_2', db2: `SELECT * FROM FINAL TABLE (UPDATE "Users" SET "firstName"=$sequelize_1,"lastName"=$1,"username"=$sequelize_2);`, }); expect(bind).to.deep.eq({ sequelize_1: 'John', sequelize_2: 'jd', }); }); it('does not generate extra bind params with bindParams: false', async () => { const { User } = vars; const { query, bind } = queryGenerator.updateQuery( User.table, { firstName: 'John', lastName: literal('$1'), username: 'jd', }, literal('first_name = $2'), { bindParam: false, }, ); // lastName's bind position being changed from $1 to $2 is intentional expectsql(query, { default: `UPDATE [Users] SET [firstName]='John',[lastName]=$1,[username]='jd' WHERE first_name = $2`, mssql: `UPDATE [Users] SET [firstName]=N'John',[lastName]=$1,[username]=N'jd' WHERE first_name = $2`, db2: `SELECT * FROM FINAL TABLE (UPDATE "Users" SET "firstName"='John',"lastName"=$1,"username"='jd' WHERE first_name = $2);`, }); expect(bind).to.be.undefined; }); it('binds date values', () => { const result = queryGenerator.updateQuery( 'myTable', { date: new Date('2011-03-27T10:01:55Z'), }, { id: 2 }, ); expectsql(result, { query: { default: 'UPDATE [myTable] SET [date]=$sequelize_1 WHERE [id] = $sequelize_2', db2: 'SELECT * FROM FINAL TABLE (UPDATE "myTable" SET "date"=$sequelize_1 WHERE "id" = $sequelize_2);', }, bind: { mysql: { sequelize_1: '2011-03-27 10:01:55.000', sequelize_2: 2, }, mariadb: { sequelize_1: '2011-03-27 10:01:55.000', sequelize_2: 2, }, db2: { sequelize_1: '2011-03-27 10:01:55.000', sequelize_2: 2, }, ibmi: { sequelize_1: '2011-03-27 10:01:55.000', sequelize_2: 2, }, snowflake: { sequelize_1: '2011-03-27 10:01:55.000', sequelize_2: 2, }, sqlite3: { sequelize_1: '2011-03-27 10:01:55.000 +00:00', sequelize_2: 2, }, postgres: { sequelize_1: '2011-03-27 10:01:55.000 +00:00', sequelize_2: 2, }, mssql: { sequelize_1: '2011-03-27 10:01:55.000 +00:00', sequelize_2: 2, }, }, }); }); it('binds boolean values', () => { const result = queryGenerator.updateQuery( 'myTable', { positive: true, negative: false, }, { id: 2 }, ); expectsql(result, { query: { default: 'UPDATE [myTable] SET [positive]=$sequelize_1,[negative]=$sequelize_2 WHERE [id] = $sequelize_3', db2: 'SELECT * FROM FINAL TABLE (UPDATE "myTable" SET "positive"=$sequelize_1,"negative"=$sequelize_2 WHERE "id" = $sequelize_3);', }, bind: { sqlite3: { sequelize_1: 1, sequelize_2: 0, sequelize_3: 2, }, mysql: { sequelize_1: 1, sequelize_2: 0, sequelize_3: 2, }, mariadb: { sequelize_1: 1, sequelize_2: 0, sequelize_3: 2, }, mssql: { sequelize_1: 1, sequelize_2: 0, sequelize_3: 2, }, postgres: { sequelize_1: true, sequelize_2: false, sequelize_3: 2, }, db2: { sequelize_1: true, sequelize_2: false, sequelize_3: 2, }, ibmi: { sequelize_1: 1, sequelize_2: 0, sequelize_3: 2, }, snowflake: { sequelize_1: true, sequelize_2: false, sequelize_3: 2, }, }, }); }); // TODO: Should we ignore undefined values instead? undefined is closer to "missing property" than null it('treats undefined as null', () => { const { query, bind } = queryGenerator.updateQuery( 'myTable', { value: undefined, name: 'bar', }, { id: 2 }, ); expectsql(query, { default: 'UPDATE [myTable] SET [value]=$sequelize_1,[name]=$sequelize_2 WHERE [id] = $sequelize_3', db2: 'SELECT * FROM FINAL TABLE (UPDATE "myTable" SET "value"=$sequelize_1,"name"=$sequelize_2 WHERE "id" = $sequelize_3);', }); expect(bind).to.deep.eq({ sequelize_1: null, sequelize_2: 'bar', sequelize_3: 2, }); }); });