From 31e291a455f3690f326a36dfab75798304bb5e93 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Thu, 4 Aug 2022 16:27:04 +0530 Subject: [PATCH] fix: add filter and sort support on nested list data Signed-off-by: Pranav C --- .../sql-data-mapper/lib/sql/BaseModelSqlv2.ts | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts index 347c244cc4..5bc1bf4ea5 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts @@ -369,7 +369,7 @@ class BaseModelSqlv2 { async multipleHmList({ colId, ids }, args: { limit?; offset? } = {}) { try { - const { where, ...rest } = this._getListArgs(args as any); + const { where, sort, ...rest } = this._getListArgs(args as any); // todo: get only required fields // const { cn } = this.hasManyRelations.find(({ tn }) => tn === child) || {}; @@ -393,6 +393,7 @@ class BaseModelSqlv2 { const qb = this.dbDriver(childTable.table_name); await childModel.selectObject({ qb }); + await this.applySortAndFilter({ table: childTable, where, qb, sort }); const childQb = this.dbDriver.queryBuilder().from( this.dbDriver @@ -440,6 +441,26 @@ class BaseModelSqlv2 { } } + private async applySortAndFilter({ + table, + where, + qb, + sort, + }: { + table: Model; + where: string; + qb; + sort: string; + }) { + const childAliasColMap = await table.getAliasColObjMap(); + + const filter = extractFilterFromXwhere(where, childAliasColMap); + await conditionV2(filter, qb, this.dbDriver); + if (!sort) return; + const sortObj = extractSortsObject(sort, childAliasColMap); + if (sortObj) await sortV2(sortObj, qb, this.dbDriver); + } + async multipleHmListCount({ colId, ids }) { try { // const { cn } = this.hasManyRelations.find(({ tn }) => tn === child) || {}; @@ -483,7 +504,7 @@ class BaseModelSqlv2 { async hmList({ colId, id }, args: { limit?; offset? } = {}) { try { - const { where, ...rest } = this._getListArgs(args as any); + const { where, sort, ...rest } = this._getListArgs(args as any); // todo: get only required fields const relColumn = (await this.model.getColumns()).find( @@ -505,6 +526,7 @@ class BaseModelSqlv2 { await parentTable.getColumns(); const qb = this.dbDriver(childTable.table_name); + await this.applySortAndFilter({ table: childTable, where, qb, sort }); qb.whereIn( chilCol.column_name, @@ -576,7 +598,7 @@ class BaseModelSqlv2 { { colId, parentIds }, args: { limit?; offset? } = {} ) { - const { where, ...rest } = this._getListArgs(args as any); + const { where, sort, ...rest } = this._getListArgs(args as any); const relColumn = (await this.model.getColumns()).find( (c) => c.id === colId ); @@ -603,6 +625,9 @@ class BaseModelSqlv2 { const qb = this.dbDriver(rtn).join(vtn, `${vtn}.${vrcn}`, `${rtn}.${rcn}`); await childModel.selectObject({ qb }); + + await this.applySortAndFilter({ table: childTable, where, qb, sort }); + const finalQb = this.dbDriver.unionAll( parentIds.map((id) => { const query = qb @@ -646,7 +671,7 @@ class BaseModelSqlv2 { } public async mmList({ colId, parentId }, args: { limit?; offset? } = {}) { - const { where, ...rest } = this._getListArgs(args as any); + const { where, sort, ...rest } = this._getListArgs(args as any); const relColumn = (await this.model.getColumns()).find( (c) => c.id === colId ); @@ -681,6 +706,9 @@ class BaseModelSqlv2 { ); await childModel.selectObject({ qb }); + + await this.applySortAndFilter({ table: childTable, where, qb, sort }); + // todo: sanitize qb.limit(+rest?.limit || 25); qb.offset(+rest?.offset || 0);