@jakub.knejzlik/ts-query
Version:
TypeScript implementation of SQL builder
295 lines (294 loc) • 10.8 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.Cond = exports.Conditions = exports.Condition = void 0;
const Expression_1 = require("./Expression");
const Query_1 = require("./Query");
class Condition {
toSQL(flavor) {
throw new Error("Method not implemented.");
}
toJSON() {
throw new Error("Method not implemented.");
}
serialize() {
return JSON.stringify(this.toJSON());
}
static fromJSON(json) {
switch (json.type) {
case "BinaryCondition":
return BinaryCondition.fromJSON(json);
case "LogicalCondition":
return LogicalCondition.fromJSON(json);
case "BetweenCondition":
return BetweenCondition.fromJSON(json);
case "InCondition":
return InCondition.fromJSON(json);
case "NotInCondition":
return NotInCondition.fromJSON(json);
case "NullCondition":
return NullCondition.fromJSON(json);
case "LikeCondition":
return LikeCondition.fromJSON(json);
case "ColumnComparisonCondition":
return ColumnComparisonCondition.fromJSON(json);
default:
throw new Error(`Unknown condition type: ${json.type} (${JSON.stringify(json)})`);
}
}
static deserialize(value) {
if (typeof value === "string") {
try {
return Condition.fromJSON(JSON.parse(value));
}
catch (_a) {
return null;
}
}
return value;
}
}
exports.Condition = Condition;
class BinaryCondition extends Condition {
constructor(key, value, operator) {
super();
this.key = Query_1.Q.expr(key);
this.value = Query_1.Q.value(value);
this.operator = operator;
}
toSQL(flavor) {
return `${this.key.toSQL(flavor)} ${this.operator} ${this.value.toSQL(flavor)}`;
}
// serialization
toJSON() {
return {
type: "BinaryCondition",
key: this.key.serialize(),
value: this.value.serialize(),
operator: this.operator,
};
}
static fromJSON(json) {
return new BinaryCondition(Expression_1.ExpressionBase.deserialize(json.key), Expression_1.ExpressionBase.deserializeValue(json.value), json.operator);
}
}
class LogicalCondition extends Condition {
constructor(conditions, operator) {
super();
this.conditions = conditions;
this.operator = operator;
}
toSQL(flavor) {
return `(${this.conditions
.map((c) => c.toSQL(flavor))
.join(` ${this.operator} `)})`;
}
// serialization
toJSON() {
return {
type: "LogicalCondition",
conditions: this.conditions.map((condition) => condition.toJSON()),
operator: this.operator,
};
}
static fromJSON(json) {
const conditions = json.conditions.map(Condition.fromJSON);
return new LogicalCondition(conditions, json.operator);
}
}
class BetweenCondition extends Condition {
constructor(key, from, to) {
super();
this.key = Query_1.Q.expr(key);
this.from = Query_1.Q.expr(from);
this.to = Query_1.Q.expr(to);
}
toSQL(flavor) {
return `${this.key.toSQL(flavor)} BETWEEN ${this.from.toSQL(flavor)} AND ${this.to.toSQL(flavor)}`;
}
// serialization
toJSON() {
return {
type: "BetweenCondition",
key: this.key.serialize(),
from: this.from.serialize(),
to: this.to.serialize(),
};
}
static fromJSON(json) {
return new BetweenCondition(Expression_1.ExpressionBase.deserialize(json.key), Expression_1.ExpressionBase.deserializeValue(json.from), Expression_1.ExpressionBase.deserializeValue(json.to));
}
}
class InCondition extends Condition {
constructor(key, values) {
super();
this.key = Query_1.Q.expr(key);
this.values = values.map((v) => Query_1.Q.exprValue(v));
}
toSQL(flavor) {
return `${this.key.toSQL(flavor)} IN (${this.values
.map((v) => v.toSQL(flavor))
.join(", ")})`;
}
// serialization
toJSON() {
return {
type: "InCondition",
key: this.key.serialize(),
values: this.values.map((v) => v.serialize()),
};
}
static fromJSON(json) {
return new InCondition(Expression_1.ExpressionBase.deserialize(json.key), json.values.map(Expression_1.ExpressionBase.deserializeValue));
}
}
class NotInCondition extends Condition {
constructor(key, values) {
super();
this.key = Query_1.Q.expr(key);
this.values = values.map((v) => Query_1.Q.expr(v));
}
toSQL(flavor) {
return `${this.key.toSQL(flavor)} NOT IN (${this.values
.map((v) => v.toSQL(flavor))
.join(", ")})`;
}
// serialization
toJSON() {
return {
type: "NotInCondition",
key: this.key.serialize(),
values: this.values.map((v) => v.serialize()),
};
}
static fromJSON(json) {
return new NotInCondition(Expression_1.ExpressionBase.deserialize(json.key), json.values.map(Expression_1.ExpressionBase.deserializeValue));
}
}
class NullCondition extends Condition {
constructor(key, isNull) {
super();
this.key = Query_1.Q.expr(key);
this.isNull = isNull;
}
toSQL(flavor) {
return `${this.key.toSQL(flavor)} IS ${this.isNull ? "" : "NOT "}NULL`;
}
// serialization
toJSON() {
return {
type: "NullCondition",
key: this.key.serialize(),
isNull: this.isNull,
};
}
static fromJSON(json) {
return new NullCondition(Expression_1.ExpressionBase.deserialize(json.key), json.isNull);
}
}
class LikeCondition extends Condition {
constructor(key, pattern, isLike) {
super();
this.key = Query_1.Q.expr(key);
this.pattern = pattern;
this.isLike = isLike;
}
toSQL(flavor) {
return `${this.key.toSQL(flavor)} ${this.isLike ? "" : "NOT "}LIKE \'${this.pattern}\'`;
}
// serialization
toJSON() {
return {
type: "LikeCondition",
key: this.key.serialize(),
pattern: this.pattern,
isLike: this.isLike,
};
}
static fromJSON(json) {
return new LikeCondition(Expression_1.ExpressionBase.deserialize(json.key), json.pattern, json.isLike);
}
}
class ColumnComparisonCondition extends Condition {
constructor(leftKey, rightKey, operator) {
super();
this.leftKey = Query_1.Q.expr(leftKey);
this.rightKey = Query_1.Q.expr(rightKey);
this.operator = operator;
}
toSQL(flavor) {
return `${this.leftKey.toSQL(flavor)} ${this.operator} ${this.rightKey.toSQL(flavor)}`;
}
// serialization
toJSON() {
return {
type: "ColumnComparisonCondition",
leftKey: this.leftKey.serialize(),
rightKey: this.rightKey.serialize(),
operator: this.operator,
};
}
static fromJSON(json) {
return new ColumnComparisonCondition(Expression_1.ExpressionBase.deserialize(json.leftKey), Expression_1.ExpressionBase.deserialize(json.rightKey), json.operator);
}
}
exports.Conditions = {
fromString: (column, value) => {
const str = `${value}`;
if (str.indexOf(">=") === 0) {
return exports.Conditions.greaterThanOrEqual(column, str.substring(2));
}
if (str.indexOf("<=") === 0) {
return exports.Conditions.lessThanOrEqual(column, str.substring(2));
}
if (str.indexOf(">") === 0) {
return exports.Conditions.greaterThan(column, str.substring(1));
}
if (str.indexOf("<") === 0) {
return exports.Conditions.lessThan(column, str.substring(1));
}
if (str.indexOf("~") === 0) {
return exports.Conditions.or([
exports.Conditions.like(column, `${str.substring(1)}%`),
exports.Conditions.like(column, `% ${str.substring(1)}%`),
]);
}
if (str.indexOf("!~") === 0) {
return exports.Conditions.and([
exports.Conditions.notLike(column, `${str.substring(2)}%`),
exports.Conditions.notLike(column, `% ${str.substring(2)}%`),
]);
}
if (str.indexOf("!") === 0) {
return exports.Conditions.notEqual(column, `${str.substring(1)}%`);
}
return exports.Conditions.equal(column, str);
},
equal: (key, value) => new BinaryCondition(key, value, "="),
notEqual: (key, value) => new BinaryCondition(key, value, "!="),
greaterThan: (key, value) => new BinaryCondition(key, value, ">"),
lessThan: (key, value) => new BinaryCondition(key, value, "<"),
greaterThanOrEqual: (key, value) => new BinaryCondition(key, value, ">="),
lessThanOrEqual: (key, value) => new BinaryCondition(key, value, "<="),
between: (key, values) => new BetweenCondition(key, Query_1.Q.exprValue(values[0]), Query_1.Q.exprValue(values[1])),
in: (key, values) => values && values.length > 0 ? new InCondition(key, values) : null,
notIn: (key, values) => new NotInCondition(key, values),
and: (conditions) => {
const _c = (conditions || []).filter((c) => c !== null);
return _c.length > 0 ? new LogicalCondition(_c, "AND") : null;
},
or: (conditions) => {
const _c = (conditions || []).filter((c) => c !== null);
return _c.length > 0 ? new LogicalCondition(_c, "OR") : null;
},
null: (key) => new NullCondition(key, true),
notNull: (key) => new NullCondition(key, false),
like: (key, pattern) => new LikeCondition(key, pattern, true),
notLike: (key, pattern) => new LikeCondition(key, pattern, false),
columnEqual: (leftKey, rightKey) => new ColumnComparisonCondition(leftKey, rightKey, "="),
columnNotEqual: (leftKey, rightKey) => new ColumnComparisonCondition(leftKey, rightKey, "!="),
columnGreaterThan: (leftKey, rightKey) => new ColumnComparisonCondition(leftKey, rightKey, ">"),
columnLessThan: (leftKey, rightKey) => new ColumnComparisonCondition(leftKey, rightKey, "<"),
columnGreaterThanOrEqual: (leftKey, rightKey) => new ColumnComparisonCondition(leftKey, rightKey, ">="),
columnLessThanOrEqual: (leftKey, rightKey) => new ColumnComparisonCondition(leftKey, rightKey, "<="),
};
exports.Cond = exports.Conditions;
;