|
|
|
@ -43,7 +43,14 @@ import {
|
|
|
|
|
} from '~/helpers/getUniqueName'; |
|
|
|
|
import mapDefaultDisplayValue from '~/helpers/mapDefaultDisplayValue'; |
|
|
|
|
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 NcConnectionMgrv2 from '~/utils/common/NcConnectionMgrv2'; |
|
|
|
|
import { MetaTable } from '~/utils/globals'; |
|
|
|
@ -1072,6 +1079,235 @@ export class ColumnsService {
|
|
|
|
|
); |
|
|
|
|
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, { |
|
|
|
|
...colBody, |
|
|
|
|
}); |
|
|
|
|