UNPKG

@jakub.knejzlik/ts-query

Version:

TypeScript implementation of SQL builder

233 lines (232 loc) 8.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OperationExpression = exports.FunctionExpression = exports.RawExpression = exports.ValueExpression = exports.Expression = exports.ExpressionBase = void 0; const Condition_1 = require("./Condition"); class ExpressionBase { static deserialize(value) { if (value instanceof Date) { return ValueExpression.deserialize(value); } const valueIsString = typeof value === "string"; if (valueIsString && RawExpression.isValueString(value)) { return RawExpression.deserialize(value); } if (valueIsString && ValueExpression.isValueString(value)) { return ValueExpression.deserialize(value); } if (valueIsString && FunctionExpression.isValidString(value)) { return FunctionExpression.deserialize(value); } if (valueIsString && OperationExpression.isValidString(value)) { return OperationExpression.deserialize(value); } if (value instanceof RawExpression) { return value; } if (valueIsString || (value instanceof Expression && typeof value.value === "string")) { const condition = Condition_1.Condition.deserialize(value instanceof Expression ? value.value : value); if (condition !== null) { return condition; } } if (valueIsString || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean") { const expr = new Expression(value); return expr; } if (value instanceof Condition_1.Condition) { return Condition_1.Condition.deserialize(value); } return value; } static deserializeValue(value) { if (value instanceof FunctionExpression) { throw new Error("FunctionExpression cannot be used as a value"); } if (value instanceof ValueExpression) { return value; } if (value instanceof RawExpression) { return value; } if (typeof value === "string" && RawExpression.isValueString(value)) { return RawExpression.deserialize(value); } return ValueExpression.deserialize(value); } static deserializeRaw(value) { return RawExpression.deserialize(value); } toSQL(_, __) { throw new Error("Method not implemented."); } serialize() { throw new Error("Method not implemented."); } } exports.ExpressionBase = ExpressionBase; class Expression extends ExpressionBase { constructor(value) { super(); this.value = value; } toSQL(flavor, options) { if (this.value instanceof Expression) { return this.value.toSQL(flavor, options); } let value = `${this.value}`; const stringMatches = value.match(/&([^#]+)&/g); if (stringMatches) { for (const match of stringMatches) { value = value.replace(match, flavor.escapeValue(match.substring(1, match.length - 1))); } } const matches = value.match(/#([^#]+)#/g); if (matches) { for (const match of matches) { value = value.replace(match, flavor.escapeColumn(match.substring(1, match.length - 1))); } } return flavor.escapeColumn(value, true); } serialize() { return `${this.value}`; } static escapeColumn(column) { return `#${column}#`; } static escapeString(column) { return `&${column}&`; } static escapeExpressionValue(column) { if (typeof column === "string" || typeof column === "number") { return this.escapeColumn(column); } if (column instanceof FunctionExpression) { throw new Error("FunctionExpression cannot be used as a value"); } if (column instanceof Expression) { return `${column.value}`; } throw new Error(`Invalid expression value: ${column}`); } } exports.Expression = Expression; class ValueExpression extends Expression { static isValueString(str) { return str.startsWith("!!!") || this.isValueDateString(str); } static isValueDateString(str) { return str.startsWith("!D!"); } toSQL(flavor, options) { if (typeof this.value === "number" || typeof this.value === "string" || typeof this.value === "bigint" || typeof this.value === "boolean" || this.value instanceof Date) { return flavor.escapeValue(this.value); } return this.value.toSQL(flavor, options); } serialize() { if (this.value instanceof Date) { return `!D!` + this.value.valueOf() + "!!"; } return `!!!` + JSON.stringify(this.value); } static deserialize(value) { const isStringValue = typeof value === "string"; if (isStringValue && ValueExpression.isValueString(value)) { if (ValueExpression.isValueDateString(value)) { return new ValueExpression(new Date(parseInt(value.substring(3, value.length - 2), 10))); } const res = new ValueExpression(JSON.parse(value.substring(3))); return res; } return new ValueExpression(value); } } exports.ValueExpression = ValueExpression; class RawExpression extends Expression { static isValueString(str) { return str.startsWith("!!") && str.endsWith("!!"); } toSQL(flavor, _) { return flavor.escapeRawValue(this.value); } serialize() { return `!!` + JSON.stringify(this.value) + "!!"; } static deserialize(value) { if (typeof value === "string" && value.startsWith("!!") && value.endsWith("!!")) { const res = new RawExpression(JSON.parse(value.substring(2, value.length - 2))); return res; } throw new Error(`Invalid raw expression: '${value}'`); } } exports.RawExpression = RawExpression; class FunctionExpression extends Expression { constructor(name, ...args) { super(args); this.name = name; } toSQL(flavor, _) { return flavor.escapeFunction(this); } static isValidString(str) { return str.startsWith("FN(") && str.endsWith(")"); } static deserialize(value) { if (typeof value === "string") { const content = value.substring(3, value.length - 1); const [name, ...args] = JSON.parse(content); return new FunctionExpression(name, ...args.map(Expression.deserialize)); } throw new Error(`Invalid function expression: '${value}'`); } serialize() { return (`FN(` + JSON.stringify([ this.name, ...this.value.map((v) => Expression.deserialize(v).serialize()), ]) + `)`); } } exports.FunctionExpression = FunctionExpression; class OperationExpression extends Expression { constructor(operation, ...args) { super(args); this.operation = operation; } toSQL(flavor, _) { return flavor.escapeOperation(this); } static isValidString(str) { return str.startsWith("OP(") && str.endsWith(")"); } static deserialize(value) { if (typeof value === "string") { const content = value.substring(3, value.length - 1); const [operation, ...args] = JSON.parse(content); return new OperationExpression(operation, ...args.map(Expression.deserialize)); } throw new Error(`Invalid function expression: '${value}'`); } serialize() { return (`OP(` + JSON.stringify([ this.operation, ...this.value.map((v) => Expression.deserialize(v).serialize()), ]) + `)`); } } exports.OperationExpression = OperationExpression;