195 lines
6.6 KiB
JavaScript
195 lines
6.6 KiB
JavaScript
// @ts-check
|
|
|
|
/**
|
|
* # SQL Query Generator
|
|
* @description Generates an SQL Query for node module `mysql` or `serverless-mysql`
|
|
* @type {import("../../../types").SqlGeneratorFn}
|
|
*/
|
|
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;
|
|
|
|
const finalFieldName = (() => {
|
|
if (queryObj?.tableName) {
|
|
return `${queryObj.tableName}.${field}`;
|
|
}
|
|
if (genObject.join) {
|
|
return `${tableName}.${field}`;
|
|
}
|
|
return field;
|
|
})();
|
|
|
|
let str = `${finalFieldName}=?`;
|
|
|
|
if (
|
|
typeof queryObj.value == "string" ||
|
|
typeof queryObj.value == "number"
|
|
) {
|
|
const valueParsed = String(queryObj.value);
|
|
if (queryObj.equality == "LIKE") {
|
|
str = `LOWER(${finalFieldName}) LIKE LOWER('%${valueParsed}%')`;
|
|
} 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(
|
|
`LOWER(${finalFieldName}) LIKE LOWER('%${valueParsed}%')`
|
|
);
|
|
} else {
|
|
strArray.push(`${finalFieldName} = ?`);
|
|
sqlSearhValues.push(valueParsed);
|
|
}
|
|
});
|
|
|
|
str = "(" + strArray.join(` ${queryObj.operator || "AND"} `) + ")";
|
|
}
|
|
|
|
return str;
|
|
});
|
|
|
|
function generateJoinStr(
|
|
/** @type {import("../../../types").ServerQueryParamsJoinMatchObject} */ mtch,
|
|
/** @type {import("../../../types").ServerQueryParamsJoin} */ join
|
|
) {
|
|
return `${
|
|
typeof mtch.source == "object" ? mtch.source.tableName : tableName
|
|
}.${
|
|
typeof mtch.source == "object" ? mtch.source.fieldName : mtch.source
|
|
}=${(() => {
|
|
if (mtch.targetLiteral) {
|
|
return `'${mtch.targetLiteral}'`;
|
|
}
|
|
|
|
return `${
|
|
typeof mtch.target == "object"
|
|
? mtch.target.tableName
|
|
: join.tableName
|
|
}.${
|
|
typeof mtch.target == "object"
|
|
? mtch.target.fieldName
|
|
: mtch.target
|
|
}`;
|
|
})()}`;
|
|
}
|
|
|
|
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];
|
|
|
|
str +=
|
|
"," +
|
|
genObject.join
|
|
.map((joinObj) => {
|
|
if (existingJoinTableNames.includes(joinObj.tableName))
|
|
return null;
|
|
existingJoinTableNames.push(joinObj.tableName);
|
|
|
|
if (joinObj.selectFields) {
|
|
return joinObj.selectFields
|
|
.map((slFld) => {
|
|
if (typeof slFld == "string") {
|
|
return `${joinObj.tableName}.${slFld}`;
|
|
} else if (typeof slFld == "object") {
|
|
let aliasSlctFld = `${joinObj.tableName}.${slFld.field}`;
|
|
if (slFld.alias)
|
|
aliasSlctFld += ` as ${slFld.alias}`;
|
|
return aliasSlctFld;
|
|
}
|
|
})
|
|
.join(",");
|
|
} else {
|
|
return `${joinObj.tableName}.*`;
|
|
}
|
|
})
|
|
.filter((_) => Boolean(_))
|
|
.join(",");
|
|
}
|
|
|
|
str += ` FROM ${tableName}`;
|
|
|
|
if (genObject.join) {
|
|
str +=
|
|
" " +
|
|
genObject.join
|
|
.map((join) => {
|
|
return (
|
|
join.joinType +
|
|
" " +
|
|
join.tableName +
|
|
" 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;
|
|
})();
|
|
|
|
if (sqlSearhString?.[0] && sqlSearhString.find((str) => str)) {
|
|
const stringOperator = genObject?.searchOperator || "AND";
|
|
queryString += ` WHERE ${sqlSearhString.join(` ${stringOperator} `)} `;
|
|
}
|
|
|
|
if (genObject.order)
|
|
queryString += ` ORDER BY ${
|
|
genObject.join
|
|
? `${tableName}.${genObject.order.field}`
|
|
: genObject.order.field
|
|
} ${genObject.order.strategy}`;
|
|
if (genObject.limit) queryString += ` LIMIT ${genObject.limit}`;
|
|
|
|
return {
|
|
string: queryString,
|
|
values: sqlSearhValues,
|
|
};
|
|
}
|
|
|
|
module.exports = sqlGenerator;
|