From fc7e69d1e16340be19a7a64e63997c214ff67fb7 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 29 Mar 2023 12:39:32 +0530 Subject: [PATCH] refactor: validate formula only if error occurred (WIP) Signed-off-by: Pranav C --- .../sql-data-mapper/lib/sql/BaseModelSqlv2.ts | 34 ++++++++++++++----- .../sql/formulav2/formulaQueryBuilderv2.ts | 3 ++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts index 89f9805255..4563567aea 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts @@ -58,6 +58,7 @@ const nanoidv2 = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 14); const { v4: uuidv4 } = require('uuid'); const INNER_QUERY_ALIAS = '__nc_inner'; + // const WRAPPER_QUERY_ALIAS = '__nc_wrapper'; async function populatePk(model: Model, insertObj: any) { @@ -202,7 +203,7 @@ class BaseModelSqlv2 { fieldsSet?: Set; } = {}, ignoreViewFilterAndSort = false, - + validateFormula = false ): Promise { const { where, fields, ...rest } = this._getListArgs(args as any); @@ -215,6 +216,7 @@ class BaseModelSqlv2 { fieldsSet: args.fieldsSet, viewId: this.viewId, alias: INNER_QUERY_ALIAS, + validateFormula }); if (+rest?.shuffle) { await this.shuffle({ qb: innerQb }); @@ -287,10 +289,16 @@ class BaseModelSqlv2 { if (!ignoreViewFilterAndSort) applyPaginate(innerQb, rest); const proto = await this.getProto(); - console.log(wrapperQb.toQuery()) - - const data = await this.execAndParse(wrapperQb); + let data; + try { + data = await this.execAndParse(wrapperQb); + } catch (e) { + if (!validateFormula) { + return this.list(args, ignoreViewFilterAndSort, true); + } + throw e; + } return data?.map((d) => { d.__proto__ = proto; return d; @@ -1262,7 +1270,8 @@ class BaseModelSqlv2 { private async getSelectQueryBuilderForFormula( column: Column, - tableAlias?: string + tableAlias?: string, + validateFormula = false ) { const formula = await column.getColOptions(); if (formula.error) throw new Error(`Formula error: ${formula.error}`); @@ -1273,7 +1282,8 @@ class BaseModelSqlv2 { this.model, column, {}, - tableAlias + tableAlias, + validateFormula ); return qb; } @@ -1492,6 +1502,7 @@ class BaseModelSqlv2 { viewId, fieldsSet, alias, + validateFormula }: { fieldsSet?: Set; qb: Knex.QueryBuilder; @@ -1500,6 +1511,7 @@ class BaseModelSqlv2 { extractPkAndPv?: boolean; viewId?: string; alias?: string; + validateFormula?:boolean }): Promise { const view = await View.get(viewId); const viewColumns = viewId && (await View.getColumns(viewId)); @@ -1553,7 +1565,8 @@ class BaseModelSqlv2 { try { const selectQb = await this.getSelectQueryBuilderForFormula( qrValueColumn, - alias + alias, + validateFormula ); qb.select({ [column.column_name]: selectQb.builder, @@ -1585,7 +1598,9 @@ class BaseModelSqlv2 { case UITypes.Formula: try { const selectQb = await this.getSelectQueryBuilderForFormula( - barcodeValueColumn + barcodeValueColumn, + alias, + validateFormula ); qb.select({ [column.column_name]: selectQb.builder, @@ -1609,7 +1624,8 @@ class BaseModelSqlv2 { try { const selectQb = await this.getSelectQueryBuilderForFormula( column, - alias + alias, + validateFormula ); qb.select( this.dbDriver.raw(`?? as ??`, [ diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts index edf1da8221..0b59219c43 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts @@ -822,6 +822,7 @@ export default async function formulaQueryBuilderv2( column?: Column, aliasToColumn = {}, tableAlias?: string, + validateFormula = false ) { // register jsep curly hook once only jsep.plugins.register(jsepCurlyHook); @@ -835,6 +836,8 @@ export default async function formulaQueryBuilderv2( tableAlias ); + if(!validateFormula) return qb; + try { // dry run qb.builder to see if it will break the grid view or not // if so, set formula error and show empty selectQb instead