Skip to content

Commit

Permalink
Update dateDiff function
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubknejzlik committed Feb 15, 2024
1 parent 7b9f0e2 commit a35c54d
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 29 deletions.
24 changes: 16 additions & 8 deletions src/Expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type ExpressionValue =
| Condition;

export class ExpressionBase implements ISerializable, ISequelizable {
static deserialize(value: ExpressionValue): ExpressionBase {
static deserialize(value: ExpressionValue, exact = false): ExpressionBase {
const valueIsString = typeof value === "string";
if (valueIsString && ValueExpression.isValueString(value)) {
return ValueExpression.deserialize(value);
Expand All @@ -22,21 +22,25 @@ export class ExpressionBase implements ISerializable, ISequelizable {
if (valueIsString && OperationExpression.isValidString(value)) {
return OperationExpression.deserialize(value);
}
if (valueIsString || typeof value === "number") {
return new Expression(value);
}
if (value instanceof Condition) {
return Condition.deserialize(value);
}
if (
valueIsString ||
(value instanceof Expression && typeof value.value === "string")
) {
const condition = Condition.deserialize(value.value || value);
const condition = Condition.deserialize(
value instanceof Expression ? value.value : value
);
if (condition !== null) {
return condition;
}
}
if (valueIsString || typeof value === "number") {
const expr = new Expression(value);
expr.setExact(exact);
return expr;
}
if (value instanceof Condition) {
return Condition.deserialize(value);
}
return value;
}
static deserializeValue(value: ExpressionValue): ValueExpression {
Expand All @@ -57,6 +61,10 @@ export class Expression<T = ExpressionValue> extends ExpressionBase {
super();
}

setExact(exact: boolean): this {
return this;
}

toSQL(flavor: ISQLFlavor): string {
if (this.value instanceof Expression) {
return this.value.toSQL(flavor);
Expand Down
33 changes: 30 additions & 3 deletions src/Function.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ describe("Expression", () => {
"(`foo` * `blah`)"
);
expect(Fn.divide("foo", "blah").toSQL(flavor)).toEqual("(`foo` / `blah`)");
expect(Fn.ifnull("foo", `123`).toSQL(flavor)).toEqual("IFNULL(`foo`,123)");
expect(Fn.ifnull("foo", Q.value(123)).toSQL(flavor)).toEqual(
"IFNULL(`foo`,123)"
);
expect(Fn.ifnull("foo", Q.S`123`).toSQL(flavor)).toEqual(
'IFNULL(`foo`,"123")'
);
expect(
Fn.dateDiff("year", "2024-01-01", "2025-01-01").toSQL(flavor)
).toEqual("YEAR(`2024-01-01`) - YEAR(`2025-01-01`)");
Fn.dateDiff("year", Q.value("2024-01-01"), Q.value("2025-01-01")).toSQL(
flavor
)
).toEqual('(YEAR("2024-01-01") - YEAR("2025-01-01"))');
});
it("should support value composition", () => {
expect(Fn.sum(Fn.ifnull("foo", Q.S`123`)).toSQL(flavor)).toEqual(
Expand Down Expand Up @@ -112,4 +116,27 @@ describe("Expression", () => {
fn4.toSQL(flavor)
);
});
it("should support serialization for ifnull", () => {
const fn = Q.select().addField(
Fn.ifnull(Fn.if(Cond.equal("foo_blah", 123), "aa", Q.value(123)), "blah"),
"blah"
);
expect(fn.toSQL(flavor)).toEqual(
"SELECT IFNULL(IF(`foo_blah` = 123,`aa`,123),`blah`) AS `blah` "
);
expect(Q.deserialize(fn.serialize()).toSQL(flavor)).toEqual(
fn.toSQL(flavor)
);
});
it("datediff", () => {
expect(Fn.dateDiff("day", "a", "b").toSQL(flavor)).toEqual(
"DATEDIFF(`a`,`b`)"
);
expect(Fn.dateDiff("month", "a", "b").toSQL(flavor)).toEqual(
"TIMESTAMPDIFF(MONTH, `a`, `b`)"
);
expect(Fn.dateDiff("year", "a", "b").toSQL(flavor)).toEqual(
"(YEAR(`a`) - YEAR(`b`))"
);
});
});
24 changes: 7 additions & 17 deletions src/Function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,17 @@ export const Function = {
) => {
if (interval === "month") {
return Q.expr(
`TIMESTAMPDIFF(MONTH,${Expression.escapeExpressionValue(
`TIMESTAMPDIFF(MONTH, ${Expression.escapeExpressionValue(
date1
)}, ${Expression.escapeExpressionValue(date2)})`
);
} else if (interval === "day") {
return Q.expr(
`DATEDIFF(${Expression.escapeExpressionValue(
date1
)}, ${Expression.escapeExpressionValue(date2)})`
);
return new FunctionExpression("DATEDIFF", date1, date2);
} else {
return Q.expr(
`YEAR(${Expression.escapeExpressionValue(
date1
)}) - YEAR(${Expression.escapeExpressionValue(date2)})`
return new OperationExpression(
"-",
Function.year(date1),
Function.year(date2)
);
}
},
Expand All @@ -88,13 +84,7 @@ export const Function = {
return Q.expr(`NULL`);
},
ifnull: (name: ExpressionValue, value: ExpressionValue) => {
return Q.expr(
`IFNULL(${Expression.escapeExpressionValue(name)},${
typeof value === "string"
? value
: Expression.escapeExpressionValue(value)
})`
);
return new FunctionExpression("IFNULL", name, value);
},
concat: (...values: ExpressionValue[]) => {
return new FunctionExpression("CONCAT", ...values);
Expand Down
3 changes: 2 additions & 1 deletion src/Query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,8 @@ export const Query = {
new CreateViewAsSelect(table, select, true),
deserialize,
flavors,
expr: (val: ExpressionValue) => ExpressionBase.deserialize(val),
expr: (val: ExpressionValue, exact = false) =>
ExpressionBase.deserialize(val, exact),
exprValue: (val: ExpressionValue) => ExpressionBase.deserializeValue(val),
value: (val: ExpressionValue) => ExpressionBase.deserializeValue(val),
column: (col: ExpressionRawValue) => Expression.escapeColumn(col),
Expand Down

0 comments on commit a35c54d

Please sign in to comment.