UNPKG

@jakub.knejzlik/ts-query

Version:

TypeScript implementation of SQL builder

71 lines (61 loc) 1.97 kB
import { ExpressionBase, FunctionExpression } from "../Expression"; import { DefaultFlavor } from "./default"; export class PostgresFlavor extends DefaultFlavor { protected columnQuotes = '"'; protected stringQuotes = "'"; escapeFunction(fn: FunctionExpression): string { const args = fn.value.map((arg) => ExpressionBase.deserialize(arg).toSQL(this) ); if (fn.name === "DATEADD") { const argsValues = fn.value.map((x) => ExpressionBase.deserializeValue(x) ); const interval = parseInt(argsValues[1].value.toString(), 10); if (isNaN(interval)) { throw new Error(`Invalid DATEADD interval: ${argsValues[1].value}`); } const intervalType = argsValues[2].value.toString().toLowerCase(); const validIntervalTypes = [ "year", "month", "day", "hour", "minute", "second", "week", ]; if (!validIntervalTypes.includes(intervalType)) { throw new Error(`Invalid DATEADD interval type: ${intervalType}`); } return `(${args[0]} + INTERVAL '${interval} ${intervalType}')`; } if (fn.name === "YEAR") { return `EXTRACT(YEAR FROM ${args.join(", ")})`; } if (fn.name === "MONTH") { return `EXTRACT(MONTH FROM ${args.join(", ")})`; } if (fn.name === "IF") { const [condition, thenValue, elseValue] = args; return `CASE WHEN ${condition} THEN ${thenValue} ELSE ${elseValue} END`; } if (fn.name === "IFNULL") { return `COALESCE(${args.join(",")})`; } return super.escapeFunction(fn); } escapeLikeCondition( column: string, pattern: string, isLike: boolean, caseInsensitive: boolean ): string { const notPrefix = isLike ? "" : "NOT "; if (caseInsensitive) { // PostgreSQL: use native ILIKE return `${column} ${notPrefix}ILIKE ${pattern}`; } return `${column} ${notPrefix}LIKE ${pattern}`; } }