From 30392bcdce9d2d5b585fd7aa2d01f87a2d25d4a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ad=C3=A1mek?= Date: Thu, 13 May 2021 13:44:35 +0200 Subject: [PATCH] fix(query-builder): validate missing `onConflict` calls Also allows calling `onConflict()` without parameter. Closes #1803 --- packages/knex/src/query/QueryBuilder.ts | 14 +++++++++++--- tests/QueryBuilder.test.ts | 23 +++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/knex/src/query/QueryBuilder.ts b/packages/knex/src/query/QueryBuilder.ts index 00f7deb682b5..a193cee8c45c 100644 --- a/packages/knex/src/query/QueryBuilder.ts +++ b/packages/knex/src/query/QueryBuilder.ts @@ -250,19 +250,27 @@ export class QueryBuilder = AnyEntity> { return this; } - onConflict(fields: string | string[]): this { + onConflict(fields: string | string[] = []): this { this._onConflict = this._onConflict || []; this._onConflict.push({ fields: Utils.asArray(fields) }); return this; } ignore(): this { - this._onConflict![this._onConflict!.length - 1].ignore = true; + if (!this._onConflict) { + throw new Error('You need to call `qb.onConflict()` first to use `qb.ignore()`'); + } + + this._onConflict[this._onConflict.length - 1].ignore = true; return this; } merge(data?: EntityData | Field[]): this { - this._onConflict![this._onConflict!.length - 1].merge = data; + if (!this._onConflict) { + throw new Error('You need to call `qb.onConflict()` first to use `qb.merge()`'); + } + + this._onConflict[this._onConflict.length - 1].merge = data; return this; } diff --git a/tests/QueryBuilder.test.ts b/tests/QueryBuilder.test.ts index be0b3780d08c..c2e842af068a 100644 --- a/tests/QueryBuilder.test.ts +++ b/tests/QueryBuilder.test.ts @@ -1228,6 +1228,29 @@ describe('QueryBuilder', () => { expect(qb3.getQuery()).toEqual('insert into `author2` (`created_at`, `email`, `name`, `updated_at`) values (?, ?, ?, ?) on duplicate key update `name` = values(`name`)'); expect(qb3.getParams()).toEqual([timestamp, 'ignore@example.com', 'John Doe', timestamp]); + + const qb4 = orm.em.createQueryBuilder(Author2) + .insert({ + createdAt: timestamp, + email: 'ignore@example.com', + name: 'John Doe', + updatedAt: timestamp, + }) + .onConflict() + .ignore(); + + expect(qb4.getQuery()).toEqual('insert ignore into `author2` (`created_at`, `email`, `name`, `updated_at`) values (?, ?, ?, ?)'); + expect(qb4.getParams()).toEqual([timestamp, 'ignore@example.com', 'John Doe', timestamp]); + + const qb5 = orm.em.createQueryBuilder(Author2) + .insert({ + createdAt: timestamp, + email: 'ignore@example.com', + name: 'John Doe', + updatedAt: timestamp, + }); + expect(() => qb5.ignore()).toThrow('You need to call `qb.onConflict()` first to use `qb.ignore()`'); + expect(() => qb5.merge()).toThrow('You need to call `qb.onConflict()` first to use `qb.merge()`'); }); test('insert many query', async () => {