datasquirel/package-shared/functions/dsql/sql/sql-generator.js

203 lines
6.9 KiB
JavaScript
Raw Permalink Normal View History

2024-11-08 18:54:14 +00:00
// @ts-check
/**
* # SQL Query Generator
* @description Generates an SQL Query for node module `mysql` or `serverless-mysql`
2024-12-06 10:31:24 +00:00
* @type {import("../../../types").SqlGeneratorFn}
2024-11-08 18:54:14 +00:00
*/
function sqlGenerator({ tableName, genObject }) {
if (!genObject) return undefined;
const finalQuery = genObject.query ? genObject.query : undefined;
const queryKeys = finalQuery ? Object.keys(finalQuery) : undefined;
/** @type {string[]} */
const sqlSearhValues = [];
const sqlSearhString = queryKeys?.map((field) => {
const queryObj = finalQuery?.[field];
if (!queryObj) return;
2024-11-08 20:44:24 +00:00
const finalFieldName = (() => {
if (queryObj?.tableName) {
return `${queryObj.tableName}.${field}`;
}
if (genObject.join) {
return `${tableName}.${field}`;
}
return field;
})();
let str = `${finalFieldName}=?`;
2024-11-08 18:54:14 +00:00
if (
typeof queryObj.value == "string" ||
typeof queryObj.value == "number"
) {
const valueParsed = String(queryObj.value);
if (queryObj.equality == "LIKE") {
2024-11-08 20:44:24 +00:00
str = `LOWER(${finalFieldName}) LIKE LOWER('%${valueParsed}%')`;
2024-11-08 18:54:14 +00:00
} else {
sqlSearhValues.push(valueParsed);
}
} else if (Array.isArray(queryObj.value)) {
/** @type {string[]} */
const strArray = [];
queryObj.value.forEach((val) => {
const valueParsed = val;
if (queryObj.equality == "LIKE") {
strArray.push(
2024-11-08 20:44:24 +00:00
`LOWER(${finalFieldName}) LIKE LOWER('%${valueParsed}%')`
2024-11-08 18:54:14 +00:00
);
} else {
2024-11-08 20:44:24 +00:00
strArray.push(`${finalFieldName} = ?`);
2024-11-08 18:54:14 +00:00
sqlSearhValues.push(valueParsed);
}
});
str = "(" + strArray.join(` ${queryObj.operator || "AND"} `) + ")";
}
return str;
});
function generateJoinStr(
2024-12-06 10:31:24 +00:00
/** @type {import("../../../types").ServerQueryParamsJoinMatchObject} */ mtch,
/** @type {import("../../../types").ServerQueryParamsJoin} */ join
2024-11-08 18:54:14 +00:00
) {
return `${
typeof mtch.source == "object" ? mtch.source.tableName : tableName
}.${
typeof mtch.source == "object" ? mtch.source.fieldName : mtch.source
2024-11-12 05:47:31 +00:00
}=${(() => {
if (mtch.targetLiteral) {
2024-11-12 05:52:30 +00:00
return `'${mtch.targetLiteral}'`;
2024-11-12 05:47:31 +00:00
}
2024-12-19 20:37:34 +00:00
if (join.alias) return `${join.alias}.${mtch.target}`;
2024-11-12 05:47:31 +00:00
return `${
typeof mtch.target == "object"
? mtch.target.tableName
: join.tableName
}.${
typeof mtch.target == "object"
? mtch.target.fieldName
: mtch.target
}`;
})()}`;
2024-11-08 18:54:14 +00:00
}
let queryString = (() => {
let str = "SELECT";
if (genObject.selectFields?.[0]) {
if (genObject.join) {
str += ` ${genObject.selectFields
?.map((fld) => `${tableName}.${fld}`)
.join(",")}`;
} else {
str += ` ${genObject.selectFields?.join(",")}`;
}
} else {
if (genObject.join) {
str += ` ${tableName}.*`;
} else {
str += " *";
}
}
if (genObject.join) {
/** @type {string[]} */
const existingJoinTableNames = [tableName];
2024-11-08 18:54:14 +00:00
str +=
"," +
genObject.join
.map((joinObj) => {
2024-12-19 20:37:34 +00:00
const joinTableName = joinObj.alias
? joinObj.alias
: joinObj.tableName;
if (existingJoinTableNames.includes(joinTableName))
return null;
2024-12-19 20:37:34 +00:00
existingJoinTableNames.push(joinTableName);
2024-11-08 18:54:14 +00:00
if (joinObj.selectFields) {
return joinObj.selectFields
.map((slFld) => {
if (typeof slFld == "string") {
2024-12-19 20:37:34 +00:00
return `${joinTableName}.${slFld}`;
2024-11-08 18:54:14 +00:00
} else if (typeof slFld == "object") {
2024-12-19 20:37:34 +00:00
let aliasSlctFld = `${joinTableName}.${slFld.field}`;
2024-11-08 18:54:14 +00:00
if (slFld.alias)
aliasSlctFld += ` as ${slFld.alias}`;
return aliasSlctFld;
}
})
.join(",");
} else {
2024-12-19 20:37:34 +00:00
return `${joinTableName}.*`;
2024-11-08 18:54:14 +00:00
}
})
.filter((_) => Boolean(_))
2024-11-08 18:54:14 +00:00
.join(",");
}
str += ` FROM ${tableName}`;
if (genObject.join) {
str +=
" " +
genObject.join
.map((join) => {
return (
join.joinType +
" " +
2024-12-19 20:37:34 +00:00
(join.alias
? join.tableName + " AS " + join.alias
: join.tableName) +
2024-11-08 18:54:14 +00:00
" ON " +
(() => {
if (Array.isArray(join.match)) {
return (
"(" +
join.match
.map((mtch) =>
generateJoinStr(mtch, join)
)
.join(" AND ") +
")"
);
} else if (typeof join.match == "object") {
return generateJoinStr(join.match, join);
}
})()
);
})
.join(" ");
}
return str;
})();
2024-12-17 17:39:50 +00:00
if (sqlSearhString?.[0] && sqlSearhString.find((str) => str)) {
2024-11-08 18:54:14 +00:00
const stringOperator = genObject?.searchOperator || "AND";
2024-11-08 20:44:24 +00:00
queryString += ` WHERE ${sqlSearhString.join(` ${stringOperator} `)} `;
2024-11-08 18:54:14 +00:00
}
if (genObject.order)
queryString += ` ORDER BY ${
genObject.join
? `${tableName}.${genObject.order.field}`
: genObject.order.field
} ${genObject.order.strategy}`;
2024-11-08 18:54:14 +00:00
if (genObject.limit) queryString += ` LIMIT ${genObject.limit}`;
return {
string: queryString,
values: sqlSearhValues,
};
}
module.exports = sqlGenerator;