import dbHandler from "../db-handler"; import _ from "lodash"; import sqlGenerator from "../../utils/sql-generator"; import sanitizeHtmlFields from "../../utils/sanitize-html-fields"; function quoteIdentifier(identifier) { return `\`${identifier.replace(/`/g, "``")}\``; } export default async function DbUpdate({ table, data, query, targetId, config, }) { let sqlObj = { string: "", values: [] }; try { let finalQuery = query || {}; if (targetId) { finalQuery = _.merge(finalQuery, { query: { id: { value: String(targetId), }, }, }); } const sqlQueryObj = sqlGenerator({ tableName: quoteIdentifier(table), genObject: finalQuery, }); const whereClause = sqlQueryObj.string.match(/WHERE .*/)?.[0]; if (!whereClause) { return { success: false, msg: `No WHERE clause`, }; } let values = []; let sql = ``; sql += `UPDATE ${quoteIdentifier(table)} SET`; const sanitizedData = sanitizeHtmlFields({ table, data, config, }); const finalData = { updated_at: Date.now(), ...sanitizedData, }; const keys = Object.keys(finalData); for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (!key) continue; const isLast = i == keys.length - 1; sql += ` ${quoteIdentifier(key)}=?`; values.push(finalData[key] ?? null); if (!isLast) { sql += `,`; } } sql += ` ${whereClause}`; values = [...values, ...sqlQueryObj.values]; const res = await dbHandler({ query: sql, values: values, config, }); sqlObj.string = sql; sqlObj.values = values; let updated_sql = ``; let updated_sql_values = []; updated_sql += `SELECT * FROM ${quoteIdentifier(table)} ${whereClause}`; updated_sql_values = [...updated_sql_values, ...sqlQueryObj.values]; updated_sql += ` AND `; for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (!key) continue; if (key == "updated_at") continue; const isLast = i == keys.length - 1; updated_sql += ` ${quoteIdentifier(key)}=?`; updated_sql_values.push(finalData[key] ?? null); if (!isLast) { updated_sql += ` AND `; } } const updated_res = await dbHandler({ query: updated_sql, values: updated_sql_values, config, }); const affected_rows = updated_res.payload?.length; return { ...res, success: Boolean(affected_rows), insert_return: { affected_rows, }, debug: { sqlObj, }, }; } catch (error) { return { success: false, error: error.message, debug: { sqlObj, }, }; } }