diff --git a/src/models/hasChildrenModel.js b/src/models/hasChildrenModel.js new file mode 100644 index 0000000..2073858 --- /dev/null +++ b/src/models/hasChildrenModel.js @@ -0,0 +1,33 @@ +import { cascadeSoftDeleteQuery, hasChildrenQuery } from "../repositories/hasChildrenRepository.js"; +import dayjs from "dayjs"; + +const hasChildrenModel = (conn, { adapter, dbName, table1, fieldName1, uuidTable1, table2, fieldName2 }) => { + const params = { + dbName, + table1, + fieldName1, + uuidTable1, + table2, + fieldName2 + }; + + return adapter.execute(hasChildrenQuery(params), conn, params); +}; + + +const cascadeSoftDeleteModel = (conn, {adapter, dbName, tableName, uuid}, deleted) => { + const deletedData = deleted ? dayjs.utc(deleted).format('YYYY-MM-DD HH:mm:ss') : dayjs.utc().format('YYYY-MM-DD HH:mm:ss') + const params = { + dbName, + tableName, + uuid, + deleted: deletedData} + + return adapter + .execute(cascadeSoftDeleteQuery(params), conn, params) +} + +export { + hasChildrenModel, + cascadeSoftDeleteModel +} \ No newline at end of file diff --git a/src/repositories/hasChildrenRepository.js b/src/repositories/hasChildrenRepository.js new file mode 100644 index 0000000..8802c69 --- /dev/null +++ b/src/repositories/hasChildrenRepository.js @@ -0,0 +1,28 @@ +const hasChildrenQuery = ({dbName, table1, fieldName1, table2, fieldName2}) => { + const table2InSchema = `${dbName}.${table2}` + const table1InSchema = `${dbName}.${table1}` + const fieldName1NoQuotation = fieldName1.replace(/['"]/g, ''); + const fieldName2NoQuotation = fieldName2.replace(/['"]/g, ''); + return ` + SELECT * + FROM ${table2InSchema} + WHERE ${fieldName2NoQuotation} = + (SELECT ${fieldName1NoQuotation} FROM ${table1InSchema} WHERE uuid = :uuidTable1) + AND deleted IS NULL + ` +} + +const cascadeSoftDeleteQuery = ({dbName, tableName}) => { + const tableInSchema = `${dbName}.${tableName}` + return ` + UPDATE ${tableInSchema} + SET deleted = :deleted + WHERE uuid = :uuid + AND deleted IS NULL + ` +} + +export { + hasChildrenQuery, + cascadeSoftDeleteQuery +} \ No newline at end of file diff --git a/src/utils/hasChildren.js b/src/utils/hasChildren.js index ecdb8f8..1976afc 100644 --- a/src/utils/hasChildren.js +++ b/src/utils/hasChildren.js @@ -1,21 +1,57 @@ -import { hasChildrenModel } from '../models/hasChildrenModel' +import { cascadeSoftDeleteModel } from '../models/hasChildrenModel.js' +import { hasChildrenModel } from '../models/hasChildrenModel.js' +import { errorHandler } from './errors.js' -const hasChildren = (req, res, next, config, { adapter, schema, table1, fieldNameTable1, uuidTable1, table2, fieldNameTable2 }) => { +const hasChildren = (req, res, next, config, { adapter, dbName, table1, fieldName1, uuidTable1, table2, fieldName2 }) => { return new Promise((resolve) => { - const conn = adapter.start(config) - resolve(hasChildrenModel({ adapter, schema, table1, fieldNameTable1, uuidTable1, table2, fieldNameTable2 }, conn) - .then((hasChildren) => { - const result = hasChildren === undefined || hasChildren.length === 0 ? [] : { hasChildren } - next(result) - return result - }) - .catch((err) => { - throw (err.message) - }) - .finally(() => { - adapter.end(conn) - })) + const conn = adapter.start(config) + resolve(hasChildrenModel(conn, { adapter, dbName, table1, fieldName1, uuidTable1, table2, fieldName2 }) + .then((hasChildren) => { + const result = hasChildren === undefined || hasChildren.length === 0 ? [] : { hasChildren } + next(result) + return result + }) + .catch((err) => { + const error = errorHandler(err, config.environment) + res.status(error.code).json(error); + }) + .finally(() => { + adapter.end(conn) + })) }) } + +const checkAndSoftDeleteChildren = (req, res, next, config, {adapter, dbName, childTable, childField, parentTable, parentField, parentUuid}) => { + hasChildren(req, res, (result) => { + const children = result.hasChildren || []; + if (!children.length) { + next(); + return; + } + const conn = adapter.start(config); + + const deletePromises = children.map((child) => { + return cascadeSoftDeleteModel(conn, { + adapter, + dbName, + tableName: childTable, + uuid: child.uuid + }); + }); -export { hasChildren } + Promise.all(deletePromises) + .then(() => + next()) + .catch(err => { + const error = errorHandler(err, config.environment); + res.status(error.code).json(error); + }) + .finally(() => { + adapter.end(conn); + }); + }, config, { adapter, dbName, table1: parentTable, fieldName1: parentField, uuidTable1: parentUuid, table2: childTable, fieldName2: childField }); +}; + +export{ + checkAndSoftDeleteChildren, hasChildren +} \ No newline at end of file