Browse Source

fix(api): block table deletion if there is a relation exist

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/1886/head
Pranav C 3 years ago
parent
commit
1f3b889c4a
  1. 91
      packages/nocodb/src/lib/noco/meta/api/tableApis.ts

91
packages/nocodb/src/lib/noco/meta/api/tableApis.ts

@ -5,10 +5,12 @@ import { Tele } from 'nc-help';
import { import {
AuditOperationSubTypes, AuditOperationSubTypes,
AuditOperationTypes, AuditOperationTypes,
isVirtualCol,
ModelTypes, ModelTypes,
TableListType, TableListType,
TableReqType, TableReqType,
TableType TableType,
UITypes
} from 'nocodb-sdk'; } from 'nocodb-sdk';
import ProjectMgrv2 from '../../../sqlMgr/v2/ProjectMgrv2'; import ProjectMgrv2 from '../../../sqlMgr/v2/ProjectMgrv2';
import Project from '../../../noco-models/Project'; import Project from '../../../noco-models/Project';
@ -23,6 +25,7 @@ import getTableNameAlias, { getColumnNameAlias } from '../helpers/getTableName';
import Column from '../../../noco-models/Column'; import Column from '../../../noco-models/Column';
import NcConnectionMgrv2 from '../../common/NcConnectionMgrv2'; import NcConnectionMgrv2 from '../../common/NcConnectionMgrv2';
import getColumnUiType from '../helpers/getColumnUiType'; import getColumnUiType from '../helpers/getColumnUiType';
import LinkToAnotherRecordColumn from '../../../noco-models/LinkToAnotherRecordColumn';
export async function tableGet(req: Request, res: Response<TableType>) { export async function tableGet(req: Request, res: Response<TableType>) {
const table = await Model.getWithInfo({ const table = await Model.getWithInfo({
id: req.params.tableId id: req.params.tableId
@ -199,44 +202,60 @@ export async function tableUpdate(req: Request<any, any>, res) {
res.json({ msg: 'success' }); res.json({ msg: 'success' });
} }
export async function tableDelete(req: Request, res: Response, next) { export async function tableDelete(req: Request, res: Response) {
try { const table = await Model.getByIdOrName({ id: req.params.tableId });
const table = await Model.getByIdOrName({ id: req.params.tableId }); await table.getColumns();
await table.getColumns();
const project = await Project.getWithInfo(table.project_id);
const base = project.bases.find(b => b.id === table.base_id);
const sqlMgr = await ProjectMgrv2.getSqlMgr(project);
(table as any).tn = table.table_name;
table.columns.forEach(c => {
(c as any).cn = c.column_name;
});
if (table.type === ModelTypes.TABLE) { const relationColumns = table.columns.filter(
await sqlMgr.sqlOpPlus(base, 'tableDelete', table); c => c.uidt === UITypes.LinkToAnotherRecord
} else if (table.type === ModelTypes.VIEW) { );
await sqlMgr.sqlOpPlus(base, 'viewDelete', {
...table,
view_name: table.table_name
});
}
Audit.insert({ if (relationColumns?.length) {
project_id: project.id, const referredTables = await Promise.all(
op_type: AuditOperationTypes.TABLE, relationColumns.map(async c =>
op_sub_type: AuditOperationSubTypes.DELETED, c
user: (req as any)?.user?.email, .getColOptions<LinkToAnotherRecordColumn>()
description: `Deleted ${table.type} ${table.table_name} with alias ${table.title} `, .then(opt => opt.getRelatedTable())
ip: (req as any).clientIp .then()
}).then(() => {}); )
);
Tele.emit('evt', { evt_type: 'table:deleted' }); NcError.badRequest(
`Table can't be deleted since Table is being referred in following tables : ${referredTables.join(
res.json(await table.delete()); ', '
} catch (e) { )}. Delete LinkToAnotherRecord columns and try again.`
console.log(e); );
next(e);
} }
const project = await Project.getWithInfo(table.project_id);
const base = project.bases.find(b => b.id === table.base_id);
const sqlMgr = await ProjectMgrv2.getSqlMgr(project);
(table as any).tn = table.table_name;
table.columns = table.columns.filter(c => !isVirtualCol(c));
table.columns.forEach(c => {
(c as any).cn = c.column_name;
});
if (table.type === ModelTypes.TABLE) {
await sqlMgr.sqlOpPlus(base, 'tableDelete', table);
} else if (table.type === ModelTypes.VIEW) {
await sqlMgr.sqlOpPlus(base, 'viewDelete', {
...table,
view_name: table.table_name
});
}
Audit.insert({
project_id: project.id,
op_type: AuditOperationTypes.TABLE,
op_sub_type: AuditOperationSubTypes.DELETED,
user: (req as any)?.user?.email,
description: `Deleted ${table.type} ${table.table_name} with alias ${table.title} `,
ip: (req as any).clientIp
}).then(() => {});
Tele.emit('evt', { evt_type: 'table:deleted' });
res.json(await table.delete());
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });

Loading…
Cancel
Save