Browse Source

feat: group by - lookup support - mm/hm lookup - WIP

pull/6987/head
Pranav C 1 year ago
parent
commit
86238145da
  1. 3
      packages/nocodb/src/db/BaseModelSqlv2.ts
  2. 142
      packages/nocodb/src/db/generateMMLookupSelectQuery.ts

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

@ -35,7 +35,6 @@ import type {
SelectOption, SelectOption,
} from '~/models'; } from '~/models';
import type { SortType } from 'nocodb-sdk'; import type { SortType } from 'nocodb-sdk';
import generateBTLookupSelectQuery from '~/db/generateBTLookupSelectQuery';
import formulaQueryBuilderv2 from '~/db/formulav2/formulaQueryBuilderv2'; import formulaQueryBuilderv2 from '~/db/formulav2/formulaQueryBuilderv2';
import genRollupSelectv2 from '~/db/genRollupSelectv2'; import genRollupSelectv2 from '~/db/genRollupSelectv2';
import conditionV2 from '~/db/conditionV2'; import conditionV2 from '~/db/conditionV2';
@ -770,7 +769,7 @@ class BaseModelSqlv2 {
} }
case UITypes.Lookup: case UITypes.Lookup:
{ {
const _selectQb = await generateBTLookupSelectQuery({ const _selectQb = await generateMMLookupSelectQuery({
baseModelSqlv2: this, baseModelSqlv2: this,
column, column,
alias: null, alias: null,

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

@ -10,7 +10,6 @@ import type {
} from '~/models'; } from '~/models';
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 { getAliasGenerator } from '~/utils'; import { getAliasGenerator } from '~/utils';
export default async function generateMMLookupSelectQuery({ export default async function generateMMLookupSelectQuery({
@ -24,7 +23,7 @@ export default async function generateMMLookupSelectQuery({
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;
@ -41,26 +40,107 @@ export default async function generateMMLookupSelectQuery({
await relationCol.getColOptions<LinkToAnotherRecordColumn>(); await relationCol.getColOptions<LinkToAnotherRecordColumn>();
// if not belongs to then throw error as we don't support // if not belongs to then throw error as we don't support
if (relation.type !== RelationTypes.BELONGS_TO) { if (relation.type === RelationTypes.BELONGS_TO) {
// NcError.badRequest('HasMany/ManyToMany lookup is not supported'); 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 = knex(
`${baseModelSqlv2.getTnPath(parentModel.table_name)} as ${alias}`,
).where(
`${alias}.${parentColumn.column_name}`,
knex.raw(`??`, [
`${rootAlias || baseModelSqlv2.getTnPath(childModel.table_name)}.${
childColumn.column_name
}`,
]),
);
}
// if not belongs to then throw error as we don't support
else if (relation.type === RelationTypes.HAS_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();
selectQb = knex(
`${baseModelSqlv2.getTnPath(childModel.table_name)} as ${alias}`,
).where(
`${alias}.${parentColumn.column_name}`,
knex.raw(`??`, [
`${rootAlias || baseModelSqlv2.getTnPath(parentModel.table_name)}.${
childColumn.column_name
}`,
]),
);
}
// if not belongs to then throw error as we don't support
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();
selectQb = knex(
`${baseModelSqlv2.getTnPath(parentModel.table_name)} as ${alias}`,
).where(
`${alias}.${parentColumn.column_name}`,
knex.raw(`??`, [
`${rootAlias || baseModelSqlv2.getTnPath(childModel.table_name)}.${
childColumn.column_name
}`,
]),
);
/*
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}`,
// )
selectQb
.innerJoin(
baseModelSqlv2.getTnPath(mmModel.table_name),
knex.ref(
`${baseModelSqlv2.getTnPath(mmModel.table_name)}.${
mmParentCol.column_name
}`,
),
'=',
knex.ref(`${nestedAlias}.${parentColumn.column_name}`),
)
.where(
knex.ref(
`${baseModelSqlv2.getTnPath(mmModel.table_name)}.${
mmChildCol.column_name
}`,
),
'=',
knex.ref(
`${alias || baseModelSqlv2.getTnPath(childModel.table_name)}.${
childColumn.column_name
}`,
),
);
* */
} }
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 = knex(
`${baseModelSqlv2.getTnPath(parentModel.table_name)} as ${alias}`,
).where(
`${alias}.${parentColumn.column_name}`,
knex.raw(`??`, [
`${rootAlias || baseModelSqlv2.getTnPath(childModel.table_name)}.${
childColumn.column_name
}`,
]),
);
} }
let lookupColumn = await lookup.getLookupColumn(); let lookupColumn = await lookup.getLookupColumn();
let prevAlias = alias; let prevAlias = alias;
@ -117,11 +197,12 @@ export default async function generateMMLookupSelectQuery({
const mmChildCol = await relation.getMMChildColumn(); const mmChildCol = await relation.getMMChildColumn();
const mmParentCol = await relation.getMMParentColumn(); const mmParentCol = await relation.getMMParentColumn();
knex( // knex(
`${baseModelSqlv2.getTnPath( // `${baseModelSqlv2.getTnPath(
parentModel?.table_name, // parentModel?.table_name,
)} as ${nestedAlias}`, // )} as ${nestedAlias}`,
) // )
selectQb
.innerJoin( .innerJoin(
baseModelSqlv2.getTnPath(mmModel.table_name), baseModelSqlv2.getTnPath(mmModel.table_name),
knex.ref( knex.ref(
@ -213,12 +294,17 @@ export default async function generateMMLookupSelectQuery({
break; break;
default: default:
{ {
selectQb.select(`${prevAlias}.${lookupColumn.column_name}`); selectQb.select(`${prevAlias}.${lookupColumn.column_name} as ${lookupColumn.title}`);
} }
break; break;
} }
return { builder: selectQb }; selectQb.orderBy(`${lookupColumn.title}`, 'asc');
// mysql : https://www.db-fiddle.com/f/qC4hrbSrSp7v3exb4moVCE/1
const subQueryAlias = getAlias();
// return { builder: knex.select(knex.raw('array_agg(??)', [lookupColumn.title])).from(selectQb) };
return { builder: knex.select(knex.raw("cast(JSON_ARRAYAGG(??) as NCHAR)", [lookupColumn.title])).from(selectQb.as(subQueryAlias)) };
} }
} }

Loading…
Cancel
Save