import type { ServerQueryParamsJoin, ServerQueryParamsJoinMatchObject, SQLInsertGenValueType, } from "../types"; import { sqlName, sqlOperator, sqlRawEquality } from "./sql-safe"; type Param = { mtch: ServerQueryParamsJoinMatchObject; join: ServerQueryParamsJoin; table_name: string; }; export default function sqlGenGenJoinStr({ join, mtch, table_name }: Param) { let values: SQLInsertGenValueType[] = []; if (mtch.__batch) { let btch_mtch = ``; btch_mtch += `(`; for (let i = 0; i < mtch.__batch.matches.length; i++) { const __mtch = mtch.__batch.matches[ i ] as ServerQueryParamsJoinMatchObject; const { str, values: batch_values } = sqlGenGenJoinStr({ join, mtch: __mtch, table_name, }); btch_mtch += str; values.push(...batch_values); if (i < mtch.__batch.matches.length - 1) { btch_mtch += ` ${sqlOperator(mtch.__batch.operator, "OR")} `; } } btch_mtch += `)`; return { str: btch_mtch, values, }; } const equality = mtch.raw_equality ? sqlRawEquality(mtch.raw_equality) : "="; // `table_name` is already validated and quoted by `sqlGenerator` const lhs = `${ typeof mtch.source == "object" ? sqlName(mtch.source.tableName, "table name") : table_name }.${sqlName( typeof mtch.source == "object" ? mtch.source.fieldName : mtch.source, "field name", )}`; if (mtch.between) { values.push(mtch.between.min, mtch.between.max); return { str: `${lhs} BETWEEN ? AND ?`, values, }; } if (mtch.not_between) { values.push(mtch.not_between.min, mtch.not_between.max); return { str: `${lhs} NOT BETWEEN ? AND ?`, values, }; } const rhs = (() => { if (mtch.targetLiteral !== undefined && mtch.targetLiteral !== null) { values.push(mtch.targetLiteral); return `?`; } const targetTable = typeof mtch.target == "object" ? mtch.target.tableName : join.alias || join.tableName; const targetField = typeof mtch.target == "object" ? mtch.target.fieldName : mtch.target; return `${sqlName(targetTable, "table name")}.${sqlName( targetField, "field name", )}`; })(); return { str: `${lhs} ${equality} ${rhs}`, values, }; }