From 35b0398a836588647897fa03e24ef4f13b41a9b3 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 3 Nov 2021 12:36:40 +0530 Subject: [PATCH] feat: lookup and rollup parsing Signed-off-by: Pranav C --- .../lib/dataMapper/lib/sql/BaseModelSql.ts | 8 +- .../lib/dataMapper/lib/sql/genRollupSelect.ts | 24 ++++- .../lib/templateParser/NcTemplateParser.ts | 87 +++++++++---------- 3 files changed, 72 insertions(+), 47 deletions(-) diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts index 90772d23e6..9ff8e05e41 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts @@ -2407,7 +2407,13 @@ class BaseModelSql extends BaseModel { return (this.virtualColumns || [])?.reduce((arr, v) => { if (v.rl) { arr.push( - genRollupSelect({ knex: this.dbDriver, rollup: v.rl }).as(v._cn) + genRollupSelect({ + tn: this.tn, + knex: this.dbDriver, + rollup: v.rl, + hasMany: this.hasManyRelations, + manyToMany: this.manyToManyRelations + }).as(v._cn) ); } return arr; diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/genRollupSelect.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/genRollupSelect.ts index 302a66a685..e9bc17f659 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/genRollupSelect.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/genRollupSelect.ts @@ -1,8 +1,24 @@ import Knex from 'knex'; -export default function({ knex, rollup }: { knex: Knex; rollup: any }) { +export default function({ + knex, + rollup: _rollup, + hasMany, + manyToMany +}: { + tn: string; + knex: Knex; + rollup: any; + hasMany: any[]; + manyToMany: any[]; +}) { + let rollup = _rollup; + switch (rollup.type) { case 'hm': + if (!rollup.tn || !rollup.rtn) { + rollup = { ...rollup, ...hasMany.find(hm => hm.tn === rollup.rltn) }; + } return knex(rollup.rltn) [rollup.fn]?.(knex.ref(`${rollup.rltn}.${rollup.rlcn}`)) .where( @@ -12,6 +28,12 @@ export default function({ knex, rollup }: { knex: Knex; rollup: any }) { ); break; case 'mm': + if (!rollup.tn || !rollup.rtn || !rollup.vtn) { + rollup = { + ...rollup, + ...manyToMany.find(mm => mm.rtn === rollup.rltn) + }; + } return knex(rollup.rltn) [rollup.fn]?.(knex.ref(`${rollup.rltn}.${rollup.rlcn}`)) .innerJoin( diff --git a/packages/nocodb/src/lib/templateParser/NcTemplateParser.ts b/packages/nocodb/src/lib/templateParser/NcTemplateParser.ts index 41c563bf3f..f5677c20da 100644 --- a/packages/nocodb/src/lib/templateParser/NcTemplateParser.ts +++ b/packages/nocodb/src/lib/templateParser/NcTemplateParser.ts @@ -24,11 +24,11 @@ export default class NcTemplateParser { private prefix: string; private template: any; - constructor({client, template, prefix = ''}) { + constructor({ client, template, prefix = '' }) { this.client = client; - this.sqlUi = SqlUiFactory.create({client}); + this.sqlUi = SqlUiFactory.create({ client }); this.template = template; - this.prefix = prefix + this.prefix = prefix; } public parse(template?: any): any { @@ -39,11 +39,11 @@ export default class NcTemplateParser { ...tableTemplate, tn: this.getTable(tableTemplate.tn), _tn: tableTemplate._tn || tableTemplate.tn - } + }; const table = this.extractTable(t); tables.push(table); - return t - }) + return t; + }); this._tables = tables; @@ -73,7 +73,7 @@ export default class NcTemplateParser { columns: [ defaultColumns[0], ...this.extractTableColumns(tableTemplate.columns), - ...defaultColumns.slice(1), + ...defaultColumns.slice(1) ] }; } @@ -95,22 +95,24 @@ export default class NcTemplateParser { // // this.extractRelations(tableColumn, 'mm'); // break; default: - const colProp = this.sqlUi.getDataTypeForUiType(tableColumn); - columns.push({ - ...this.sqlUi.getNewColumn(''), - rqd: false, - pk: false, - ai: false, - cdf: null, - un: false, - dtx: 'specificType', - dtxp: this.sqlUi.getDefaultLengthForDatatype(colProp.dt), - dtxs: this.sqlUi.getDefaultScaleForDatatype(colProp.dt), - cn: tableColumn.cn, - _cn: tableColumn.cn, - uidt: tableColumn.uidt, - ...colProp - }); + { + const colProp = this.sqlUi.getDataTypeForUiType(tableColumn); + columns.push({ + ...this.sqlUi.getNewColumn(''), + rqd: false, + pk: false, + ai: false, + cdf: null, + un: false, + dtx: 'specificType', + dtxp: this.sqlUi.getDefaultLengthForDatatype(colProp.dt), + dtxs: this.sqlUi.getDefaultScaleForDatatype(colProp.dt), + cn: tableColumn.cn, + _cn: tableColumn.cn, + uidt: tableColumn.uidt, + ...colProp + }); + } break; } } @@ -121,7 +123,9 @@ export default class NcTemplateParser { if (!this._relations) this._relations = []; if (!this._m2mRelations) this._m2mRelations = []; for (const hasMany of tableTemplate.hasMany || []) { - const childTable = this.tables.find(table => table.tn === this.getTable(hasMany.tn)); + const childTable = this.tables.find( + table => table.tn === this.getTable(hasMany.tn) + ); const parentTable = this.tables.find( table => table.tn === tableTemplate.tn ); @@ -160,7 +164,9 @@ export default class NcTemplateParser { } for (const manyToMany of tableTemplate.manyToMany || []) { // @ts-ignore - const childTable = this.tables.find(table => table.tn === this.getTable(manyToMany.rtn)); + const childTable = this.tables.find( + table => table.tn === this.getTable(manyToMany.rtn) + ); const parentTable = this.tables.find( table => table.tn === tableTemplate.tn ); @@ -189,27 +195,18 @@ export default class NcTemplateParser { private extractVirtualColumns(tableMeta) { if (!this._virtualColumns) this._virtualColumns = {}; const virtualColumns = []; - for (const v of (tableMeta.v || [])) { - const v1 = {...v} - let type, prop; - - switch (v.uidt) { - case UITypes.Rollup: - type = v.rl.type - prop = 'rl' - break; - case UITypes.Lookup: - type = v.lk.type - prop = 'lk' - break; - } - - if (type && prop) { - // todo: extract relation data - } else { - virtualColumns.push(v1) + for (const v of tableMeta.v || []) { + const v1 = { ...v }; + + if (v.rl) { + v1.rl.rlttn = v1.rl.rltn; + v1.rl.rltn = this.getTable(v1.rl.rltn); + } else if (v.lk) { + v1.lk._ltn = v1.lk.ltn; + v1.lk.ltn = this.getTable(v1.lk.ltn); } + virtualColumns.push(v1); } this.virtualColumns[tableMeta.tn] = virtualColumns; } @@ -231,6 +228,6 @@ export default class NcTemplateParser { } private getTable(tn) { - return `${this.prefix}${tn}` + return `${this.prefix}${tn}`; } }