import { isUndefined } from "lodash"; import sqlGenGrabConcatStr from "./sql-generator-grab-concat-str"; import sqlGenGenJoinStr from "./sql-generator-gen-join-str"; import sqlGenGrabSelectFieldSQL from "./sql-generator-grab-select-field-sql"; import { sqlName, sqlJoinType, sqlOperator } from "./sql-safe"; export default function sqlGenGenQueryStr(params) { let str = "SELECT"; const genObject = params.genObject; const table_name = params.table_name; let sqlSearhValues = []; if (genObject?.select_sql) { str += ` ${genObject.select_sql}`; } else if (genObject?.selectFields?.[0]) { if (genObject.join) { str += sqlGenGrabSelectFieldSQL({ selectFields: genObject.selectFields, append_table_names: true, table_name, }); } else { str += sqlGenGrabSelectFieldSQL({ selectFields: genObject.selectFields, table_name, }); } } else { if (genObject?.join) { str += ` ${table_name}.*`; } else { str += " *"; } } if (genObject?.countSubQueries) { let countSqls = []; for (let i = 0; i < genObject.countSubQueries.length; i++) { const countSubQuery = genObject.countSubQueries[i]; if (!countSubQuery) continue; const countTable = sqlName(countSubQuery.table, "table name"); const tableAlias = countSubQuery.table_alias ? sqlName(countSubQuery.table_alias, "alias") : undefined; let subQStr = `(SELECT COUNT(*)`; subQStr += ` FROM ${countTable}${tableAlias ? ` ${tableAlias}` : ""}`; subQStr += ` WHERE (`; for (let j = 0; j < countSubQuery.srcTrgMap.length; j++) { const csqSrc = countSubQuery.srcTrgMap[j]; if (!csqSrc) continue; subQStr += ` ${tableAlias || countTable}.${sqlName(csqSrc.src, "field name")}`; if (typeof csqSrc.trg == "string") { subQStr += ` = ?`; sqlSearhValues.push(csqSrc.trg); } else if (typeof csqSrc.trg == "object") { subQStr += ` = ${sqlName(csqSrc.trg.table, "table name")}.${sqlName(csqSrc.trg.field, "field name")}`; } if (j < countSubQuery.srcTrgMap.length - 1) { subQStr += ` AND `; } } subQStr += ` )) AS ${sqlName(countSubQuery.alias, "alias")}`; countSqls.push(subQStr); } str += `, ${countSqls.join(",")}`; } if (genObject?.join) { const existingJoinTableNames = [table_name]; const joinSelectStr = genObject.join .flat() .filter((j) => !isUndefined(j)) .map((joinObj) => { const joinTableName = sqlName(joinObj.alias ? joinObj.alias : joinObj.tableName, "join table name"); if (existingJoinTableNames.includes(joinTableName)) return null; existingJoinTableNames.push(joinTableName); if (joinObj.group_concat) { return sqlGenGrabConcatStr({ field: `${joinTableName}.${sqlName(joinObj.group_concat.field, "field name")}`, alias: joinObj.group_concat.alias, separator: joinObj.group_concat.separator, distinct: joinObj.group_concat.distinct, }); } else if (joinObj.selectFields) { return joinObj.selectFields .map((selectField) => { if (typeof selectField != "object") { return `${joinTableName}.${sqlName(selectField, "field name")}`; } const field = `${joinTableName}.${sqlName(selectField.field, "field name")}`; if (selectField.group_concat && selectField.alias) { return sqlGenGrabConcatStr({ field, alias: selectField.alias, separator: selectField.group_concat.separator, distinct: selectField.group_concat.distinct, }); } let aliasSelectField = field; if (selectField.count) { aliasSelectField = `COUNT(${field})`; } else if (selectField.sum) { aliasSelectField = `SUM(${selectField.distinct ? "DISTINCT " : ""}${field})`; } else if (selectField.average) { aliasSelectField = `AVG(${field})`; } else if (selectField.max) { aliasSelectField = `MAX(${field})`; } else if (selectField.min) { aliasSelectField = `MIN(${field})`; } else if (selectField.distinct) { aliasSelectField = `DISTINCT ${field}`; } if (selectField.alias) aliasSelectField += ` AS ${sqlName(selectField.alias, "alias")}`; return aliasSelectField; }) .join(","); } else { return `${joinTableName}.*`; } }) .filter((_) => Boolean(_)) .join(","); if (joinSelectStr) { str += "," + joinSelectStr; } } str += ` FROM ${table_name}`; if (genObject?.join) { str += " " + genObject.join .flat() .filter((j) => !isUndefined(j)) .map((join) => { const joinTable = sqlName(join.tableName, "table name"); return (sqlJoinType(join.joinType) + " " + (join.alias ? `${joinTable} ${sqlName(join.alias, "alias")}` : joinTable) + " ON " + (() => { if (Array.isArray(join.match)) { return ("(" + join.match .map((mtch) => { const { str, values } = sqlGenGenJoinStr({ mtch, join, table_name, }); sqlSearhValues.push(...values); return str; }) .join(` ${sqlOperator(join.operator)} `) + ")"); } else if (typeof join.match == "object") { const { str, values } = sqlGenGenJoinStr({ mtch: join.match, join, table_name, }); sqlSearhValues.push(...values); return str; } })()); }) .join(" "); } return { str, values: sqlSearhValues }; }