bulk-update.test.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import { DataTypes, Op, literal } from '@sequelize/core';
  2. import { expect } from 'chai';
  3. import sinon from 'sinon';
  4. import { beforeAll2, expectsql, sequelize } from '../../support';
  5. describe('QueryInterface#bulkUpdate', () => {
  6. const vars = beforeAll2(() => {
  7. const User = sequelize.define(
  8. 'User',
  9. {
  10. firstName: DataTypes.STRING,
  11. },
  12. { timestamps: false },
  13. );
  14. return { User };
  15. });
  16. afterEach(() => {
  17. sinon.restore();
  18. });
  19. // you'll find more replacement tests in query-generator tests
  20. it('does not parse replacements outside of raw sql', async () => {
  21. const { User } = vars;
  22. const stub = sinon.stub(sequelize, 'queryRaw').resolves([[], 0]);
  23. await sequelize.queryInterface.bulkUpdate(
  24. User.table,
  25. {
  26. // values
  27. firstName: ':injection',
  28. },
  29. {
  30. // where
  31. firstName: ':injection',
  32. },
  33. {
  34. replacements: {
  35. injection: 'raw sql',
  36. },
  37. },
  38. {},
  39. );
  40. expect(stub.callCount).to.eq(1);
  41. const firstCall = stub.getCall(0);
  42. expectsql(firstCall.args[0], {
  43. default: `UPDATE [Users] SET [firstName]=$sequelize_1 WHERE [firstName] = $sequelize_2`,
  44. db2: `SELECT * FROM FINAL TABLE (UPDATE "Users" SET "firstName"=$sequelize_1 WHERE "firstName" = $sequelize_2);`,
  45. });
  46. expect(firstCall.args[1]?.bind).to.deep.eq({
  47. sequelize_1: ':injection',
  48. sequelize_2: ':injection',
  49. });
  50. });
  51. it('throws if a bind parameter name starts with the reserved "sequelize_" prefix', async () => {
  52. const { User } = vars;
  53. sinon.stub(sequelize, 'queryRaw');
  54. await expect(
  55. sequelize.queryInterface.bulkUpdate(
  56. User.table,
  57. {
  58. firstName: literal('$sequelize_test'),
  59. },
  60. {},
  61. {
  62. bind: {
  63. sequelize_test: 'raw sql',
  64. },
  65. },
  66. ),
  67. ).to.be.rejectedWith(
  68. 'Bind parameters cannot start with "sequelize_", these bind parameters are reserved by Sequelize.',
  69. );
  70. });
  71. it('merges user-provided bind parameters with sequelize-generated bind parameters (object bind)', async () => {
  72. const { User } = vars;
  73. const stub = sinon.stub(sequelize, 'queryRaw');
  74. await sequelize.queryInterface.bulkUpdate(
  75. User.table,
  76. {
  77. firstName: 'newName',
  78. },
  79. {
  80. // where
  81. firstName: { [Op.eq]: literal('$one') },
  82. },
  83. {
  84. bind: { one: 'bind1' },
  85. },
  86. );
  87. expect(stub.callCount).to.eq(1);
  88. const firstCall = stub.getCall(0);
  89. expectsql(firstCall.args[0], {
  90. default: 'UPDATE [Users] SET [firstName]=$sequelize_1 WHERE [firstName] = $one',
  91. db2: `SELECT * FROM FINAL TABLE (UPDATE "Users" SET "firstName"=$sequelize_1 WHERE "firstName" = $one);`,
  92. });
  93. expect(firstCall.args[1]?.bind).to.deep.eq({
  94. sequelize_1: 'newName',
  95. one: 'bind1',
  96. });
  97. });
  98. it('merges user-provided bind parameters with sequelize-generated bind parameters (array bind)', async () => {
  99. const { User } = vars;
  100. const stub = sinon.stub(sequelize, 'queryRaw');
  101. await sequelize.queryInterface.bulkUpdate(
  102. User.table,
  103. {
  104. firstName: 'newName',
  105. },
  106. {
  107. // where
  108. firstName: { [Op.eq]: literal('$1') },
  109. },
  110. {
  111. bind: ['bind1'],
  112. },
  113. );
  114. expect(stub.callCount).to.eq(1);
  115. const firstCall = stub.getCall(0);
  116. expectsql(firstCall.args[0], {
  117. default: 'UPDATE [Users] SET [firstName]=$sequelize_1 WHERE [firstName] = $1',
  118. db2: `SELECT * FROM FINAL TABLE (UPDATE "Users" SET "firstName"=$sequelize_1 WHERE "firstName" = $1);`,
  119. });
  120. expect(firstCall.args[1]?.bind).to.deep.eq({
  121. sequelize_1: 'newName',
  122. 1: 'bind1',
  123. });
  124. });
  125. });