From f8758286e2cb90859df3b4da1eb58c6400df7b4c Mon Sep 17 00:00:00 2001 From: Harminder Virk Date: Sun, 8 May 2022 15:10:33 +0530 Subject: [PATCH] feat: add where"JSON" methods introduced by Knex 1.0 --- adonis-typings/querybuilder.ts | 75 +- src/Database/QueryBuilder/Chainable.ts | 282 ++++ test/database/query-builder.spec.ts | 1682 ++++++++++++++++++++++++ 3 files changed, 2038 insertions(+), 1 deletion(-) diff --git a/adonis-typings/querybuilder.ts b/adonis-typings/querybuilder.ts index 47f3e377..8dd6747c 100644 --- a/adonis-typings/querybuilder.ts +++ b/adonis-typings/querybuilder.ts @@ -152,7 +152,52 @@ declare module '@ioc:Adonis/Lucid/Database' { /** * Key-value pair. The value can also be a subquery */ - (key: string | RawQuery, value: StrictValues | ChainableContract): Builder + (key: string, value: StrictValues | ChainableContract): Builder + } + + /** + * Possible signatures for adding a whereLike clause + */ + interface WhereJson { + /** + * Key-value pair. The value can also be a subquery + */ + ( + column: string, + value: Record | ChainableContract | QueryCallback + ): Builder + } + + interface WhereJsonPath { + ( + column: string, + jsonPath: string, + value: + | string + | number + | boolean + | string[] + | number[] + | boolean[] + | Record + | ChainableContract + | QueryCallback + ): Builder + ( + column: string, + jsonPath: string, + operator: string, + value: + | string + | number + | boolean + | string[] + | number[] + | boolean[] + | Record + | ChainableContract + | QueryCallback + ): Builder } /** @@ -531,6 +576,34 @@ declare module '@ioc:Adonis/Lucid/Database' { orWhereILike: WhereLike andWhereILike: WhereLike + whereJson: WhereJson + orWhereJson: WhereJson + andWhereJson: WhereJson + + whereNotJson: WhereJson + orWhereNotJson: WhereJson + andWhereNotJson: WhereJson + + whereJsonSuperset: WhereJson + orWhereJsonSuperset: WhereJson + andWhereJsonSuperset: WhereJson + + whereNotJsonSuperset: WhereJson + orWhereNotJsonSuperset: WhereJson + andWhereNotJsonSuperset: WhereJson + + whereJsonSubset: WhereJson + orWhereJsonSubset: WhereJson + andWhereJsonSubset: WhereJson + + whereNotJsonSubset: WhereJson + orWhereNotJsonSubset: WhereJson + andWhereNotJsonSubset: WhereJson + + whereJsonPath: WhereJsonPath + orWhereJsonPath: WhereJsonPath + andWhereJsonPath: WhereJsonPath + join: Join innerJoin: Join leftJoin: Join diff --git a/src/Database/QueryBuilder/Chainable.ts b/src/Database/QueryBuilder/Chainable.ts index 31c72e4b..7b690d94 100644 --- a/src/Database/QueryBuilder/Chainable.ts +++ b/src/Database/QueryBuilder/Chainable.ts @@ -892,6 +892,288 @@ export abstract class Chainable extends Macroable implements ChainableContract { return this.andWhere(key, 'ilike', value) } + /** + * Define a where clause with value that matches for JSON + */ + public whereJson(column: string, value: any) { + const whereClauses = this.getRecentStackItem() + + whereClauses.push({ + method: 'whereJsonObject', + args: [this.resolveColumn(column), this.transformValue(value)], + }) + + return this + } + + /** + * Define a or where clause with value that matches for JSON + */ + public orWhereJson(column: string, value: any) { + const whereClauses = this.getRecentStackItem() + + whereClauses.push({ + method: 'orWhereJsonObject', + args: [this.resolveColumn(column), this.transformValue(value)], + }) + + return this + } + + /** + * Define a where clause with value that matches for JSON + * + * @alias whereJson + */ + public andWhereJson(column: string, value: any) { + return this.whereJson(column, value) + } + + /** + * Define a where clause with value that matches for JSON + */ + public whereNotJson(column: string, value: any) { + const whereClauses = this.getRecentStackItem() + + whereClauses.push({ + method: 'whereNotJsonObject', + args: [this.resolveColumn(column), this.transformValue(value)], + }) + + return this + } + + /** + * Define a or where clause with value that matches for JSON + */ + public orWhereNotJson(column: string, value: any) { + const whereClauses = this.getRecentStackItem() + + whereClauses.push({ + method: 'orWhereNotJsonObject', + args: [this.resolveColumn(column), this.transformValue(value)], + }) + + return this + } + + /** + * Define a where clause with value that matches for JSON + * + * @alias whereNotJson + */ + public andWhereNotJson(column: string, value: any) { + return this.whereNotJson(column, value) + } + + /** + * Define a where clause with value that matches for a superset of + * JSON + */ + public whereJsonSuperset(column: string, value: any) { + const whereClauses = this.getRecentStackItem() + + whereClauses.push({ + method: 'whereJsonSupersetOf', + args: [this.resolveColumn(column), this.transformValue(value)], + }) + + return this + } + + /** + * Define a or where clause with value that matches for a superset of + * JSON + */ + public orWhereJsonSuperset(column: string, value: any) { + const whereClauses = this.getRecentStackItem() + + whereClauses.push({ + method: 'orWhereJsonSupersetOf', + args: [this.resolveColumn(column), this.transformValue(value)], + }) + + return this + } + + /** + * Define or where clause with value that matches for a superset of + * JSON + * + * @alias whereJsonSuperset + */ + public andWhereJsonSuperset(column: string, value: any) { + return this.whereJsonSuperset(column, value) + } + + /** + * Define a where clause with value that matches for a superset of + * JSON + */ + public whereNotJsonSuperset(column: string, value: any) { + const whereClauses = this.getRecentStackItem() + + whereClauses.push({ + method: 'whereJsonNotSupersetOf', + args: [this.resolveColumn(column), this.transformValue(value)], + }) + + return this + } + + /** + * Define a or where clause with value that matches for a superset of + * JSON + */ + public orWhereNotJsonSuperset(column: string, value: any) { + const whereClauses = this.getRecentStackItem() + + whereClauses.push({ + method: 'orWhereJsonNotSupersetOf', + args: [this.resolveColumn(column), this.transformValue(value)], + }) + + return this + } + + /** + * Define or where clause with value that matches for a superset of + * JSON + * + * @alias whereNotJsonSuperset + */ + public andWhereNotJsonSuperset(column: string, value: any) { + return this.whereNotJsonSuperset(column, value) + } + + /** + * Define a where clause with value that matches for a subset of + * JSON + */ + public whereJsonSubset(column: string, value: any) { + const whereClauses = this.getRecentStackItem() + + whereClauses.push({ + method: 'whereJsonSubsetOf', + args: [this.resolveColumn(column), this.transformValue(value)], + }) + + return this + } + + /** + * Define a or where clause with value that matches for a subset of + * JSON + */ + public orWhereJsonSubset(column: string, value: any) { + const whereClauses = this.getRecentStackItem() + + whereClauses.push({ + method: 'orWhereJsonSubsetOf', + args: [this.resolveColumn(column), this.transformValue(value)], + }) + + return this + } + + /** + * Define or where clause with value that matches for a subset of + * JSON + * + * @alias whereJsonSubset + */ + public andWhereJsonSubset(column: string, value: any) { + return this.whereJsonSubset(column, value) + } + + /** + * Define a where clause with value that matches for a subset of + * JSON + */ + public whereNotJsonSubset(column: string, value: any) { + const whereClauses = this.getRecentStackItem() + + whereClauses.push({ + method: 'whereJsonNotSubsetOf', + args: [this.resolveColumn(column), this.transformValue(value)], + }) + + return this + } + + /** + * Define a or where clause with value that matches for a subset of + * JSON + */ + public orWhereNotJsonSubset(column: string, value: any) { + const whereClauses = this.getRecentStackItem() + + whereClauses.push({ + method: 'orWhereJsonNotSubsetOf', + args: [this.resolveColumn(column), this.transformValue(value)], + }) + + return this + } + + /** + * Define or where clause with value that matches for a subset of + * JSON + * + * @alias whereNotJsonSubset + */ + public andWhereNotJsonSubset(column: string, value: any) { + return this.whereNotJsonSubset(column, value) + } + + /** + * Adds a where clause with comparison of a value returned + * by a JsonPath given an operator and a value. + */ + public whereJsonPath(column: string, jsonPath: string, operator: any, value?: any): this { + const whereClauses = this.getRecentStackItem() + if (!value) { + value = operator + operator = '=' + } + + whereClauses.push({ + method: 'whereJsonPath', + args: [this.resolveColumn(column), jsonPath, operator, this.transformValue(value)], + }) + + return this + } + + /** + * Adds a or where clause with comparison of a value returned + * by a JsonPath given an operator and a value. + */ + public orWhereJsonPath(column: string, jsonPath: string, operator: any, value?: any): this { + const whereClauses = this.getRecentStackItem() + if (!value) { + value = operator + operator = '=' + } + + whereClauses.push({ + method: 'orWhereJsonPath', + args: [this.resolveColumn(column), jsonPath, operator, this.transformValue(value)], + }) + + return this + } + + /** + * Adds a where clause with comparison of a value returned + * by a JsonPath given an operator and a value. + * + * @alias whereJsonPath + */ + public andWhereJsonPath(column: string, jsonPath: string, operator: any, value?: any): this { + return this.whereJsonPath(column, jsonPath, operator, value) + } + /** * Add a join clause */ diff --git a/test/database/query-builder.spec.ts b/test/database/query-builder.spec.ts index 8dc9bada..bee76b45 100644 --- a/test/database/query-builder.spec.ts +++ b/test/database/query-builder.spec.ts @@ -4174,6 +4174,41 @@ test.group('Query Builder | join', (group) => { await connection.disconnect() }) + + test('use onJsonPathEquals method from the join callback', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + const db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .join('profiles', (builder) => { + builder.onJsonPathEquals( + 'country_name', // json column in cities + '$.country.name', // json path to country name in 'country_name' column + 'description', // json column in country + '$.name' // json field in 'description' column + ) + }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .join('profiles', (builder) => { + builder.onJsonPathEquals( + 'country_name', // json column in cities + '$.country.name', // json path to country name in 'country_name' column + 'description', // json column in country + '$.name' // json field in 'description' column + ) + }) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + await connection.disconnect() + }) }) test.group('Query Builder | innerJoin', (group) => { @@ -12702,3 +12737,1650 @@ test.group('Query Builder | whereILike', (group) => { await connection.disconnect() }) }) + +test.group('Query Builder | whereJson', (group) => { + group.setup(async () => { + app = await setupApplication() + await setup() + }) + + group.teardown(async () => { + await cleanup() + await fs.cleanup() + }) + + group.each.teardown(async () => { + app.container.use('Adonis/Core/Event').clearListeners('db:query') + await resetTables() + }) + + test('add where json clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db.from('users').whereJson('location', { country: 'India' }).toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonObject('location', { country: 'India' }) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + /** + * Using keys resolver + */ + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJson('location', { country: 'India' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonObject('my_location', { country: 'India' }) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + await connection.disconnect() + }) + + test('wrap where json clause to its own group', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJson('location', { country: 'India' }) + .orWhereJson('location', { country: 'Brazil' }) + .wrapExisting() + .whereNull('deleted_at') + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .where((q) => + q + .whereJsonObject('location', { country: 'India' }) + .orWhereJsonObject('location', { country: 'Brazil' }) + ) + .where((q) => q.whereNull('deleted_at')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + /** + * Using keys resolver + */ + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJson('location', { country: 'India' }) + .orWhereJson('location', { country: 'Brazil' }) + .wrapExisting() + .whereNull('deleted_at') + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .where((q) => + q + .whereJsonObject('my_location', { country: 'India' }) + .orWhereJsonObject('my_location', { country: 'Brazil' }) + ) + .where((q) => q.whereNull('my_deleted_at')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + await connection.disconnect() + }) + + test('add orWhereJson clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJson('location', { country: 'India' }) + .orWhereJson('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonObject('location', { country: 'India' }) + .orWhereJsonObject('location', { country: 'Brazil' }) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJson('location', { country: 'India' }) + .orWhereJson('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonObject('my_location', { country: 'India' }) + .orWhereJsonObject('my_location', { country: 'Brazil' }) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('wrap orWhereJson clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJson('location', { country: 'India' }) + .wrapExisting() + .orWhereJson('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .where((q) => q.whereJsonObject('location', { country: 'India' })) + .orWhere((q) => q.whereJsonObject('location', { country: 'Brazil' })) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJson('location', { country: 'India' }) + .wrapExisting() + .orWhereJson('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .where((q) => q.whereJsonObject('my_location', { country: 'India' })) + .orWhere((q) => q.whereJsonObject('my_location', { country: 'Brazil' })) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('define whereJson value as a callback', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJson('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonObject('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJson('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonObject('my_location', (q) => q.from('locations').where('my_user_id', '1')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('define whereJson value as a subquery', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJson( + 'location', + getQueryBuilder(getQueryClient(connection, app)).from('locations').where('user_id', '1') + ) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonObject('location', connection.client!.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJson( + 'location', + getQueryBuilder(getQueryClient(connection, app)).from('locations').where('user_id', '1') + ) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonObject('my_location', connection.client!.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) +}) + +test.group('Query Builder | whereNotJson', (group) => { + group.setup(async () => { + app = await setupApplication() + await setup() + }) + + group.teardown(async () => { + await cleanup() + await fs.cleanup() + }) + + group.each.teardown(async () => { + app.container.use('Adonis/Core/Event').clearListeners('db:query') + await resetTables() + }) + + test('add where not json clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJson('location', { country: 'India' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereNotJsonObject('location', { country: 'India' }) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + /** + * Using keys resolver + */ + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJson('location', { country: 'India' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereNotJsonObject('my_location', { country: 'India' }) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + await connection.disconnect() + }) + + test('wrap where not json clause to its own group', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJson('location', { country: 'India' }) + .orWhereNotJson('location', { country: 'Brazil' }) + .wrapExisting() + .whereNull('deleted_at') + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .where((q) => + q + .whereNotJsonObject('location', { country: 'India' }) + .orWhereNotJsonObject('location', { country: 'Brazil' }) + ) + .where((q) => q.whereNull('deleted_at')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + /** + * Using keys resolver + */ + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJson('location', { country: 'India' }) + .orWhereNotJson('location', { country: 'Brazil' }) + .wrapExisting() + .whereNull('deleted_at') + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .where((q) => + q + .whereNotJsonObject('my_location', { country: 'India' }) + .orWhereNotJsonObject('my_location', { country: 'Brazil' }) + ) + .where((q) => q.whereNull('my_deleted_at')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + await connection.disconnect() + }) + + test('add orWhereNotJson clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJson('location', { country: 'India' }) + .orWhereNotJson('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereNotJsonObject('location', { country: 'India' }) + .orWhereNotJsonObject('location', { country: 'Brazil' }) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJson('location', { country: 'India' }) + .orWhereNotJson('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereNotJsonObject('my_location', { country: 'India' }) + .orWhereNotJsonObject('my_location', { country: 'Brazil' }) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('wrap orWhereNotJson clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJson('location', { country: 'India' }) + .wrapExisting() + .orWhereNotJson('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .where((q) => q.whereNotJsonObject('location', { country: 'India' })) + .orWhere((q) => q.whereNotJsonObject('location', { country: 'Brazil' })) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJson('location', { country: 'India' }) + .wrapExisting() + .orWhereNotJson('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .where((q) => q.whereNotJsonObject('my_location', { country: 'India' })) + .orWhere((q) => q.whereNotJsonObject('my_location', { country: 'Brazil' })) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('define whereNotJson value as a callback', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJson('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereNotJsonObject('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJson('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereNotJsonObject('my_location', (q) => q.from('locations').where('my_user_id', '1')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('define whereNotJson value as a subquery', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJson( + 'location', + getQueryBuilder(getQueryClient(connection, app)).from('locations').where('user_id', '1') + ) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereNotJsonObject('location', connection.client!.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJson( + 'location', + getQueryBuilder(getQueryClient(connection, app)).from('locations').where('user_id', '1') + ) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereNotJsonObject('my_location', connection.client!.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) +}) + +test.group('Query Builder | whereJsonSuperset', (group) => { + group.setup(async () => { + app = await setupApplication() + await setup() + }) + + group.teardown(async () => { + await cleanup() + await fs.cleanup() + }) + + group.each.teardown(async () => { + app.container.use('Adonis/Core/Event').clearListeners('db:query') + await resetTables() + }) + + test('add where json superset clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJsonSuperset('location', { country: 'India' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonSupersetOf('location', { country: 'India' }) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + /** + * Using keys resolver + */ + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJsonSuperset('location', { country: 'India' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonSupersetOf('my_location', { country: 'India' }) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + await connection.disconnect() + }) + + test('wrap where json superset clause to its own group', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJsonSuperset('location', { country: 'India' }) + .orWhereJsonSuperset('location', { country: 'Brazil' }) + .wrapExisting() + .whereNull('deleted_at') + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .where((q) => + q + .whereJsonSupersetOf('location', { country: 'India' }) + .orWhereJsonSupersetOf('location', { country: 'Brazil' }) + ) + .where((q) => q.whereNull('deleted_at')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + /** + * Using keys resolver + */ + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJsonSuperset('location', { country: 'India' }) + .orWhereJsonSuperset('location', { country: 'Brazil' }) + .wrapExisting() + .whereNull('deleted_at') + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .where((q) => + q + .whereJsonSupersetOf('my_location', { country: 'India' }) + .orWhereJsonSupersetOf('my_location', { country: 'Brazil' }) + ) + .where((q) => q.whereNull('my_deleted_at')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + await connection.disconnect() + }) + + test('add orWhereJsonSuperset clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJsonSuperset('location', { country: 'India' }) + .orWhereJsonSuperset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonSupersetOf('location', { country: 'India' }) + .orWhereJsonSupersetOf('location', { country: 'Brazil' }) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJsonSuperset('location', { country: 'India' }) + .orWhereJsonSuperset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonSupersetOf('my_location', { country: 'India' }) + .orWhereJsonSupersetOf('my_location', { country: 'Brazil' }) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('wrap orWhereJsonSuperset clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJsonSuperset('location', { country: 'India' }) + .wrapExisting() + .orWhereJsonSuperset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .where((q) => q.whereJsonSupersetOf('location', { country: 'India' })) + .orWhere((q) => q.whereJsonSupersetOf('location', { country: 'Brazil' })) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJsonSuperset('location', { country: 'India' }) + .wrapExisting() + .orWhereJsonSuperset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .where((q) => q.whereJsonSupersetOf('my_location', { country: 'India' })) + .orWhere((q) => q.whereJsonSupersetOf('my_location', { country: 'Brazil' })) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('define whereJsonSuperset value as a callback', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJsonSuperset('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonSupersetOf('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJsonSuperset('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonSupersetOf('my_location', (q) => q.from('locations').where('my_user_id', '1')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('define whereJsonSuperset value as a subquery', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJsonSuperset( + 'location', + getQueryBuilder(getQueryClient(connection, app)).from('locations').where('user_id', '1') + ) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonSupersetOf('location', connection.client!.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJsonSuperset( + 'location', + getQueryBuilder(getQueryClient(connection, app)).from('locations').where('user_id', '1') + ) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonSupersetOf( + 'my_location', + connection.client!.from('locations').where('user_id', '1') + ) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) +}) + +test.group('Query Builder | whereNotJsonSuperset', (group) => { + group.setup(async () => { + app = await setupApplication() + await setup() + }) + + group.teardown(async () => { + await cleanup() + await fs.cleanup() + }) + + group.each.teardown(async () => { + app.container.use('Adonis/Core/Event').clearListeners('db:query') + await resetTables() + }) + + test('add where not json superset clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJsonSuperset('location', { country: 'India' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonNotSupersetOf('location', { country: 'India' }) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + /** + * Using keys resolver + */ + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJsonSuperset('location', { country: 'India' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonNotSupersetOf('my_location', { country: 'India' }) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + await connection.disconnect() + }) + + test('wrap where not json superset clause to its own group', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJsonSuperset('location', { country: 'India' }) + .orWhereNotJsonSuperset('location', { country: 'Brazil' }) + .wrapExisting() + .whereNull('deleted_at') + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .where((q) => + q + .whereJsonNotSupersetOf('location', { country: 'India' }) + .orWhereJsonNotSupersetOf('location', { country: 'Brazil' }) + ) + .where((q) => q.whereNull('deleted_at')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + /** + * Using keys resolver + */ + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJsonSuperset('location', { country: 'India' }) + .orWhereNotJsonSuperset('location', { country: 'Brazil' }) + .wrapExisting() + .whereNull('deleted_at') + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .where((q) => + q + .whereJsonNotSupersetOf('my_location', { country: 'India' }) + .orWhereJsonNotSupersetOf('my_location', { country: 'Brazil' }) + ) + .where((q) => q.whereNull('my_deleted_at')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + await connection.disconnect() + }) + + test('add orWhereNotJsonSuperset clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJsonSuperset('location', { country: 'India' }) + .orWhereNotJsonSuperset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonNotSupersetOf('location', { country: 'India' }) + .orWhereJsonNotSupersetOf('location', { country: 'Brazil' }) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJsonSuperset('location', { country: 'India' }) + .orWhereNotJsonSuperset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonNotSupersetOf('my_location', { country: 'India' }) + .orWhereJsonNotSupersetOf('my_location', { country: 'Brazil' }) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('wrap orWhereNotJsonSuperset clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJsonSuperset('location', { country: 'India' }) + .wrapExisting() + .orWhereNotJsonSuperset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .where((q) => q.whereJsonNotSupersetOf('location', { country: 'India' })) + .orWhere((q) => q.whereJsonNotSupersetOf('location', { country: 'Brazil' })) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJsonSuperset('location', { country: 'India' }) + .wrapExisting() + .orWhereNotJsonSuperset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .where((q) => q.whereJsonNotSupersetOf('my_location', { country: 'India' })) + .orWhere((q) => q.whereJsonNotSupersetOf('my_location', { country: 'Brazil' })) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('define whereNotJsonSuperset value as a callback', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJsonSuperset('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonNotSupersetOf('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJsonSuperset('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonNotSupersetOf('my_location', (q) => q.from('locations').where('my_user_id', '1')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('define whereNotJsonSuperset value as a subquery', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJsonSuperset( + 'location', + getQueryBuilder(getQueryClient(connection, app)).from('locations').where('user_id', '1') + ) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonNotSupersetOf( + 'location', + connection.client!.from('locations').where('user_id', '1') + ) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJsonSuperset( + 'location', + getQueryBuilder(getQueryClient(connection, app)).from('locations').where('user_id', '1') + ) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonNotSupersetOf( + 'my_location', + connection.client!.from('locations').where('user_id', '1') + ) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) +}) + +test.group('Query Builder | whereJsonSubset', (group) => { + group.setup(async () => { + app = await setupApplication() + await setup() + }) + + group.teardown(async () => { + await cleanup() + await fs.cleanup() + }) + + group.each.teardown(async () => { + app.container.use('Adonis/Core/Event').clearListeners('db:query') + await resetTables() + }) + + test('add where json subset clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJsonSubset('location', { country: 'India' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonSubsetOf('location', { country: 'India' }) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + /** + * Using keys resolver + */ + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJsonSubset('location', { country: 'India' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonSubsetOf('my_location', { country: 'India' }) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + await connection.disconnect() + }) + + test('wrap where json subset clause to its own group', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJsonSubset('location', { country: 'India' }) + .orWhereJsonSubset('location', { country: 'Brazil' }) + .wrapExisting() + .whereNull('deleted_at') + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .where((q) => + q + .whereJsonSubsetOf('location', { country: 'India' }) + .orWhereJsonSubsetOf('location', { country: 'Brazil' }) + ) + .where((q) => q.whereNull('deleted_at')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + /** + * Using keys resolver + */ + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJsonSubset('location', { country: 'India' }) + .orWhereJsonSubset('location', { country: 'Brazil' }) + .wrapExisting() + .whereNull('deleted_at') + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .where((q) => + q + .whereJsonSubsetOf('my_location', { country: 'India' }) + .orWhereJsonSubsetOf('my_location', { country: 'Brazil' }) + ) + .where((q) => q.whereNull('my_deleted_at')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + await connection.disconnect() + }) + + test('add orWhereJsonSubset clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJsonSubset('location', { country: 'India' }) + .orWhereJsonSubset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonSubsetOf('location', { country: 'India' }) + .orWhereJsonSubsetOf('location', { country: 'Brazil' }) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJsonSubset('location', { country: 'India' }) + .orWhereJsonSubset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonSubsetOf('my_location', { country: 'India' }) + .orWhereJsonSubsetOf('my_location', { country: 'Brazil' }) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('wrap orWhereJsonSubset clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJsonSubset('location', { country: 'India' }) + .wrapExisting() + .orWhereJsonSubset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .where((q) => q.whereJsonSubsetOf('location', { country: 'India' })) + .orWhere((q) => q.whereJsonSubsetOf('location', { country: 'Brazil' })) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJsonSubset('location', { country: 'India' }) + .wrapExisting() + .orWhereJsonSubset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .where((q) => q.whereJsonSubsetOf('my_location', { country: 'India' })) + .orWhere((q) => q.whereJsonSubsetOf('my_location', { country: 'Brazil' })) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('define whereJsonSubset value as a callback', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJsonSubset('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonSubsetOf('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJsonSubset('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonSubsetOf('my_location', (q) => q.from('locations').where('my_user_id', '1')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('define whereJsonSubset value as a subquery', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereJsonSubset( + 'location', + getQueryBuilder(getQueryClient(connection, app)).from('locations').where('user_id', '1') + ) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonSubsetOf('location', connection.client!.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereJsonSubset( + 'location', + getQueryBuilder(getQueryClient(connection, app)).from('locations').where('user_id', '1') + ) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonSubsetOf('my_location', connection.client!.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) +}) + +test.group('Query Builder | whereNotJsonSubset', (group) => { + group.setup(async () => { + app = await setupApplication() + await setup() + }) + + group.teardown(async () => { + await cleanup() + await fs.cleanup() + }) + + group.each.teardown(async () => { + app.container.use('Adonis/Core/Event').clearListeners('db:query') + await resetTables() + }) + + test('add where not json subset clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJsonSubset('location', { country: 'India' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonNotSubsetOf('location', { country: 'India' }) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + /** + * Using keys resolver + */ + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJsonSubset('location', { country: 'India' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonNotSubsetOf('my_location', { country: 'India' }) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + await connection.disconnect() + }) + + test('wrap where not json Subset clause to its own group', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJsonSubset('location', { country: 'India' }) + .orWhereNotJsonSubset('location', { country: 'Brazil' }) + .wrapExisting() + .whereNull('deleted_at') + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .where((q) => + q + .whereJsonNotSubsetOf('location', { country: 'India' }) + .orWhereJsonNotSubsetOf('location', { country: 'Brazil' }) + ) + .where((q) => q.whereNull('deleted_at')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + /** + * Using keys resolver + */ + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJsonSubset('location', { country: 'India' }) + .orWhereNotJsonSubset('location', { country: 'Brazil' }) + .wrapExisting() + .whereNull('deleted_at') + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .where((q) => + q + .whereJsonNotSubsetOf('my_location', { country: 'India' }) + .orWhereJsonNotSubsetOf('my_location', { country: 'Brazil' }) + ) + .where((q) => q.whereNull('my_deleted_at')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + await connection.disconnect() + }) + + test('add orWhereNotJsonSubset clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJsonSubset('location', { country: 'India' }) + .orWhereNotJsonSubset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonNotSubsetOf('location', { country: 'India' }) + .orWhereJsonNotSubsetOf('location', { country: 'Brazil' }) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJsonSubset('location', { country: 'India' }) + .orWhereNotJsonSubset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonNotSubsetOf('my_location', { country: 'India' }) + .orWhereJsonNotSubsetOf('my_location', { country: 'Brazil' }) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('wrap orWhereNotJsonSubset clause', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJsonSubset('location', { country: 'India' }) + .wrapExisting() + .orWhereNotJsonSubset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .where((q) => q.whereJsonNotSubsetOf('location', { country: 'India' })) + .orWhere((q) => q.whereJsonNotSubsetOf('location', { country: 'Brazil' })) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJsonSubset('location', { country: 'India' }) + .wrapExisting() + .orWhereNotJsonSubset('location', { country: 'Brazil' }) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .where((q) => q.whereJsonNotSubsetOf('my_location', { country: 'India' })) + .orWhere((q) => q.whereJsonNotSubsetOf('my_location', { country: 'Brazil' })) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('define whereNotJsonSubset value as a callback', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJsonSubset('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonNotSubsetOf('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJsonSubset('location', (q) => q.from('locations').where('user_id', '1')) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonNotSubsetOf('my_location', (q) => q.from('locations').where('my_user_id', '1')) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) + + test('define whereNotJsonSubset value as a subquery', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), app.logger) + connection.connect() + + let db = getQueryBuilder(getQueryClient(connection, app)) + const { sql, bindings } = db + .from('users') + .whereNotJsonSubset( + 'location', + getQueryBuilder(getQueryClient(connection, app)).from('locations').where('user_id', '1') + ) + .toSQL() + + const { sql: knexSql, bindings: knexBindings } = connection + .client!.from('users') + .whereJsonNotSubsetOf('location', connection.client!.from('locations').where('user_id', '1')) + .toSQL() + + assert.equal(sql, knexSql) + assert.deepEqual(bindings, knexBindings) + + db = getQueryBuilder(getQueryClient(connection, app)) + db.keysResolver = (key) => `my_${key}` + + const { sql: resolverSql, bindings: resolverBindings } = db + .from('users') + .whereNotJsonSubset( + 'location', + getQueryBuilder(getQueryClient(connection, app)).from('locations').where('user_id', '1') + ) + .toSQL() + + const { sql: knexResolverSql, bindings: knexResolverBindings } = connection + .client!.from('users') + .whereJsonNotSubsetOf( + 'my_location', + connection.client!.from('locations').where('user_id', '1') + ) + .toSQL() + + assert.equal(resolverSql, knexResolverSql) + assert.deepEqual(resolverBindings, knexResolverBindings) + + await connection.disconnect() + }) +})