From 0d3e51793125f7aad9b15c8a5863390002d1abdc Mon Sep 17 00:00:00 2001 From: Pranav C Date: Tue, 6 Jun 2023 01:03:17 +0530 Subject: [PATCH] feat: delete related data in bulk delete Signed-off-by: Pranav C --- packages/nocodb/src/db/BaseModelSqlv2.ts | 62 +++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/packages/nocodb/src/db/BaseModelSqlv2.ts b/packages/nocodb/src/db/BaseModelSqlv2.ts index dae2103079..c3de3a4ffd 100644 --- a/packages/nocodb/src/db/BaseModelSqlv2.ts +++ b/packages/nocodb/src/db/BaseModelSqlv2.ts @@ -1885,7 +1885,6 @@ class BaseModelSqlv2 { const execQueries: ((trx: Transaction) => Promise)[] = []; - // start a transaction if not already in one for (const column of this.model.columns) { if (column.uidt !== UITypes.LinkToAnotherRecord) continue; @@ -2445,8 +2444,69 @@ class BaseModelSqlv2 { res.push(d); } + const execQueries: ((trx: Transaction, ids: any[]) => Promise)[] = + []; + + for (const column of this.model.columns) { + if (column.uidt !== UITypes.LinkToAnotherRecord) continue; + + const colOptions = + await column.getColOptions(); + + switch (colOptions.type) { + case 'mm': + { + const mmTable = await Model.get(colOptions.fk_mm_model_id); + const mmParentColumn = await Column.get({ + colId: colOptions.fk_mm_child_column_id, + }); + + execQueries.push((trx, ids) => + trx(mmTable.table_name) + .del() + .whereIn(mmParentColumn.column_name, ids), + ); + } + break; + case 'hm': + { + // skip if it's an mm table column + const relatedTable = await colOptions.getRelatedTable(); + if (relatedTable.mm) { + break; + } + + const childColumn = await Column.get({ + colId: colOptions.fk_child_column_id, + }); + + execQueries.push((trx, ids) => + trx(relatedTable.table_name) + .update({ + [childColumn.column_name]: null, + }) + .whereIn(childColumn.column_name, ids), + ); + } + break; + case 'bt': + { + // nothing to do + } + break; + } + } + + const idsVals = res.map((d) => d[this.model.primaryKey.column_name]); + transaction = await this.dbDriver.transaction(); + if (execQueries.length > 0) { + for (const execQuery of execQueries) { + await execQuery(transaction, idsVals); + } + } + for (const d of res) { await transaction(this.tnPath).del().where(d); }