From 9d5bce4a6afe96349fbc4af25d754a0f968ea77e Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 17 May 2022 13:03:30 +0800 Subject: [PATCH] refactor: move formula helpers to sdk --- packages/nocodb-sdk/src/lib/formulaHelpers.ts | 88 +++++++++++++------ .../sql/formulav2/formulaQueryBuilderv2.ts | 10 ++- .../src/lib/noco/meta/api/columnApis.ts | 9 +- .../lib/noco/meta/helpers/formulaHelpers.ts | 60 ------------- .../jobs/ncProjectUpgraderV2_0090000.ts | 8 +- 5 files changed, 81 insertions(+), 94 deletions(-) delete mode 100644 packages/nocodb/src/lib/noco/meta/helpers/formulaHelpers.ts diff --git a/packages/nocodb-sdk/src/lib/formulaHelpers.ts b/packages/nocodb-sdk/src/lib/formulaHelpers.ts index e534325fa3..97407da52f 100644 --- a/packages/nocodb-sdk/src/lib/formulaHelpers.ts +++ b/packages/nocodb-sdk/src/lib/formulaHelpers.ts @@ -2,6 +2,65 @@ import jsep from 'jsep'; import { ColumnType } from './Api'; +export const jsepCurlyHook = { + name: 'curly', + init(jsep) { + jsep.hooks.add('gobble-token', function gobbleCurlyLiteral(env) { + const OCURLY_CODE = 123; // { + const CCURLY_CODE = 125; // } + const { context } = env; + if ( + !jsep.isIdentifierStart(context.code) && + context.code === OCURLY_CODE + ) { + context.index += 1; + const nodes = context.gobbleExpressions(CCURLY_CODE); + if (context.code === CCURLY_CODE) { + context.index += 1; + if (nodes.length > 0) { + env.node = nodes[0]; + } + return env.node; + } else { + context.throwError('Unclosed }'); + } + } + }); + }, +} as jsep.IPlugin; + +export async function substituteColumnAliasWithIdInFormula( + formula, + columns: ColumnType[] +) { + const substituteId = async (pt: any) => { + if (pt.type === 'CallExpression') { + for (const arg of pt.arguments || []) { + await substituteId(arg); + } + } else if (pt.type === 'Literal') { + return; + } else if (pt.type === 'Identifier') { + const colNameOrId = pt.name; + const column = columns.find( + (c) => + c.id === colNameOrId || + c.column_name === colNameOrId || + c.title === colNameOrId + ); + pt.name = '{' + column.id + '}'; + } else if (pt.type === 'BinaryExpression') { + await substituteId(pt.left); + await substituteId(pt.right); + } + }; + // register jsep curly hook + jsep.plugins.register(jsepCurlyHook); + const parsedFormula = jsep(formula); + await substituteId(parsedFormula); + return jsepTreeToFormula(parsedFormula); +} + export function substituteColumnIdWithAliasInFormula( formula, columns: ColumnType[], @@ -30,33 +89,8 @@ export function substituteColumnIdWithAliasInFormula( } }; - // register curly hook - jsep.plugins.register({ - name: 'curly', - init(jsep) { - jsep.hooks.add('gobble-token', function gobbleCurlyLiteral(env) { - const OCURLY_CODE = 123; // { - const CCURLY_CODE = 125; // } - const { context } = env; - if ( - !jsep.isIdentifierStart(context.code) && - context.code === OCURLY_CODE - ) { - context.index += 1; - const nodes = context.gobbleExpressions(CCURLY_CODE); - if (context.code === CCURLY_CODE) { - context.index += 1; - if (nodes.length > 0) { - env.node = nodes[0]; - } - return env.node; - } else { - context.throwError('Unclosed }'); - } - } - }); - }, - } as jsep.IPlugin); + // register jsep curly hook + jsep.plugins.register(jsepCurlyHook); const parsedFormula = jsep(formula); const parsedRawFormula = rawFormula && jsep(rawFormula); substituteId(parsedFormula, parsedRawFormula); diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/formulav2/formulaQueryBuilderv2.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/formulav2/formulaQueryBuilderv2.ts index 7bc9327ab5..3a10ea4bd6 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/formulav2/formulaQueryBuilderv2.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/formulav2/formulaQueryBuilderv2.ts @@ -7,7 +7,7 @@ import FormulaColumn from '../../../../noco-models/FormulaColumn'; import { XKnex } from '../../..'; import LinkToAnotherRecordColumn from '../../../../noco-models/LinkToAnotherRecordColumn'; import LookupColumn from '../../../../noco-models/LookupColumn'; -import { UITypes } from 'nocodb-sdk'; +import { jsepCurlyHook, UITypes } from 'nocodb-sdk'; // todo: switch function based on database @@ -51,6 +51,8 @@ export default async function formulaQueryBuilderv2( model: Model, aliasToColumn = {} ) { + // register jsep curly hook + jsep.plugins.register(jsepCurlyHook); const tree = jsep(_tree); // todo: improve - implement a common solution for filter, sort, formula, etc @@ -647,7 +649,11 @@ export default async function formulaQueryBuilderv2( return query; } else if (pt.type === 'UnaryExpression') { const query = knex.raw( - `${pt.operator}${fn(pt.argument, null, pt.operator).toQuery()}${colAlias}` + `${pt.operator}${fn( + pt.argument, + null, + pt.operator + ).toQuery()}${colAlias}` ); if (prevBinaryOp && pt.operator !== prevBinaryOp) { query.wrap('(', ')'); diff --git a/packages/nocodb/src/lib/noco/meta/api/columnApis.ts b/packages/nocodb/src/lib/noco/meta/api/columnApis.ts index 96c68b5885..d7c3a99123 100644 --- a/packages/nocodb/src/lib/noco/meta/api/columnApis.ts +++ b/packages/nocodb/src/lib/noco/meta/api/columnApis.ts @@ -3,7 +3,6 @@ import Model from '../../../noco-models/Model'; import ProjectMgrv2 from '../../../sqlMgr/v2/ProjectMgrv2'; import Base from '../../../noco-models/Base'; import Column from '../../../noco-models/Column'; -import { substituteColumnAliasWithIdInFormula } from '../helpers/formulaHelpers'; import validateParams from '../helpers/validateParams'; import { Tele } from 'nc-help'; @@ -19,6 +18,7 @@ import { isVirtualCol, LinkToAnotherRecordType, RelationTypes, + substituteColumnAliasWithIdInFormula, substituteColumnIdWithAliasInFormula, TableType, UITypes @@ -496,9 +496,12 @@ export async function columnAdd(req: Request, res: Response) { }> = (await sqlClient.columnList({ tn: table.table_name }))?.data?.list; const insertedColumnMeta = - columns.find(c => c.cn === colBody.column_name) || {} as any; + columns.find(c => c.cn === colBody.column_name) || ({} as any); - if (colBody.uidt === UITypes.SingleSelect || colBody.uidt === UITypes.MultiSelect) { + if ( + colBody.uidt === UITypes.SingleSelect || + colBody.uidt === UITypes.MultiSelect + ) { insertedColumnMeta.dtxp = colBody.dtxp; } diff --git a/packages/nocodb/src/lib/noco/meta/helpers/formulaHelpers.ts b/packages/nocodb/src/lib/noco/meta/helpers/formulaHelpers.ts deleted file mode 100644 index 8f114447b6..0000000000 --- a/packages/nocodb/src/lib/noco/meta/helpers/formulaHelpers.ts +++ /dev/null @@ -1,60 +0,0 @@ -import jsep from 'jsep'; -import jsepTreeToFormula from '../../common/helpers/jsepTreeToFormula'; -import Column from '../../../noco-models/Column'; - -export async function substituteColumnAliasWithIdInFormula( - formula, - columns: Column[] -) { - const substituteId = async (pt: any) => { - if (pt.type === 'CallExpression') { - for (const arg of pt.arguments || []) { - await substituteId(arg); - } - } else if (pt.type === 'Literal') { - return; - } else if (pt.type === 'Identifier') { - const colNameOrId = pt.name; - const column = columns.find( - c => - c.id === colNameOrId || - c.column_name === colNameOrId || - c.title === colNameOrId - ); - pt.name = '{' + column.id + '}'; - } else if (pt.type === 'BinaryExpression') { - await substituteId(pt.left); - await substituteId(pt.right); - } - }; - // register curly hook - jsep.plugins.register({ - name: 'curly', - init(jsep) { - jsep.hooks.add('gobble-token', function gobbleCurlyLiteral(env) { - const OCURLY_CODE = 123; // { - const CCURLY_CODE = 125; // } - const { context } = env; - if ( - !jsep.isIdentifierStart(context.code) && - context.code === OCURLY_CODE - ) { - context.index += 1; - const nodes = context.gobbleExpressions(CCURLY_CODE); - if (context.code === CCURLY_CODE) { - context.index += 1; - if (nodes.length > 0) { - env.node = nodes[0]; - } - return env.node; - } else { - context.throwError('Unclosed }'); - } - } - }); - } - } as jsep.IPlugin); - const parsedFormula = jsep(formula); - await substituteId(parsedFormula); - return jsepTreeToFormula(parsedFormula); -} diff --git a/packages/nocodb/src/lib/noco/upgrader/jobs/ncProjectUpgraderV2_0090000.ts b/packages/nocodb/src/lib/noco/upgrader/jobs/ncProjectUpgraderV2_0090000.ts index d2765134af..6b451221c7 100644 --- a/packages/nocodb/src/lib/noco/upgrader/jobs/ncProjectUpgraderV2_0090000.ts +++ b/packages/nocodb/src/lib/noco/upgrader/jobs/ncProjectUpgraderV2_0090000.ts @@ -4,11 +4,15 @@ import User from '../../../noco-models/User'; import Project from '../../../noco-models/Project'; import ProjectUser from '../../../noco-models/ProjectUser'; import Model from '../../../noco-models/Model'; -import { ModelTypes, UITypes, ViewTypes } from 'nocodb-sdk'; +import { + ModelTypes, + substituteColumnAliasWithIdInFormula, + UITypes, + ViewTypes +} from 'nocodb-sdk'; import Column from '../../../noco-models/Column'; import LinkToAnotherRecordColumn from '../../../noco-models/LinkToAnotherRecordColumn'; import NcHelp from '../../../utils/NcHelp'; -import { substituteColumnAliasWithIdInFormula } from '../../meta/helpers/formulaHelpers'; import RollupColumn from '../../../noco-models/RollupColumn'; import View from '../../../noco-models/View'; import GridView from '../../../noco-models/GridView';