From 11d5c930c02e995d77c629f54d459f40fab368a2 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Thu, 16 Nov 2023 12:24:10 +0000 Subject: [PATCH] feat: lookup support - mm/hm lookup - WIP --- .../src/db/generateMMLookupSelectQuery.ts | 108 ++++++++++-------- 1 file changed, 58 insertions(+), 50 deletions(-) diff --git a/packages/nocodb/src/db/generateMMLookupSelectQuery.ts b/packages/nocodb/src/db/generateMMLookupSelectQuery.ts index baf5a703ae..767ec5e6e9 100644 --- a/packages/nocodb/src/db/generateMMLookupSelectQuery.ts +++ b/packages/nocodb/src/db/generateMMLookupSelectQuery.ts @@ -11,18 +11,23 @@ import type { import formulaQueryBuilderv2 from '~/db/formulav2/formulaQueryBuilderv2'; import genRollupSelectv2 from '~/db/genRollupSelectv2'; import { NcError } from '~/helpers/catchError'; +import {getAliasGenerator} from "~/utils"; export default async function generateBTLookupSelectQuery({ column, baseModelSqlv2, alias, model, + getAlias = getAliasGenerator('__lk_slt_') }: { column: Column; baseModelSqlv2: BaseModelSqlv2; alias: string; model: Model; + getAlias: ReturnType }): Promise { + + const knex = baseModelSqlv2.dbDriver; const rootAlias = alias; @@ -30,7 +35,7 @@ export default async function generateBTLookupSelectQuery({ { let aliasCount = 0, selectQb; - const alias = `__nc_lk_${aliasCount++}`; + const alias = getAlias(); const lookup = await column.getColOptions(); { const relationCol = await lookup.getRelationColumn(); @@ -62,7 +67,7 @@ export default async function generateBTLookupSelectQuery({ let lookupColumn = await lookup.getLookupColumn(); let prevAlias = alias; while (lookupColumn.uidt === UITypes.Lookup) { - const nestedAlias = `__nc_lk_nested_${aliasCount++}`; + const nestedAlias = getAlias(); const nestedLookup = await lookupColumn.getColOptions(); const relationCol = await nestedLookup.getRelationColumn(); const relation = @@ -70,62 +75,65 @@ export default async function generateBTLookupSelectQuery({ // if any of the relation in nested lookup is // not belongs to then throw error as we don't support - if (relation.type !== RelationTypes.BELONGS_TO) { - // NcError.badRequest('HasMany/ManyToMany lookup is not supported'); - } + if (relation.type === RelationTypes.BELONGS_TO) { - const childColumn = await relation.getChildColumn(); - const parentColumn = await relation.getParentColumn(); - const childModel = await childColumn.getModel(); - await childModel.getColumns(); - const parentModel = await parentColumn.getModel(); - await parentModel.getColumns(); + const childColumn = await relation.getChildColumn(); + const parentColumn = await relation.getParentColumn(); + const childModel = await childColumn.getModel(); + await childModel.getColumns(); + const parentModel = await parentColumn.getModel(); + await parentModel.getColumns(); - selectQb.join( - `${baseModelSqlv2.getTnPath(parentModel.table_name)} as ${nestedAlias}`, - `${nestedAlias}.${parentColumn.column_name}`, - `${prevAlias}.${childColumn.column_name}`, - ); + selectQb.join( + `${baseModelSqlv2.getTnPath(parentModel.table_name)} as ${nestedAlias}`, + `${nestedAlias}.${parentColumn.column_name}`, + `${prevAlias}.${childColumn.column_name}`, + ); + } else if (relation.type === RelationTypes.HAS_MANY) { + }else if (relation.type === RelationTypes.MANY_TO_MANY) { + const mmTableAlias = getAlias() + const mmModel = await relation.getMMModel(); + const mmChildCol = await relation.getMMChildColumn(); + const mmParentCol = await relation.getMMParentColumn(); + + knex( + `${baseModelSqlv2.getTnPath( + parentModel?.table_name, + )} as ${refTableAlias}`, + ) + [columnOptions.rollup_function as string]?.( + knex.ref(`${refTableAlias}.${rollupColumn.column_name}`), + ) + .innerJoin( + baseModelSqlv2.getTnPath(mmModel.table_name), + knex.ref( + `${baseModelSqlv2.getTnPath(mmModel.table_name)}.${ + mmParentCol.column_name + }`, + ), + '=', + knex.ref(`${refTableAlias}.${parentCol.column_name}`), + ) + .where( + knex.ref( + `${baseModelSqlv2.getTnPath(mmModel.table_name)}.${ + mmChildCol.column_name + }`, + ), + '=', + knex.ref( + `${alias || baseModelSqlv2.getTnPath(childModel.table_name)}.${ + childCol.column_name + }`, + ), + ) + } - const mmModel = await relationColumnOption.getMMModel(); - const mmChildCol = await relationColumnOption.getMMChildColumn(); - const mmParentCol = await relationColumnOption.getMMParentColumn(); - knex( - `${baseModelSqlv2.getTnPath( - parentModel?.table_name, - )} as ${refTableAlias}`, - ) - [columnOptions.rollup_function as string]?.( - knex.ref(`${refTableAlias}.${rollupColumn.column_name}`), - ) - .innerJoin( - baseModelSqlv2.getTnPath(mmModel.table_name), - knex.ref( - `${baseModelSqlv2.getTnPath(mmModel.table_name)}.${ - mmParentCol.column_name - }`, - ), - '=', - knex.ref(`${refTableAlias}.${parentCol.column_name}`), - ) - .where( - knex.ref( - `${baseModelSqlv2.getTnPath(mmModel.table_name)}.${ - mmChildCol.column_name - }`, - ), - '=', - knex.ref( - `${alias || baseModelSqlv2.getTnPath(childModel.table_name)}.${ - childCol.column_name - }`, - ), - ) lookupColumn = await nestedLookup.getLookupColumn(); prevAlias = nestedAlias;