Browse Source

feat: lookup support - mm/hm lookup - WIP

pull/6987/head
Pranav C 11 months ago
parent
commit
646aa1db5e
  1. 1
      docker-compose/mysql/docker-compose.yml
  2. 7
      packages/nocodb/src/db/BaseModelSqlv2.ts
  3. 140
      packages/nocodb/src/db/generateMMLookupSelectQuery.ts

1
docker-compose/mysql/docker-compose.yml

@ -37,3 +37,4 @@ services:
volumes: volumes:
db_data: {} db_data: {}
nc_data: {} nc_data: {}

7
packages/nocodb/src/db/BaseModelSqlv2.ts

@ -64,6 +64,7 @@ import {
} from '~/utils/globals'; } from '~/utils/globals';
import { extractProps } from '~/helpers/extractProps'; import { extractProps } from '~/helpers/extractProps';
import { defaultLimitConfig } from '~/helpers/extractLimitAndOffset'; import { defaultLimitConfig } from '~/helpers/extractLimitAndOffset';
import generateMMLookupSelectQuery from "~/db/generateMMLookupSelectQuery";
dayjs.extend(utc); dayjs.extend(utc);
@ -600,7 +601,7 @@ class BaseModelSqlv2 {
break; break;
case UITypes.Lookup: case UITypes.Lookup:
{ {
const _selectQb = await generateBTLookupSelectQuery({ const _selectQb = await generateMMLookupSelectQuery({
baseModelSqlv2: this, baseModelSqlv2: this,
column, column,
alias: null, alias: null,
@ -695,6 +696,10 @@ class BaseModelSqlv2 {
qb.groupBy(...groupBySelectors); qb.groupBy(...groupBySelectors);
applyPaginate(qb, rest); applyPaginate(qb, rest);
console.log('========')
console.log(qb.toQuery())
console.log('========')
return await this.execAndParse(qb); return await this.execAndParse(qb);
} }

140
packages/nocodb/src/db/generateMMLookupSelectQuery.ts

@ -11,23 +11,21 @@ import type {
import formulaQueryBuilderv2 from '~/db/formulav2/formulaQueryBuilderv2'; import formulaQueryBuilderv2 from '~/db/formulav2/formulaQueryBuilderv2';
import genRollupSelectv2 from '~/db/genRollupSelectv2'; import genRollupSelectv2 from '~/db/genRollupSelectv2';
import { NcError } from '~/helpers/catchError'; import { NcError } from '~/helpers/catchError';
import {getAliasGenerator} from "~/utils"; import { getAliasGenerator } from '~/utils';
export default async function generateBTLookupSelectQuery({ export default async function generateMMLookupSelectQuery({
column, column,
baseModelSqlv2, baseModelSqlv2,
alias, alias,
model, model,
getAlias = getAliasGenerator('__lk_slt_') getAlias = getAliasGenerator('__lk_slt_'),
}: { }: {
column: Column; column: Column;
baseModelSqlv2: BaseModelSqlv2; baseModelSqlv2: BaseModelSqlv2;
alias: string; alias: string;
model: Model; model: Model;
getAlias: ReturnType<typeof getAliasGenerator> getAlias: ReturnType<typeof getAliasGenerator>;
}): Promise<any> { }): Promise<any> {
const knex = baseModelSqlv2.dbDriver; const knex = baseModelSqlv2.dbDriver;
const rootAlias = alias; const rootAlias = alias;
@ -53,9 +51,9 @@ export default async function generateBTLookupSelectQuery({
const parentModel = await parentColumn.getModel(); const parentModel = await parentColumn.getModel();
await parentModel.getColumns(); await parentModel.getColumns();
`${baseModelSqlv2.getTnPath(parentModel.table_name)} as ${alias}`,
).where(
selectQb = knex( selectQb = knex(
`${baseModelSqlv2.getTnPath(parentModel.table_name)} as ${alias}`,
).where(
`${alias}.${parentColumn.column_name}`, `${alias}.${parentColumn.column_name}`,
knex.raw(`??`, [ knex.raw(`??`, [
`${rootAlias || baseModelSqlv2.getTnPath(childModel.table_name)}.${ `${rootAlias || baseModelSqlv2.getTnPath(childModel.table_name)}.${
@ -76,65 +74,79 @@ export default async function generateBTLookupSelectQuery({
// if any of the relation in nested lookup is // if any of the relation in nested lookup is
// not belongs to then throw error as we don't support // not belongs to then throw error as we don't support
if (relation.type === RelationTypes.BELONGS_TO) { if (relation.type === RelationTypes.BELONGS_TO) {
const childColumn = await relation.getChildColumn();
const childColumn = await relation.getChildColumn(); const parentColumn = await relation.getParentColumn();
const parentColumn = await relation.getParentColumn(); const childModel = await childColumn.getModel();
const childModel = await childColumn.getModel(); await childModel.getColumns();
await childModel.getColumns(); const parentModel = await parentColumn.getModel();
const parentModel = await parentColumn.getModel(); await parentModel.getColumns();
await parentModel.getColumns();
selectQb.join(
selectQb.join( `${baseModelSqlv2.getTnPath(
`${baseModelSqlv2.getTnPath(parentModel.table_name)} as ${nestedAlias}`, parentModel.table_name,
`${nestedAlias}.${parentColumn.column_name}`, )} as ${nestedAlias}`,
`${prevAlias}.${childColumn.column_name}`, `${nestedAlias}.${parentColumn.column_name}`,
); `${prevAlias}.${childColumn.column_name}`,
);
} else if (relation.type === RelationTypes.HAS_MANY) { } else if (relation.type === RelationTypes.HAS_MANY) {
const childColumn = await relation.getChildColumn();
}else if (relation.type === RelationTypes.MANY_TO_MANY) { const parentColumn = await relation.getParentColumn();
const mmTableAlias = getAlias() const childModel = await childColumn.getModel();
await childModel.getColumns();
const mmModel = await relation.getMMModel(); const parentModel = await parentColumn.getModel();
const mmChildCol = await relation.getMMChildColumn(); await parentModel.getColumns();
const mmParentCol = await relation.getMMParentColumn();
selectQb.join(
knex( `${baseModelSqlv2.getTnPath(
`${baseModelSqlv2.getTnPath( childModel.table_name,
parentModel?.table_name, )} as ${nestedAlias}`,
)} as ${refTableAlias}`, `${nestedAlias}.${parentColumn.column_name}`,
`${prevAlias}.${childColumn.column_name}`,
);
} else if (relation.type === RelationTypes.MANY_TO_MANY) {
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 mmTableAlias = getAlias();
const mmModel = await relation.getMMModel();
const mmChildCol = await relation.getMMChildColumn();
const mmParentCol = await relation.getMMParentColumn();
knex(
`${baseModelSqlv2.getTnPath(
parentModel?.table_name,
)} as ${nestedAlias}`,
)
.innerJoin(
baseModelSqlv2.getTnPath(mmModel.table_name),
knex.ref(
`${baseModelSqlv2.getTnPath(mmModel.table_name)}.${
mmParentCol.column_name
}`,
),
'=',
knex.ref(`${nestedAlias}.${parentColumn.column_name}`),
) )
[columnOptions.rollup_function as string]?.( .where(
knex.ref(`${refTableAlias}.${rollupColumn.column_name}`), knex.ref(
) `${baseModelSqlv2.getTnPath(mmModel.table_name)}.${
.innerJoin( mmChildCol.column_name
baseModelSqlv2.getTnPath(mmModel.table_name), }`,
knex.ref( ),
`${baseModelSqlv2.getTnPath(mmModel.table_name)}.${ '=',
mmParentCol.column_name knex.ref(
}`, `${alias || baseModelSqlv2.getTnPath(childModel.table_name)}.${
), childColumn.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(); lookupColumn = await nestedLookup.getLookupColumn();
prevAlias = nestedAlias; prevAlias = nestedAlias;
} }

Loading…
Cancel
Save