From 3736bf2d1cb0aa3aa747573a8987d0b30f0bf5b4 Mon Sep 17 00:00:00 2001 From: mertmit Date: Fri, 26 Jan 2024 21:38:13 +0000 Subject: [PATCH 1/4] refactor: replace getNestedUidt with getNestedColumn --- packages/nocodb/src/db/BaseModelSqlv2.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/nocodb/src/db/BaseModelSqlv2.ts b/packages/nocodb/src/db/BaseModelSqlv2.ts index 509ce1d58e..1774fa2e29 100644 --- a/packages/nocodb/src/db/BaseModelSqlv2.ts +++ b/packages/nocodb/src/db/BaseModelSqlv2.ts @@ -4720,7 +4720,7 @@ class BaseModelSqlv2 { if (col.uidt === UITypes.Lookup) { if ( [UITypes.User, UITypes.CreatedBy, UITypes.LastModifiedBy].includes( - (await this.getNestedUidt(col)) as UITypes, + (await this.getNestedColumn(col))?.uidt as UITypes, ) ) { userColumns.push(col); @@ -4870,12 +4870,12 @@ class BaseModelSqlv2 { return d; } - public async getNestedUidt(column: Column) { + public async getNestedColumn(column: Column) { if (column.uidt !== UITypes.Lookup) { - return column.uidt; + return column; } const colOptions = await column.getColOptions(); - return this.getNestedUidt(await colOptions?.getLookupColumn()); + return this.getNestedColumn(await colOptions?.getLookupColumn()); } public async convertAttachmentType( @@ -4897,7 +4897,7 @@ class BaseModelSqlv2 { for (const col of columns) { if (col.uidt === UITypes.Lookup) { - if ((await this.getNestedUidt(col)) === UITypes.Attachment) { + if ((await this.getNestedColumn(col))?.uidt === UITypes.Attachment) { attachmentColumns.push(col); } } else { From a9173fd60df33f09dcadf33536ac730eda10768a Mon Sep 17 00:00:00 2001 From: mertmit Date: Fri, 26 Jan 2024 21:38:13 +0000 Subject: [PATCH 2/4] fix: fetch columns if required within exec --- packages/nocodb/src/db/BaseModelSqlv2.ts | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/nocodb/src/db/BaseModelSqlv2.ts b/packages/nocodb/src/db/BaseModelSqlv2.ts index 1774fa2e29..614639d8eb 100644 --- a/packages/nocodb/src/db/BaseModelSqlv2.ts +++ b/packages/nocodb/src/db/BaseModelSqlv2.ts @@ -4591,6 +4591,14 @@ class BaseModelSqlv2 { ) : await this.dbDriver.raw(query); + if (!this.model?.columns) { + await this.model.getColumns(); + } + + if (childTable && !childTable?.columns) { + await childTable.getColumns(); + } + // update attachment fields if (!options.skipAttachmentConversion) { data = await this.convertAttachmentType(data, childTable); @@ -4706,12 +4714,6 @@ class BaseModelSqlv2 { // user is stored as id within the database // convertUserFormat is used to convert the response in id to user object in API response if (data) { - if (childTable && !childTable?.columns) { - await childTable.getColumns(); - } else if (!this.model?.columns) { - await this.model.getColumns(); - } - let userColumns = []; const columns = childTable ? childTable.columns : this.model.columns; @@ -4885,12 +4887,6 @@ class BaseModelSqlv2 { // attachment is stored in text and parse in UI // convertAttachmentType is used to convert the response in string to array of object in API response if (data) { - if (childTable && !childTable?.columns) { - await childTable.getColumns(); - } else if (!this.model?.columns) { - await this.model.getColumns(); - } - const attachmentColumns = []; const columns = childTable ? childTable.columns : this.model.columns; From fd01b0a86a0a6a4f3fed089b7101e4303f8cda97 Mon Sep 17 00:00:00 2001 From: mertmit Date: Fri, 26 Jan 2024 21:38:14 +0000 Subject: [PATCH 3/4] fix: replace childTable with dependencyColumns --- packages/nocodb/src/db/BaseModelSqlv2.ts | 74 ++++++++++++++---------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/packages/nocodb/src/db/BaseModelSqlv2.ts b/packages/nocodb/src/db/BaseModelSqlv2.ts index 614639d8eb..fcd8b0c6f6 100644 --- a/packages/nocodb/src/db/BaseModelSqlv2.ts +++ b/packages/nocodb/src/db/BaseModelSqlv2.ts @@ -1033,7 +1033,10 @@ class BaseModelSqlv2 { // console.log(childQb.toQuery()) - const children = await this.execAndParse(childQb, childTable); + const children = await this.execAndParse( + childQb, + await childTable.getColumns(), + ); const proto = await ( await Model.getBaseModelSQL({ id: childTable.id, @@ -1165,7 +1168,10 @@ class BaseModelSqlv2 { await childModel.selectObject({ qb, fieldsSet: args.fieldSet }); - const children = await this.execAndParse(qb, childTable); + const children = await this.execAndParse( + qb, + await childTable.getColumns(), + ); const proto = await ( await Model.getBaseModelSQL({ @@ -1292,7 +1298,10 @@ class BaseModelSqlv2 { !this.isSqlite, ); - const children = await this.execAndParse(finalQb, childTable); + const children = await this.execAndParse( + finalQb, + await childTable.getColumns(), + ); const proto = await ( await Model.getBaseModelSQL({ @@ -1361,7 +1370,7 @@ class BaseModelSqlv2 { qb.limit(+rest?.limit || 25); qb.offset(+rest?.offset || 0); - const children = await this.execAndParse(qb, childTable); + const children = await this.execAndParse(qb, await childTable.getColumns()); const proto = await ( await Model.getBaseModelSQL({ id: rtnId, dbDriver: this.dbDriver }) ).getProto(); @@ -1595,7 +1604,7 @@ class BaseModelSqlv2 { applyPaginate(qb, rest); const proto = await childModel.getProto(); - const data = await this.execAndParse(qb, childTable); + const data = await this.execAndParse(qb, await childTable.getColumns()); return data.map((c) => { c.__proto__ = proto; return c; @@ -1710,7 +1719,7 @@ class BaseModelSqlv2 { applyPaginate(qb, rest); const proto = await childModel.getProto(); - const data = await this.execAndParse(qb, childTable); + const data = await this.execAndParse(qb, await childTable.getColumns()); return data.map((c) => { c.__proto__ = proto; @@ -1829,7 +1838,7 @@ class BaseModelSqlv2 { applyPaginate(qb, rest); const proto = await parentModel.getProto(); - const data = await this.execAndParse(qb, parentTable); + const data = await this.execAndParse(qb, await parentTable.getColumns()); return data.map((c) => { c.__proto__ = proto; @@ -4547,7 +4556,7 @@ class BaseModelSqlv2 { public async execAndParse( qb: Knex.QueryBuilder | string, - childTable?: Model, + dependencyColumns?: Column[], options: { skipDateConversion?: boolean; skipAttachmentConversion?: boolean; @@ -4595,27 +4604,26 @@ class BaseModelSqlv2 { await this.model.getColumns(); } - if (childTable && !childTable?.columns) { - await childTable.getColumns(); - } - // update attachment fields if (!options.skipAttachmentConversion) { - data = await this.convertAttachmentType(data, childTable); + data = await this.convertAttachmentType(data, dependencyColumns); } // update date time fields if (!options.skipDateConversion) { - data = this.convertDateFormat(data, childTable); + data = this.convertDateFormat(data, dependencyColumns); } // update user fields if (!options.skipUserConversion) { - data = await this.convertUserFormat(data, childTable); + data = await this.convertUserFormat(data, dependencyColumns); } if (!options.skipSubstitutingColumnIds) { - data = await this.substituteColumnIdsWithColumnTitles(data, childTable); + data = await this.substituteColumnIdsWithColumnTitles( + data, + dependencyColumns, + ); } if (options.first) { @@ -4627,9 +4635,9 @@ class BaseModelSqlv2 { protected async substituteColumnIdsWithColumnTitles( data: Record[], - childTable?: Model, + dependencyColumns?: Column[], ) { - const modelColumns = this.model?.columns.concat(childTable?.columns ?? []); + const modelColumns = this.model?.columns.concat(dependencyColumns ?? []); if (!modelColumns || !data.length) { return data; @@ -4709,14 +4717,14 @@ class BaseModelSqlv2 { protected async convertUserFormat( data: Record, - childTable?: Model, + dependencyColumns?: Column[], ) { // user is stored as id within the database // convertUserFormat is used to convert the response in id to user object in API response if (data) { let userColumns = []; - const columns = childTable ? childTable.columns : this.model.columns; + const columns = this.model?.columns.concat(dependencyColumns ?? []); for (const col of columns) { if (col.uidt === UITypes.Lookup) { @@ -4753,7 +4761,7 @@ class BaseModelSqlv2 { // process user columns that are present in data if (userColumns.length) { const baseUsers = await BaseUser.getUsersList({ - base_id: childTable ? childTable.base_id : this.model.base_id, + base_id: this.model.base_id, }); if (Array.isArray(data)) { @@ -4882,14 +4890,14 @@ class BaseModelSqlv2 { public async convertAttachmentType( data: Record, - childTable?: Model, + dependencyColumns?: Column[], ) { // attachment is stored in text and parse in UI // convertAttachmentType is used to convert the response in string to array of object in API response if (data) { const attachmentColumns = []; - const columns = childTable ? childTable.columns : this.model.columns; + const columns = this.model?.columns.concat(dependencyColumns ?? []); for (const col of columns) { if (col.uidt === UITypes.Lookup) { @@ -5047,13 +5055,15 @@ class BaseModelSqlv2 { return d; } - public convertDateFormat(data: Record, childTable?: Model) { + public convertDateFormat( + data: Record, + dependencyColumns?: Column[], + ) { // Show the date time in UTC format in API response // e.g. 2022-01-01 04:30:00+00:00 if (data) { - const dateTimeColumns = ( - childTable ? childTable.columns : this.model.columns - ).filter( + const columns = this.model?.columns.concat(dependencyColumns ?? []); + const dateTimeColumns = columns.filter( (c) => c.uidt === UITypes.DateTime || c.uidt === UITypes.Date || @@ -5697,9 +5707,13 @@ class BaseModelSqlv2 { await parentModel.selectObject({ qb, fieldsSet: args.fieldSet }); - const parent = await this.execAndParse(qb, parentTable, { - first: true, - }); + const parent = await this.execAndParse( + qb, + await parentTable.getColumns(), + { + first: true, + }, + ); const proto = await parentModel.getProto(); From 2e79a236d630c7a349f181009f61ac1d3ce686e8 Mon Sep 17 00:00:00 2001 From: mertmit Date: Fri, 26 Jan 2024 21:38:14 +0000 Subject: [PATCH 4/4] fix: single query bt lookup --- packages/nocodb/src/db/BaseModelSqlv2.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/nocodb/src/db/BaseModelSqlv2.ts b/packages/nocodb/src/db/BaseModelSqlv2.ts index fcd8b0c6f6..fdf921ee2f 100644 --- a/packages/nocodb/src/db/BaseModelSqlv2.ts +++ b/packages/nocodb/src/db/BaseModelSqlv2.ts @@ -4636,6 +4636,7 @@ class BaseModelSqlv2 { protected async substituteColumnIdsWithColumnTitles( data: Record[], dependencyColumns?: Column[], + aliasColumns?: Record, ) { const modelColumns = this.model?.columns.concat(dependencyColumns ?? []); @@ -4648,6 +4649,12 @@ class BaseModelSqlv2 { const btMap: Record = {}; modelColumns.forEach((col) => { + if (aliasColumns && col.id in aliasColumns) { + aliasColumns[col.id].id = col.id; + aliasColumns[col.id].title = col.title; + col = aliasColumns[col.id]; + } + idToAliasMap[col.id] = col.title; if (col.colOptions?.type === 'bt') { btMap[col.id] = true;