Browse Source

fix: formula error on field title update (#7924)

* fix: avoid stringifying null with stringifyMetaProp

* fix: move updating formulas to a function
pull/7928/head
Mert E 9 months ago committed by GitHub
parent
commit
b28877360c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 183
      packages/nocodb/src/services/columns.service.ts
  2. 7
      packages/nocodb/src/utils/modelUtils.ts

183
packages/nocodb/src/services/columns.service.ts

@ -102,6 +102,37 @@ export class ColumnsService {
protected readonly appHooksService: AppHooksService,
) {}
async updateFormulas(args: { oldColumn: any; colBody: any }) {
const { oldColumn, colBody } = args;
// update formula if column name or title is changed
if (
oldColumn.column_name !== colBody.column_name ||
oldColumn.title !== colBody.title
) {
const formulas = await Noco.ncMeta
.knex(MetaTable.COL_FORMULA)
.where('formula', 'like', `%${oldColumn.id}%`);
if (formulas) {
oldColumn.column_name = colBody.column_name;
oldColumn.title = colBody.title;
for (const f of formulas) {
// replace column IDs with alias to get the new formula_raw
const new_formula_raw = substituteColumnIdWithAliasInFormula(
f.formula,
[oldColumn],
);
// update the formula_raw and set parsed_tree to null to reparse the formula
await FormulaColumn.update(oldColumn.id, {
formula_raw: new_formula_raw,
parsed_tree: null,
});
}
}
}
}
async columnUpdate(param: {
req?: any;
columnId: string;
@ -975,39 +1006,10 @@ export class ColumnsService {
};
// update formula with new column name
if (c.column_name != colBody.column_name) {
const formulas = await Noco.ncMeta
.knex(MetaTable.COL_FORMULA)
.where('formula', 'like', `%${c.id}%`);
if (formulas) {
const new_column = c;
new_column.column_name = colBody.column_name;
new_column.title = colBody.title;
for (const f of formulas) {
// the formula with column IDs only
const formula = f.formula;
// replace column IDs with alias to get the new formula_raw
const new_formula_raw =
substituteColumnIdWithAliasInFormula(formula, [
new_column,
]);
await FormulaColumn.update(c.id, {
formula_raw: new_formula_raw,
parsed_tree: await validateFormulaAndExtractTreeWithType({
formula: new_formula_raw,
columns: table.columns,
column,
clientOrSqlUi: source.type,
getMeta: async (modelId) => {
const model = await Model.get(modelId);
await model.getColumns();
return model;
},
}),
});
}
}
}
await this.updateFormulas({
oldColumn: column,
colBody,
});
return Promise.resolve(res);
} else {
(c as any).cn = c.column_name;
@ -1139,28 +1141,10 @@ export class ColumnsService {
};
// update formula with new column name
if (c.column_name != colBody.column_name) {
const formulas = await Noco.ncMeta
.knex(MetaTable.COL_FORMULA)
.where('formula', 'like', `%${c.id}%`);
if (formulas) {
const new_column = c;
new_column.column_name = colBody.column_name;
new_column.title = colBody.title;
for (const f of formulas) {
// the formula with column IDs only
const formula = f.formula;
// replace column IDs with alias to get the new formula_raw
const new_formula_raw =
substituteColumnIdWithAliasInFormula(formula, [
new_column,
]);
await FormulaColumn.update(c.id, {
formula_raw: new_formula_raw,
});
}
}
}
await this.updateFormulas({
oldColumn: column,
colBody,
});
return Promise.resolve(res);
} else {
(c as any).cn = c.column_name;
@ -1273,28 +1257,10 @@ export class ColumnsService {
};
// update formula with new column name
if (c.column_name != colBody.column_name) {
const formulas = await Noco.ncMeta
.knex(MetaTable.COL_FORMULA)
.where('formula', 'like', `%${c.id}%`);
if (formulas) {
const new_column = c;
new_column.column_name = colBody.column_name;
new_column.title = colBody.title;
for (const f of formulas) {
// the formula with column IDs only
const formula = f.formula;
// replace column IDs with alias to get the new formula_raw
const new_formula_raw =
substituteColumnIdWithAliasInFormula(formula, [
new_column,
]);
await FormulaColumn.update(c.id, {
formula_raw: new_formula_raw,
});
}
}
}
await this.updateFormulas({
oldColumn: column,
colBody,
});
return Promise.resolve(res);
} else {
(c as any).cn = c.column_name;
@ -1366,28 +1332,10 @@ export class ColumnsService {
};
// update formula with new column name
if (c.column_name != colBody.column_name) {
const formulas = await Noco.ncMeta
.knex(MetaTable.COL_FORMULA)
.where('formula', 'like', `%${c.id}%`);
if (formulas) {
const new_column = c;
new_column.column_name = colBody.column_name;
new_column.title = colBody.title;
for (const f of formulas) {
// the formula with column IDs only
const formula = f.formula;
// replace column IDs with alias to get the new formula_raw
const new_formula_raw =
substituteColumnIdWithAliasInFormula(formula, [
new_column,
]);
await FormulaColumn.update(c.id, {
formula_raw: new_formula_raw,
});
}
}
}
await this.updateFormulas({
oldColumn: column,
colBody,
});
return Promise.resolve(res);
} else {
(c as any).cn = c.column_name;
@ -1430,39 +1378,10 @@ export class ColumnsService {
};
// update formula with new column name
if (c.column_name != colBody.column_name) {
const formulas = await Noco.ncMeta
.knex(MetaTable.COL_FORMULA)
.where('formula', 'like', `%${c.id}%`);
if (formulas) {
const new_column = c;
new_column.column_name = colBody.column_name;
new_column.title = colBody.title;
for (const f of formulas) {
// the formula with column IDs only
const formula = f.formula;
// replace column IDs with alias to get the new formula_raw
const new_formula_raw =
substituteColumnIdWithAliasInFormula(formula, [
new_column,
]);
await FormulaColumn.update(c.id, {
formula_raw: new_formula_raw,
parsed_tree: await validateFormulaAndExtractTreeWithType({
formula: new_formula_raw,
columns: table.columns,
column,
clientOrSqlUi: source.type,
getMeta: async (modelId) => {
const model = await Model.get(modelId);
await model.getColumns();
return model;
},
}),
});
}
}
}
await this.updateFormulas({
oldColumn: column,
colBody,
});
return Promise.resolve(res);
} else {
(c as any).cn = c.column_name;

7
packages/nocodb/src/utils/modelUtils.ts

@ -11,12 +11,15 @@ export function parseMetaProp(model: any, propName = 'meta'): any {
}
}
export function stringifyMetaProp(model: any, propName = 'meta'): string {
export function stringifyMetaProp(
model: any,
propName = 'meta',
): string | null {
if (!model) return null;
// stringify meta property
try {
return typeof model[propName] === 'string'
return typeof model[propName] === 'string' || model[propName] === null
? model[propName]
: JSON.stringify(model[propName]);
} catch (e) {

Loading…
Cancel
Save