UNPKG

autosql

Version:

An auto-parser of JSON into SQL.

150 lines (149 loc) 6.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MySQLInsertQueryBuilder = void 0; const mysqlConfig_1 = require("../../config/mysqlConfig"); const utilities_1 = require("../../../helpers/utilities"); const dialectConfig = mysqlConfig_1.mysqlConfig; class MySQLInsertQueryBuilder { static getInsertStatementQuery(tableOrInput, data, metaData, databaseConfig, inputInsertType) { let table; let rows; let header; let insertType; const schemaPrefix = databaseConfig?.schema ? `\`${databaseConfig.schema}\`.` : ""; if (typeof tableOrInput === "object" && "table" in tableOrInput) { table = tableOrInput.table; rows = tableOrInput.data; header = tableOrInput.comparedMetaData?.updatedMetaData || tableOrInput.metaData; insertType = tableOrInput?.insertType || databaseConfig?.insertType || "UPDATE"; } else { table = tableOrInput; rows = data; header = metaData; insertType = inputInsertType || databaseConfig?.insertType || "UPDATE"; } if (!rows || rows.length === 0) { throw new Error(`No data provided for insert into table "${table}"`); } const columns = Object.keys(header); // Flatten values let params = []; if (typeof rows[0] === "object" && !Array.isArray(rows[0])) { const normalisedChunk = rows.map(row => (0, utilities_1.getInsertValues)(header, row, undefined, undefined, false) // ⬅ false = flatten ); params = normalisedChunk.flat(); } else { params = rows.flat(); } const escapedCols = columns.map(col => `\`${col}\``).join(", "); const valuePlaceholders = rows .map(() => `(${columns.map(() => `?`).join(", ")})`) .join(", "); let query = `INSERT INTO ${schemaPrefix}\`${table}\` (${escapedCols}) VALUES ${valuePlaceholders}`; if (insertType === "UPDATE") { // Get primary key columns const primaryKeys = Object.keys(header).filter((col) => header[col].primary === true); const updateCols = columns.filter((col) => { const colMeta = header[col]; // Exclude primary keys and protected calculated fields const isPrimary = primaryKeys.includes(col); const isProtectedCalc = colMeta.calculated === true && colMeta.updatedCalculated === false; return !isPrimary && !isProtectedCalc; }); if (updateCols.length > 0) { const updateSet = updateCols .map(col => `\`${col}\` = VALUES(\`${col}\`)`) .join(", "); query += ` ON DUPLICATE KEY UPDATE ${updateSet}`; } } const result = { query, params }; return result; } static getInsertFromStagingQuery(tableOrInput, metaData, databaseConfig, inputInsertType) { let table; let header; let insertType; const schemaPrefix = databaseConfig?.schema ? `\`${databaseConfig.schema}\`.` : ""; if (typeof tableOrInput === "object" && "table" in tableOrInput) { table = tableOrInput.table; header = tableOrInput.comparedMetaData?.updatedMetaData || tableOrInput.metaData; insertType = tableOrInput?.insertType || databaseConfig?.insertType || "UPDATE"; } else { table = tableOrInput; header = metaData; insertType = inputInsertType || databaseConfig?.insertType || "UPDATE"; } const tempTable = (0, utilities_1.getTempTableName)(table); const columns = Object.keys(header); const escapedCols = columns.map(col => `\`${col}\``).join(", "); const selectCols = columns.map(col => `\`${col}\``).join(", "); let query = `INSERT INTO ${schemaPrefix}\`${table}\` (${escapedCols}) SELECT ${selectCols} FROM ${schemaPrefix}\`${tempTable}\``; if (insertType === "UPDATE") { const primaryKeys = Object.keys(header).filter(col => header[col].primary === true); const updateCols = columns.filter((col) => { const colMeta = header[col]; const isPrimary = primaryKeys.includes(col); const isProtectedCalc = colMeta.calculated === true && colMeta.updatedCalculated === false; return !isPrimary && !isProtectedCalc; }); if (updateCols.length > 0) { const updateSet = updateCols .map(col => `\`${col}\` = VALUES(\`${col}\`)`) .join(", "); query += ` ON DUPLICATE KEY UPDATE ${updateSet}`; } } return { query, params: [] }; } static getInsertChangedRowsToHistoryQuery(tableOrInput, metaData, databaseConfig) { let table; let header; const schemaPrefix = databaseConfig?.schema ? `\`${databaseConfig.schema}\`.` : ""; if (typeof tableOrInput === "object" && "table" in tableOrInput) { table = (0, utilities_1.getTrueTableName)(tableOrInput.table); header = tableOrInput.comparedMetaData?.updatedMetaData || tableOrInput.metaData; } else { table = (0, utilities_1.getTrueTableName)(tableOrInput); header = metaData; } const historyTable = (0, utilities_1.getHistoryTableName)(table); const tempTable = (0, utilities_1.getTempTableName)(table); const filteredCols = Object.keys(header).filter(col => col !== "dwh_as_at"); const primaryKeys = filteredCols.filter(col => header[col].primary); const nonPrimaryCols = filteredCols.filter(col => !header[col].primary && header[col].calculated !== true); const t1 = "t1"; const t2 = "t2"; const valuesCols = filteredCols.map(col => `\`${col}\``).join(", "); const selectCols = filteredCols.map(col => `${t1}.\`${col}\``).join(", "); const joinCondition = primaryKeys .map(pk => `${t1}.\`${pk}\` = ${t2}.\`${pk}\``) .join(" AND "); const diffCondition = nonPrimaryCols .map(col => `${t1}.\`${col}\` <=> ${t2}.\`${col}\` = FALSE`) .join(" OR "); const query = ` INSERT INTO ${schemaPrefix}\`${historyTable}\` (${valuesCols}, \`dwh_as_at\`) SELECT ${selectCols}, NOW() FROM ${schemaPrefix}\`${table}\` ${t1} LEFT JOIN ${schemaPrefix}\`${tempTable}\` ${t2} ON ${joinCondition} WHERE ${diffCondition}; `.trim(); return { query, params: [] }; } } exports.MySQLInsertQueryBuilder = MySQLInsertQueryBuilder;