Browse Source

feat: user field conversion

pull/7202/head
mertmit 12 months ago
parent
commit
718f93ec59
  1. 238
      packages/nocodb/src/services/columns.service.ts

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

@ -43,7 +43,14 @@ import {
} from '~/helpers/getUniqueName'; } from '~/helpers/getUniqueName';
import mapDefaultDisplayValue from '~/helpers/mapDefaultDisplayValue'; import mapDefaultDisplayValue from '~/helpers/mapDefaultDisplayValue';
import validateParams from '~/helpers/validateParams'; import validateParams from '~/helpers/validateParams';
import { Column, FormulaColumn, KanbanView, Model, Source } from '~/models'; import {
BaseUser,
Column,
FormulaColumn,
KanbanView,
Model,
Source,
} from '~/models';
import Noco from '~/Noco'; import Noco from '~/Noco';
import NcConnectionMgrv2 from '~/utils/common/NcConnectionMgrv2'; import NcConnectionMgrv2 from '~/utils/common/NcConnectionMgrv2';
import { MetaTable } from '~/utils/globals'; import { MetaTable } from '~/utils/globals';
@ -1072,6 +1079,235 @@ export class ColumnsService {
); );
await sqlMgr.sqlOpPlus(source, 'tableUpdate', tableUpdateBody); await sqlMgr.sqlOpPlus(source, 'tableUpdate', tableUpdateBody);
await Column.update(param.columnId, {
...colBody,
});
} else if (
[UITypes.SingleLineText, UITypes.Email].includes(column.uidt)
) {
// email/text to user
const baseModel = await reuseOrSave('baseModel', reuse, async () =>
Model.getBaseModelSQL({
id: table.id,
dbDriver: await reuseOrSave('dbDriver', reuse, async () =>
NcConnectionMgrv2.get(source),
),
}),
);
const baseUsers = await BaseUser.getUsersList({
base_id: column.base_id,
});
try {
const data = await baseModel.execAndParse(
sqlClient.knex
.raw('SELECT DISTINCT ?? FROM ??', [
column.column_name,
baseModel.getTnPath(table.table_name),
])
.toQuery(),
);
let isMultiple = false;
const rows = data.map((el) => el[column.column_name]);
const emails = rows
.map((el) => {
const res = el.split(',').map((e) => e.trim());
if (res.length > 1) {
isMultiple = true;
}
return res;
})
.flat();
// check if emails are present baseUsers
const emailsNotPresent = emails.filter((el) => {
return !baseUsers.find((user) => user.email === el);
});
if (emailsNotPresent.length) {
NcError.badRequest(
`Some of the emails are not present in the database.`,
);
}
if (isMultiple) {
colBody.meta = {
is_multi: true,
};
}
} catch (e) {
NcError.badRequest('Some of the emails are present in the database.');
}
// create nested replace statement for each user
const setStatement = baseUsers.reduce((acc, user) => {
const qb = sqlClient.knex.raw(`REPLACE(${acc}, ?, ?)`, [
user.email,
user.id,
]);
return qb.toQuery();
}, sqlClient.knex.raw(`??`, [column.column_name]).toQuery());
await sqlClient.raw(`UPDATE ?? SET ?? = ${setStatement};`, [
baseModel.getTnPath(table.table_name),
column.column_name,
]);
colBody = await getColumnPropsFromUIDT(colBody, source);
const tableUpdateBody = {
...table,
tn: table.table_name,
originalColumns: table.columns.map((c) => ({
...c,
cn: c.column_name,
cno: c.column_name,
})),
columns: await Promise.all(
table.columns.map(async (c) => {
if (c.id === param.columnId) {
const res = {
...c,
...colBody,
cn: colBody.column_name,
cno: c.column_name,
altered: Altered.UPDATE_COLUMN,
};
// 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,
});
}
}
}
return Promise.resolve(res);
} else {
(c as any).cn = c.column_name;
}
return Promise.resolve(c);
}),
),
};
const sqlMgr = await reuseOrSave('sqlMgr', reuse, async () =>
ProjectMgrv2.getSqlMgr({ id: source.base_id }),
);
await sqlMgr.sqlOpPlus(source, 'tableUpdate', tableUpdateBody);
await Column.update(param.columnId, {
...colBody,
});
} else {
NcError.notImplemented(
`Updating ${column.uidt} => ${colBody.uidt} is not supported at the moment`,
);
}
} else if (column.uidt === UITypes.User) {
if ([UITypes.SingleLineText, UITypes.Email].includes(colBody.uidt)) {
// user to email/text
const baseModel = await reuseOrSave('baseModel', reuse, async () =>
Model.getBaseModelSQL({
id: table.id,
dbDriver: await reuseOrSave('dbDriver', reuse, async () =>
NcConnectionMgrv2.get(source),
),
}),
);
const baseUsers = await BaseUser.getUsersList({
base_id: column.base_id,
});
// create nested replace statement for each user
const setStatement = baseUsers.reduce((acc, user) => {
const qb = sqlClient.knex.raw(`REPLACE(${acc}, ?, ?)`, [
user.id,
user.email,
]);
return qb.toQuery();
}, sqlClient.knex.raw(`??`, [column.column_name]).toQuery());
await sqlClient.raw(`UPDATE ?? SET ?? = ${setStatement};`, [
baseModel.getTnPath(table.table_name),
column.column_name,
]);
colBody = await getColumnPropsFromUIDT(colBody, source);
const tableUpdateBody = {
...table,
tn: table.table_name,
originalColumns: table.columns.map((c) => ({
...c,
cn: c.column_name,
cno: c.column_name,
})),
columns: await Promise.all(
table.columns.map(async (c) => {
if (c.id === param.columnId) {
const res = {
...c,
...colBody,
cn: colBody.column_name,
cno: c.column_name,
altered: Altered.UPDATE_COLUMN,
};
// 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,
});
}
}
}
return Promise.resolve(res);
} else {
(c as any).cn = c.column_name;
}
return Promise.resolve(c);
}),
),
};
const sqlMgr = await reuseOrSave('sqlMgr', reuse, async () =>
ProjectMgrv2.getSqlMgr({ id: source.base_id }),
);
await sqlMgr.sqlOpPlus(source, 'tableUpdate', tableUpdateBody);
await Column.update(param.columnId, { await Column.update(param.columnId, {
...colBody, ...colBody,
}); });

Loading…
Cancel
Save