113 lines
4.2 KiB
JavaScript
113 lines
4.2 KiB
JavaScript
import sqlGenOperatorGen from "./sql-gen-operator-gen";
|
|
import { sqlField, sqlIdent, sqlOperator, sqlRawEquality } from "./sql-safe";
|
|
function isPresent(val) {
|
|
return val !== undefined && val !== null;
|
|
}
|
|
function isValuesObject(val) {
|
|
return typeof val == "object" && val !== null && !ArrayBuffer.isView(val);
|
|
}
|
|
export default function sqlGenGenSearchStr({ queryObj, join, field, table_name, }) {
|
|
let sqlSearhValues = [];
|
|
const safeField = sqlField(field);
|
|
const finalFieldName = (() => {
|
|
if (queryObj?.tableName) {
|
|
return `${sqlIdent(queryObj.tableName, "table name")}.${safeField}`;
|
|
}
|
|
if (join) {
|
|
return `${table_name}.${safeField}`;
|
|
}
|
|
return safeField;
|
|
})();
|
|
function grabValue(val) {
|
|
if (!isPresent(val))
|
|
return;
|
|
if (isValuesObject(val)) {
|
|
const isFieldValue = Boolean(val.fieldName && val.tableName);
|
|
return sqlGenOperatorGen({
|
|
queryObj,
|
|
equality: val.equality || queryObj.equality,
|
|
fieldName: finalFieldName,
|
|
value: isFieldValue
|
|
? `${sqlIdent(val.tableName, "table name")}.${sqlIdent(val.fieldName, "field name")}`
|
|
: val.value,
|
|
isValueFieldValue: isFieldValue,
|
|
});
|
|
}
|
|
return sqlGenOperatorGen({
|
|
queryObj,
|
|
equality: queryObj.equality,
|
|
fieldName: finalFieldName,
|
|
value: val,
|
|
});
|
|
}
|
|
let str;
|
|
if (Array.isArray(queryObj.value)) {
|
|
const items = queryObj.value.filter(isPresent);
|
|
const rawValues = items
|
|
.map((v) => (isValuesObject(v) ? v.value : v))
|
|
.filter(isPresent);
|
|
const equality = queryObj.equality;
|
|
if ((equality == "IN" || equality == "NOT IN") && !rawValues.length) {
|
|
// Empty IN () is invalid SQL: IN matches nothing, NOT IN matches everything
|
|
str = equality == "IN" ? "1 = 0" : "1 = 1";
|
|
}
|
|
else if (equality == "IN" || equality == "NOT IN") {
|
|
str = `${finalFieldName} ${equality} (${rawValues
|
|
.map(() => "?")
|
|
.join(", ")})`;
|
|
sqlSearhValues.push(...rawValues);
|
|
}
|
|
else if (equality == "BETWEEN" || equality == "NOT BETWEEN") {
|
|
if (rawValues.length !== 2) {
|
|
throw new Error(`\`${equality}\` on \`${finalFieldName}\` requires exactly two values`);
|
|
}
|
|
str = `${finalFieldName} ${equality} ? AND ?`;
|
|
sqlSearhValues.push(...rawValues);
|
|
}
|
|
else {
|
|
if (!items.length) {
|
|
throw new Error(`Empty value array for \`${finalFieldName}\``);
|
|
}
|
|
const strArray = [];
|
|
for (const val of items) {
|
|
const operatorStrParam = grabValue(val);
|
|
if (!operatorStrParam)
|
|
continue;
|
|
strArray.push(operatorStrParam.str);
|
|
sqlSearhValues.push(...operatorStrParam.params);
|
|
}
|
|
str =
|
|
"(" +
|
|
strArray.join(` ${sqlOperator(queryObj.operator)} `) +
|
|
")";
|
|
}
|
|
}
|
|
else if (queryObj.raw_equality && isPresent(queryObj.value)) {
|
|
const value = isValuesObject(queryObj.value)
|
|
? queryObj.value.value
|
|
: queryObj.value;
|
|
str = `${finalFieldName} ${sqlRawEquality(queryObj.raw_equality)} ?`;
|
|
sqlSearhValues.push(value ?? null);
|
|
}
|
|
else if (queryObj.between) {
|
|
str = `${finalFieldName} BETWEEN ? AND ?`;
|
|
sqlSearhValues.push(queryObj.between.min, queryObj.between.max);
|
|
}
|
|
else if (queryObj.not_between) {
|
|
str = `${finalFieldName} NOT BETWEEN ? AND ?`;
|
|
sqlSearhValues.push(queryObj.not_between.min, queryObj.not_between.max);
|
|
}
|
|
else {
|
|
const operatorStrParam = grabValue(queryObj.value) ||
|
|
sqlGenOperatorGen({
|
|
equality: queryObj.equality,
|
|
fieldName: finalFieldName,
|
|
value: undefined,
|
|
queryObj,
|
|
});
|
|
str = operatorStrParam.str;
|
|
sqlSearhValues.push(...operatorStrParam.params);
|
|
}
|
|
return { str, values: sqlSearhValues };
|
|
}
|