@stamhoofd/sql 2.118.1 → 2.120.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{src/ModelCache.d.ts → ModelCache.d.ts} +1 -1
- package/dist/ModelCache.d.ts.map +1 -0
- package/{src/ModelCache.ts → dist/ModelCache.js} +8 -16
- package/dist/ModelCache.js.map +1 -0
- package/dist/{src/QueryableModel.d.ts → QueryableModel.d.ts} +7 -6
- package/dist/QueryableModel.d.ts.map +1 -0
- package/dist/{src/QueryableModel.js → QueryableModel.js} +9 -13
- package/dist/QueryableModel.js.map +1 -0
- package/dist/{src/SQL.d.ts → SQL.d.ts} +7 -5
- package/dist/SQL.d.ts.map +1 -0
- package/dist/SQL.js +100 -0
- package/dist/SQL.js.map +1 -0
- package/dist/{src/SQLDelete.d.ts → SQLDelete.d.ts} +2 -2
- package/dist/SQLDelete.d.ts.map +1 -0
- package/dist/{src/SQLDelete.js → SQLDelete.js} +8 -12
- package/dist/SQLDelete.js.map +1 -0
- package/dist/SQLExpression.d.ts.map +1 -0
- package/dist/{src/SQLExpression.js → SQLExpression.js} +3 -8
- package/dist/SQLExpression.js.map +1 -0
- package/dist/{src/SQLExpressions.d.ts → SQLExpressions.d.ts} +2 -2
- package/dist/SQLExpressions.d.ts.map +1 -0
- package/dist/{src/SQLExpressions.js → SQLExpressions.js} +78 -115
- package/dist/SQLExpressions.js.map +1 -0
- package/dist/{src/SQLInsert.d.ts → SQLInsert.d.ts} +3 -2
- package/dist/SQLInsert.d.ts.map +1 -0
- package/dist/{src/SQLInsert.js → SQLInsert.js} +17 -21
- package/dist/SQLInsert.js.map +1 -0
- package/dist/{src/SQLJoin.d.ts → SQLJoin.d.ts} +1 -1
- package/dist/SQLJoin.d.ts.map +1 -0
- package/{src/SQLJoin.ts → dist/SQLJoin.js} +15 -18
- package/dist/SQLJoin.js.map +1 -0
- package/dist/{src/SQLJsonExpressions.d.ts → SQLJsonExpressions.d.ts} +2 -2
- package/dist/SQLJsonExpressions.d.ts.map +1 -0
- package/dist/{src/SQLJsonExpressions.js → SQLJsonExpressions.js} +32 -45
- package/dist/SQLJsonExpressions.js.map +1 -0
- package/dist/SQLLogger.d.ts.map +1 -0
- package/dist/{src/SQLLogger.js → SQLLogger.js} +5 -8
- package/dist/SQLLogger.js.map +1 -0
- package/dist/{src/SQLOrderBy.d.ts → SQLOrderBy.d.ts} +1 -1
- package/dist/SQLOrderBy.d.ts.map +1 -0
- package/dist/{src/SQLOrderBy.js → SQLOrderBy.js} +8 -13
- package/dist/SQLOrderBy.js.map +1 -0
- package/dist/{src/SQLSelect.d.ts → SQLSelect.d.ts} +3 -3
- package/dist/SQLSelect.d.ts.map +1 -0
- package/dist/{src/SQLSelect.js → SQLSelect.js} +24 -29
- package/dist/SQLSelect.js.map +1 -0
- package/dist/{src/SQLTranslatedStringHelper.d.ts → SQLTranslatedStringHelper.d.ts} +3 -2
- package/dist/SQLTranslatedStringHelper.d.ts.map +1 -0
- package/dist/SQLTranslatedStringHelper.js +33 -0
- package/dist/SQLTranslatedStringHelper.js.map +1 -0
- package/dist/{src/SQLUpdate.d.ts → SQLUpdate.d.ts} +3 -2
- package/dist/SQLUpdate.d.ts.map +1 -0
- package/{src/SQLUpdate.ts → dist/SQLUpdate.js} +18 -35
- package/dist/SQLUpdate.js.map +1 -0
- package/dist/{src/SQLWhere.d.ts → SQLWhere.d.ts} +3 -3
- package/dist/SQLWhere.d.ts.map +1 -0
- package/dist/{src/SQLWhere.js → SQLWhere.js} +42 -56
- package/dist/SQLWhere.js.map +1 -0
- package/dist/{src/filters → filters}/SQLFilter.d.ts +10 -6
- package/dist/filters/SQLFilter.d.ts.map +1 -0
- package/{src/filters/SQLFilter.ts → dist/filters/SQLFilter.js} +66 -127
- package/dist/filters/SQLFilter.js.map +1 -0
- package/dist/{src/filters → filters}/SQLSorter.d.ts +6 -6
- package/dist/filters/SQLSorter.d.ts.map +1 -0
- package/dist/{src/filters → filters}/SQLSorter.js +5 -8
- package/dist/filters/SQLSorter.js.map +1 -0
- package/dist/filters/compilers/contains.d.ts +4 -0
- package/dist/filters/compilers/contains.d.ts.map +1 -0
- package/dist/filters/compilers/contains.js +26 -0
- package/dist/filters/compilers/contains.js.map +1 -0
- package/dist/filters/compilers/equals.d.ts +4 -0
- package/dist/filters/compilers/equals.d.ts.map +1 -0
- package/dist/filters/compilers/equals.js +44 -0
- package/dist/filters/compilers/equals.js.map +1 -0
- package/dist/filters/compilers/greater.d.ts +4 -0
- package/dist/filters/compilers/greater.d.ts.map +1 -0
- package/dist/filters/compilers/greater.js +15 -0
- package/dist/filters/compilers/greater.js.map +1 -0
- package/dist/filters/compilers/in.d.ts +4 -0
- package/dist/filters/compilers/in.d.ts.map +1 -0
- package/{src/filters/compilers/in.ts → dist/filters/compilers/in.js} +11 -26
- package/dist/filters/compilers/in.js.map +1 -0
- package/dist/filters/compilers/index.d.ts.map +1 -0
- package/{src/filters/compilers/index.ts → dist/filters/compilers/index.js} +1 -0
- package/dist/filters/compilers/index.js.map +1 -0
- package/dist/filters/compilers/less.d.ts +4 -0
- package/dist/filters/compilers/less.d.ts.map +1 -0
- package/dist/filters/compilers/less.js +15 -0
- package/dist/filters/compilers/less.js.map +1 -0
- package/dist/filters/helpers/isJSONColumn.d.ts +5 -0
- package/dist/filters/helpers/isJSONColumn.d.ts.map +1 -0
- package/{src/filters/helpers/isJSONColumn.ts → dist/filters/helpers/isJSONColumn.js} +5 -5
- package/dist/filters/helpers/isJSONColumn.js.map +1 -0
- package/dist/{src/filters → filters}/helpers/normalizeCompareValue.d.ts +1 -1
- package/dist/filters/helpers/normalizeCompareValue.d.ts.map +1 -0
- package/{src/filters/helpers/normalizeCompareValue.ts → dist/filters/helpers/normalizeCompareValue.js} +3 -20
- package/dist/filters/helpers/normalizeCompareValue.js.map +1 -0
- package/dist/index.d.ts +14 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -25
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/dist/src/ModelCache.d.ts.map +0 -1
- package/dist/src/ModelCache.js +0 -57
- package/dist/src/ModelCache.js.map +0 -1
- package/dist/src/QueryableModel.d.ts.map +0 -1
- package/dist/src/QueryableModel.js.map +0 -1
- package/dist/src/SQL.d.ts.map +0 -1
- package/dist/src/SQL.js +0 -103
- package/dist/src/SQL.js.map +0 -1
- package/dist/src/SQLDelete.d.ts.map +0 -1
- package/dist/src/SQLDelete.js.map +0 -1
- package/dist/src/SQLExpression.d.ts.map +0 -1
- package/dist/src/SQLExpression.js.map +0 -1
- package/dist/src/SQLExpressions.d.ts.map +0 -1
- package/dist/src/SQLExpressions.js.map +0 -1
- package/dist/src/SQLInsert.d.ts.map +0 -1
- package/dist/src/SQLInsert.js.map +0 -1
- package/dist/src/SQLJoin.d.ts.map +0 -1
- package/dist/src/SQLJoin.js +0 -61
- package/dist/src/SQLJoin.js.map +0 -1
- package/dist/src/SQLJsonExpressions.d.ts.map +0 -1
- package/dist/src/SQLJsonExpressions.js.map +0 -1
- package/dist/src/SQLLogger.d.ts.map +0 -1
- package/dist/src/SQLLogger.js.map +0 -1
- package/dist/src/SQLOrderBy.d.ts.map +0 -1
- package/dist/src/SQLOrderBy.js.map +0 -1
- package/dist/src/SQLSelect.d.ts.map +0 -1
- package/dist/src/SQLSelect.js.map +0 -1
- package/dist/src/SQLTranslatedStringHelper.d.ts.map +0 -1
- package/dist/src/SQLTranslatedStringHelper.js +0 -37
- package/dist/src/SQLTranslatedStringHelper.js.map +0 -1
- package/dist/src/SQLUpdate.d.ts.map +0 -1
- package/dist/src/SQLUpdate.js +0 -60
- package/dist/src/SQLUpdate.js.map +0 -1
- package/dist/src/SQLWhere.d.ts.map +0 -1
- package/dist/src/SQLWhere.js.map +0 -1
- package/dist/src/filters/SQLFilter.d.ts.map +0 -1
- package/dist/src/filters/SQLFilter.js +0 -216
- package/dist/src/filters/SQLFilter.js.map +0 -1
- package/dist/src/filters/SQLSorter.d.ts.map +0 -1
- package/dist/src/filters/SQLSorter.js.map +0 -1
- package/dist/src/filters/compilers/contains.d.ts +0 -4
- package/dist/src/filters/compilers/contains.d.ts.map +0 -1
- package/dist/src/filters/compilers/contains.js +0 -28
- package/dist/src/filters/compilers/contains.js.map +0 -1
- package/dist/src/filters/compilers/equals.d.ts +0 -4
- package/dist/src/filters/compilers/equals.d.ts.map +0 -1
- package/dist/src/filters/compilers/equals.js +0 -46
- package/dist/src/filters/compilers/equals.js.map +0 -1
- package/dist/src/filters/compilers/greater.d.ts +0 -4
- package/dist/src/filters/compilers/greater.d.ts.map +0 -1
- package/dist/src/filters/compilers/greater.js +0 -17
- package/dist/src/filters/compilers/greater.js.map +0 -1
- package/dist/src/filters/compilers/in.d.ts +0 -4
- package/dist/src/filters/compilers/in.d.ts.map +0 -1
- package/dist/src/filters/compilers/in.js +0 -51
- package/dist/src/filters/compilers/in.js.map +0 -1
- package/dist/src/filters/compilers/index.d.ts.map +0 -1
- package/dist/src/filters/compilers/index.js +0 -8
- package/dist/src/filters/compilers/index.js.map +0 -1
- package/dist/src/filters/compilers/less.d.ts +0 -4
- package/dist/src/filters/compilers/less.d.ts.map +0 -1
- package/dist/src/filters/compilers/less.js +0 -17
- package/dist/src/filters/compilers/less.js.map +0 -1
- package/dist/src/filters/helpers/isJSONColumn.d.ts +0 -4
- package/dist/src/filters/helpers/isJSONColumn.d.ts.map +0 -1
- package/dist/src/filters/helpers/isJSONColumn.js +0 -16
- package/dist/src/filters/helpers/isJSONColumn.js.map +0 -1
- package/dist/src/filters/helpers/normalizeCompareValue.d.ts.map +0 -1
- package/dist/src/filters/helpers/normalizeCompareValue.js +0 -87
- package/dist/src/filters/helpers/normalizeCompareValue.js.map +0 -1
- package/dist/tests/filters/$and.test.d.ts +0 -2
- package/dist/tests/filters/$and.test.d.ts.map +0 -1
- package/dist/tests/filters/$and.test.js +0 -216
- package/dist/tests/filters/$and.test.js.map +0 -1
- package/dist/tests/filters/$contains.test.d.ts +0 -2
- package/dist/tests/filters/$contains.test.d.ts.map +0 -1
- package/dist/tests/filters/$contains.test.js +0 -701
- package/dist/tests/filters/$contains.test.js.map +0 -1
- package/dist/tests/filters/$eq.test.d.ts +0 -2
- package/dist/tests/filters/$eq.test.d.ts.map +0 -1
- package/dist/tests/filters/$eq.test.js +0 -1048
- package/dist/tests/filters/$eq.test.js.map +0 -1
- package/dist/tests/filters/$gt.test.d.ts +0 -2
- package/dist/tests/filters/$gt.test.d.ts.map +0 -1
- package/dist/tests/filters/$gt.test.js +0 -463
- package/dist/tests/filters/$gt.test.js.map +0 -1
- package/dist/tests/filters/$gte.test.d.ts +0 -2
- package/dist/tests/filters/$gte.test.d.ts.map +0 -1
- package/dist/tests/filters/$gte.test.js +0 -433
- package/dist/tests/filters/$gte.test.js.map +0 -1
- package/dist/tests/filters/$in.test.d.ts +0 -2
- package/dist/tests/filters/$in.test.d.ts.map +0 -1
- package/dist/tests/filters/$in.test.js +0 -590
- package/dist/tests/filters/$in.test.js.map +0 -1
- package/dist/tests/filters/$lt.test.d.ts +0 -2
- package/dist/tests/filters/$lt.test.d.ts.map +0 -1
- package/dist/tests/filters/$lt.test.js +0 -433
- package/dist/tests/filters/$lt.test.js.map +0 -1
- package/dist/tests/filters/$lte.test.d.ts +0 -2
- package/dist/tests/filters/$lte.test.d.ts.map +0 -1
- package/dist/tests/filters/$lte.test.js +0 -472
- package/dist/tests/filters/$lte.test.js.map +0 -1
- package/dist/tests/filters/$neq.test.d.ts +0 -2
- package/dist/tests/filters/$neq.test.d.ts.map +0 -1
- package/dist/tests/filters/$neq.test.js +0 -32
- package/dist/tests/filters/$neq.test.js.map +0 -1
- package/dist/tests/filters/$not.test.d.ts +0 -2
- package/dist/tests/filters/$not.test.d.ts.map +0 -1
- package/dist/tests/filters/$not.test.js +0 -50
- package/dist/tests/filters/$not.test.js.map +0 -1
- package/dist/tests/filters/$or.test.d.ts +0 -2
- package/dist/tests/filters/$or.test.d.ts.map +0 -1
- package/dist/tests/filters/$or.test.js +0 -185
- package/dist/tests/filters/$or.test.js.map +0 -1
- package/dist/tests/filters/SQLTranslatedStringHelper.test.d.ts +0 -2
- package/dist/tests/filters/SQLTranslatedStringHelper.test.d.ts.map +0 -1
- package/dist/tests/filters/SQLTranslatedStringHelper.test.js +0 -491
- package/dist/tests/filters/SQLTranslatedStringHelper.test.js.map +0 -1
- package/dist/tests/filters/dot-syntax.test.d.ts +0 -2
- package/dist/tests/filters/dot-syntax.test.d.ts.map +0 -1
- package/dist/tests/filters/dot-syntax.test.js +0 -210
- package/dist/tests/filters/dot-syntax.test.js.map +0 -1
- package/dist/tests/filters/exists.test.d.ts +0 -2
- package/dist/tests/filters/exists.test.d.ts.map +0 -1
- package/dist/tests/filters/exists.test.js +0 -96
- package/dist/tests/filters/exists.test.js.map +0 -1
- package/dist/tests/filters/joined-relations.test.d.ts +0 -2
- package/dist/tests/filters/joined-relations.test.d.ts.map +0 -1
- package/dist/tests/filters/joined-relations.test.js +0 -167
- package/dist/tests/filters/joined-relations.test.js.map +0 -1
- package/dist/tests/filters/special-cases.test.d.ts +0 -2
- package/dist/tests/filters/special-cases.test.d.ts.map +0 -1
- package/dist/tests/filters/special-cases.test.js +0 -114
- package/dist/tests/filters/special-cases.test.js.map +0 -1
- package/dist/tests/filters/wildcard.test.d.ts +0 -2
- package/dist/tests/filters/wildcard.test.d.ts.map +0 -1
- package/dist/tests/filters/wildcard.test.js +0 -67
- package/dist/tests/filters/wildcard.test.js.map +0 -1
- package/dist/tests/jest.global.setup.d.ts +0 -3
- package/dist/tests/jest.global.setup.d.ts.map +0 -1
- package/dist/tests/jest.global.setup.js +0 -7
- package/dist/tests/jest.global.setup.js.map +0 -1
- package/dist/tests/jest.setup.d.ts +0 -2
- package/dist/tests/jest.setup.d.ts.map +0 -1
- package/dist/tests/jest.setup.js +0 -5
- package/dist/tests/jest.setup.js.map +0 -1
- package/dist/tests/utils/index.d.ts +0 -57
- package/dist/tests/utils/index.d.ts.map +0 -1
- package/dist/tests/utils/index.js +0 -206
- package/dist/tests/utils/index.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/QueryableModel.ts +0 -134
- package/src/SQL.ts +0 -128
- package/src/SQLDelete.ts +0 -73
- package/src/SQLExpression.ts +0 -34
- package/src/SQLExpressions.ts +0 -587
- package/src/SQLInsert.ts +0 -113
- package/src/SQLJsonExpressions.ts +0 -283
- package/src/SQLLogger.ts +0 -82
- package/src/SQLOrderBy.ts +0 -69
- package/src/SQLSelect.ts +0 -520
- package/src/SQLTranslatedStringHelper.ts +0 -40
- package/src/SQLWhere.ts +0 -744
- package/src/filters/SQLSorter.ts +0 -60
- package/src/filters/compilers/contains.ts +0 -43
- package/src/filters/compilers/equals.ts +0 -72
- package/src/filters/compilers/greater.ts +0 -20
- package/src/filters/compilers/less.ts +0 -19
- /package/dist/{src/SQLExpression.d.ts → SQLExpression.d.ts} +0 -0
- /package/dist/{src/SQLLogger.d.ts → SQLLogger.d.ts} +0 -0
- /package/dist/{src/filters → filters}/compilers/index.d.ts +0 -0
package/src/SQLWhere.ts
DELETED
|
@@ -1,744 +0,0 @@
|
|
|
1
|
-
import { SQLExpression, SQLExpressionOptions, SQLQuery, joinSQLQuery, normalizeSQLQuery } from './SQLExpression.js';
|
|
2
|
-
import { SQLArray, SQLColumnExpression, SQLDynamicExpression, SQLNull, readDynamicSQLExpression } from './SQLExpressions.js';
|
|
3
|
-
import { SQLJoin, SQLJoinType } from './SQLJoin.js';
|
|
4
|
-
import { SQLSelect } from './SQLSelect.js';
|
|
5
|
-
|
|
6
|
-
type Constructor<T = object> = new (...args: any[]) => T;
|
|
7
|
-
|
|
8
|
-
export enum SQLWhereSign {
|
|
9
|
-
Equal = '=',
|
|
10
|
-
Greater = '>',
|
|
11
|
-
GreaterEqual = '>=',
|
|
12
|
-
Less = '<',
|
|
13
|
-
LessEqual = '<=',
|
|
14
|
-
NotEqual = '!=',
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export const SQLWhereSignMap = {
|
|
18
|
-
'=': SQLWhereSign.Equal,
|
|
19
|
-
'>': SQLWhereSign.Greater,
|
|
20
|
-
'>=': SQLWhereSign.GreaterEqual,
|
|
21
|
-
'<': SQLWhereSign.Less,
|
|
22
|
-
'<=': SQLWhereSign.LessEqual,
|
|
23
|
-
'!=': SQLWhereSign.NotEqual,
|
|
24
|
-
} as const;
|
|
25
|
-
|
|
26
|
-
function parseWhereSign(sign: SQLWhereSign | keyof typeof SQLWhereSignMap): SQLWhereSign {
|
|
27
|
-
if (typeof sign === 'string' && Object.hasOwnProperty.call(SQLWhereSignMap, sign)) {
|
|
28
|
-
return SQLWhereSignMap[sign];
|
|
29
|
-
}
|
|
30
|
-
return sign as SQLWhereSign;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export type ParseWhereArguments = [
|
|
34
|
-
where: SQLWhere,
|
|
35
|
-
] | [
|
|
36
|
-
whereOrColumn: SQLExpression | string,
|
|
37
|
-
value: SQLDynamicExpression,
|
|
38
|
-
] | [
|
|
39
|
-
whereOrColumn: SQLExpression | string,
|
|
40
|
-
sign: SQLWhereSign | keyof typeof SQLWhereSignMap,
|
|
41
|
-
value: SQLDynamicExpression,
|
|
42
|
-
];
|
|
43
|
-
|
|
44
|
-
function assertWhereable(o: any): any {
|
|
45
|
-
return o;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function Whereable<Sup extends Constructor<object>>(Base: Sup) {
|
|
49
|
-
return class extends Base {
|
|
50
|
-
_where: SQLWhere | null = null;
|
|
51
|
-
|
|
52
|
-
get __where() {
|
|
53
|
-
return this._where ?? new SQLEmptyWhere();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
where<T>(this: T, ...args: ParseWhereArguments): T {
|
|
57
|
-
const me = assertWhereable(this);
|
|
58
|
-
me._where = me.__where.and(...args);
|
|
59
|
-
return me;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
andWhere<T>(this: T, ...args: ParseWhereArguments): T {
|
|
63
|
-
const me = assertWhereable(this);
|
|
64
|
-
me._where = me.__where.and(...args);
|
|
65
|
-
return me;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
orWhere<T>(this: T, ...args: ParseWhereArguments): T {
|
|
69
|
-
const me = assertWhereable(this);
|
|
70
|
-
me._where = me.__where.or(...args);
|
|
71
|
-
return me;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
whereNot<T>(this: T, ...args: ParseWhereArguments): T {
|
|
75
|
-
const me = assertWhereable(this);
|
|
76
|
-
me._where = me.__where.andNot(...args);
|
|
77
|
-
return me;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
andWhereNot<T>(this: T, ...args: ParseWhereArguments): T {
|
|
81
|
-
const me = assertWhereable(this);
|
|
82
|
-
me._where = me.__where.andNot(...args);
|
|
83
|
-
return me;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
orWhereNot<T>(this: T, ...args: ParseWhereArguments): T {
|
|
87
|
-
const me = assertWhereable(this);
|
|
88
|
-
me._where = me.__where.orNot(...args);
|
|
89
|
-
return me;
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export abstract class SQLWhere implements SQLExpression {
|
|
95
|
-
and(...args: ParseWhereArguments): SQLWhere {
|
|
96
|
-
return new SQLWhereAnd([this, SQLWhereEqual.parseWhere(...args)]);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
or(...args: ParseWhereArguments): SQLWhere {
|
|
100
|
-
return new SQLWhereOr([this, SQLWhereEqual.parseWhere(...args)]);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
andNot(...args: ParseWhereArguments): SQLWhere {
|
|
104
|
-
return new SQLWhereAnd([
|
|
105
|
-
this,
|
|
106
|
-
new SQLWhereNot(
|
|
107
|
-
SQLWhereEqual.parseWhere(...args),
|
|
108
|
-
),
|
|
109
|
-
]);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
orNot(...args: ParseWhereArguments): SQLWhere {
|
|
113
|
-
return new SQLWhereOr([
|
|
114
|
-
this,
|
|
115
|
-
new SQLWhereNot(
|
|
116
|
-
SQLWhereEqual.parseWhere(...args),
|
|
117
|
-
),
|
|
118
|
-
]);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
get isSingle(): boolean {
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
get isAlways(): boolean | null {
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
get isAlwaysTrue(): boolean {
|
|
130
|
-
return this.isAlways === true;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
get isAlwaysFalse(): boolean {
|
|
134
|
-
return this.isAlways === false;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
abstract getSQL(options?: SQLExpressionOptions): SQLQuery;
|
|
138
|
-
getJoins(): SQLJoin[] {
|
|
139
|
-
return [];
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
abstract clone(): this;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export class SQLEmptyWhere extends SQLWhere {
|
|
146
|
-
and(...args: ParseWhereArguments): SQLWhere {
|
|
147
|
-
return SQLWhereEqual.parseWhere(...args);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
or(...args: ParseWhereArguments): SQLWhere {
|
|
151
|
-
return SQLWhereEqual.parseWhere(...args);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
andNot(...args: ParseWhereArguments): SQLWhere {
|
|
155
|
-
return new SQLWhereNot(
|
|
156
|
-
SQLWhereEqual.parseWhere(...args),
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
orNot(...args: ParseWhereArguments): SQLWhere {
|
|
161
|
-
return new SQLWhereNot(
|
|
162
|
-
SQLWhereEqual.parseWhere(...args),
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
getSQL(options?: SQLExpressionOptions): SQLQuery {
|
|
167
|
-
throw new Error('Empty where');
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
get isAlways() {
|
|
171
|
-
return true;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
clone(): this {
|
|
175
|
-
return new SQLEmptyWhere() as this;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export class SQLWhereEqual extends SQLWhere {
|
|
180
|
-
column: SQLExpression;
|
|
181
|
-
sign = SQLWhereSign.Equal;
|
|
182
|
-
value: SQLExpression;
|
|
183
|
-
nullable = false;
|
|
184
|
-
|
|
185
|
-
static parseWhere(...parsed: ParseWhereArguments): SQLWhere {
|
|
186
|
-
if (parsed[1] === undefined) {
|
|
187
|
-
return parsed[0];
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (parsed.length === 3) {
|
|
191
|
-
return new SQLWhereEqual(
|
|
192
|
-
typeof parsed[0] === 'string' ? new SQLColumnExpression(parsed[0]) : parsed[0],
|
|
193
|
-
parseWhereSign(parsed[1]),
|
|
194
|
-
readDynamicSQLExpression(parsed[2]),
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
return new SQLWhereEqual(
|
|
198
|
-
typeof parsed[0] === 'string' ? new SQLColumnExpression(parsed[0]) : parsed[0],
|
|
199
|
-
SQLWhereSign.Equal,
|
|
200
|
-
readDynamicSQLExpression(parsed[1]),
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
constructor(column: SQLExpression, sign: SQLWhereSign, value: SQLExpression);
|
|
205
|
-
constructor(column: SQLExpression, value: SQLExpression);
|
|
206
|
-
constructor(column: SQLExpression, signOrValue: SQLExpression | SQLWhereSign, value?: SQLExpression) {
|
|
207
|
-
super();
|
|
208
|
-
this.column = column;
|
|
209
|
-
|
|
210
|
-
if (value !== undefined) {
|
|
211
|
-
this.value = value;
|
|
212
|
-
this.sign = signOrValue as SQLWhereSign;
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
this.value = signOrValue as SQLExpression;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
clone(): this {
|
|
220
|
-
const c = (new (this.constructor as any)(this.column, this.sign, this.value)) as this;
|
|
221
|
-
Object.assign(c, this);
|
|
222
|
-
return c;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
get isSingle(): boolean {
|
|
226
|
-
return this.transformed?.isSingle ?? true;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
get isAlways(): boolean | null {
|
|
230
|
-
return this.transformed?.isAlways ?? null;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
inverted(): this {
|
|
234
|
-
return this.clone().invert();
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
invert(): this {
|
|
238
|
-
switch (this.sign) {
|
|
239
|
-
case SQLWhereSign.Equal:
|
|
240
|
-
this.sign = SQLWhereSign.NotEqual;
|
|
241
|
-
break;
|
|
242
|
-
case SQLWhereSign.NotEqual:
|
|
243
|
-
this.sign = SQLWhereSign.Equal;
|
|
244
|
-
break;
|
|
245
|
-
case SQLWhereSign.Greater:
|
|
246
|
-
this.sign = SQLWhereSign.LessEqual;
|
|
247
|
-
break;
|
|
248
|
-
case SQLWhereSign.Less:
|
|
249
|
-
this.sign = SQLWhereSign.GreaterEqual;
|
|
250
|
-
break;
|
|
251
|
-
case SQLWhereSign.GreaterEqual:
|
|
252
|
-
this.sign = SQLWhereSign.Less;
|
|
253
|
-
break;
|
|
254
|
-
case SQLWhereSign.LessEqual:
|
|
255
|
-
this.sign = SQLWhereSign.Greater;
|
|
256
|
-
break;
|
|
257
|
-
}
|
|
258
|
-
return this;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
setNullable(nullable: boolean = true): this {
|
|
262
|
-
this.nullable = nullable;
|
|
263
|
-
return this;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
get transformed() {
|
|
267
|
-
if (this.value instanceof SQLNull) {
|
|
268
|
-
// We'll do some transformations to make this query work as expected.
|
|
269
|
-
// < null = always false
|
|
270
|
-
// > null = (IS NOT null)
|
|
271
|
-
// <= null = (IS null)
|
|
272
|
-
// >= null = always true
|
|
273
|
-
if (this.sign === SQLWhereSign.Less) {
|
|
274
|
-
// always false
|
|
275
|
-
return new SQLWhereOr([]);
|
|
276
|
-
}
|
|
277
|
-
if (this.sign === SQLWhereSign.Greater) {
|
|
278
|
-
// > null = (IS NOT null)
|
|
279
|
-
return new SQLWhereEqual(this.column, SQLWhereSign.NotEqual, this.value);
|
|
280
|
-
}
|
|
281
|
-
if (this.sign === SQLWhereSign.LessEqual) {
|
|
282
|
-
// (IS null)
|
|
283
|
-
return new SQLWhereEqual(this.column, SQLWhereSign.Equal, this.value);
|
|
284
|
-
}
|
|
285
|
-
if (this.sign === SQLWhereSign.GreaterEqual) {
|
|
286
|
-
// always true
|
|
287
|
-
return new SQLWhereAnd([]);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
// If the expression is nullable, we'll need to do some handling to make sure the query works as expected.
|
|
292
|
-
if (this.nullable && !(this.value instanceof SQLNull)) {
|
|
293
|
-
// <: should also include null values
|
|
294
|
-
// <=: should also include null values
|
|
295
|
-
if (this.sign === SQLWhereSign.Less || this.sign === SQLWhereSign.LessEqual) {
|
|
296
|
-
return new SQLWhereOr([
|
|
297
|
-
this.clone().setNullable(false),
|
|
298
|
-
new SQLWhereEqual(this.column, SQLWhereSign.Equal, new SQLNull()),
|
|
299
|
-
]);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
return null;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
getSQL(options?: SQLExpressionOptions): SQLQuery {
|
|
307
|
-
if (this.transformed) {
|
|
308
|
-
return this.transformed.getSQL(options);
|
|
309
|
-
}
|
|
310
|
-
if (this.value instanceof SQLArray) {
|
|
311
|
-
if (this.sign !== SQLWhereSign.Equal && this.sign !== SQLWhereSign.NotEqual) {
|
|
312
|
-
throw new Error('Unsupported sign for array: ' + this.sign);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return joinSQLQuery([
|
|
316
|
-
this.column.getSQL(options),
|
|
317
|
-
` ${(this.sign === SQLWhereSign.NotEqual) ? 'NOT IN' : 'IN'} `,
|
|
318
|
-
this.value.getSQL(options),
|
|
319
|
-
]);
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if (this.value instanceof SQLNull) {
|
|
323
|
-
if (this.sign !== SQLWhereSign.Equal && this.sign !== SQLWhereSign.NotEqual) {
|
|
324
|
-
throw new Error('Unsupported sign for NULL: ' + this.sign);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
return joinSQLQuery([
|
|
328
|
-
this.column.getSQL(options),
|
|
329
|
-
` IS ${(this.sign === SQLWhereSign.NotEqual) ? 'NOT ' : ''}`,
|
|
330
|
-
this.value.getSQL(options),
|
|
331
|
-
]);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
let sign = this.sign as string;
|
|
335
|
-
if (this.sign === SQLWhereSign.Equal && this.nullable) {
|
|
336
|
-
// Swap with null-safe equal
|
|
337
|
-
sign = '<=>';
|
|
338
|
-
}
|
|
339
|
-
else if (this.sign === SQLWhereSign.NotEqual && this.nullable) {
|
|
340
|
-
// Swap with null-safe not equal
|
|
341
|
-
return joinSQLQuery([
|
|
342
|
-
'NOT (',
|
|
343
|
-
this.column.getSQL(options),
|
|
344
|
-
` <=> `,
|
|
345
|
-
this.value.getSQL(options),
|
|
346
|
-
')',
|
|
347
|
-
]);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
return joinSQLQuery([
|
|
351
|
-
this.column.getSQL(options),
|
|
352
|
-
` ${sign} `,
|
|
353
|
-
this.value.getSQL(options),
|
|
354
|
-
]);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
export class SQLWhereLike extends SQLWhere {
|
|
359
|
-
column: SQLExpression;
|
|
360
|
-
notLike = false;
|
|
361
|
-
value: SQLExpression;
|
|
362
|
-
|
|
363
|
-
constructor(column: SQLExpression, value: SQLExpression) {
|
|
364
|
-
super();
|
|
365
|
-
this.column = column;
|
|
366
|
-
this.value = value;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
static escape(str: string) {
|
|
370
|
-
return str.replace(/([%_\\])/g, '\\$1');
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
clone(): this {
|
|
374
|
-
const c = (new (this.constructor as any)(this.column, this.value)) as this;
|
|
375
|
-
Object.assign(c, this);
|
|
376
|
-
return c;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
get isSingle(): boolean {
|
|
380
|
-
return true;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
inverted(): this {
|
|
384
|
-
return this.clone().invert();
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
invert(): this {
|
|
388
|
-
this.notLike = !this.notLike;
|
|
389
|
-
return this;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
getSQL(options?: SQLExpressionOptions): SQLQuery {
|
|
393
|
-
return joinSQLQuery([
|
|
394
|
-
this.column.getSQL(options),
|
|
395
|
-
` ${this.notLike ? 'NOT LIKE' : 'LIKE'} `,
|
|
396
|
-
this.value.getSQL(options),
|
|
397
|
-
]);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
export type SQLMatchSearchModifier = 'IN NATURAL LANGUAGE MODE' | 'IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION' | 'IN BOOLEAN MODE' | 'WITH QUERY EXPANSION';
|
|
402
|
-
|
|
403
|
-
export class SQLMatch extends SQLWhere {
|
|
404
|
-
column: SQLExpression;
|
|
405
|
-
notMatch = false;
|
|
406
|
-
value: SQLExpression;
|
|
407
|
-
searchModifier: SQLMatchSearchModifier;
|
|
408
|
-
|
|
409
|
-
constructor(column: SQLExpression, value: SQLExpression, searchModifier: SQLMatchSearchModifier = 'IN BOOLEAN MODE') {
|
|
410
|
-
super();
|
|
411
|
-
this.column = column;
|
|
412
|
-
this.value = value;
|
|
413
|
-
this.searchModifier = searchModifier;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
clone(): this {
|
|
417
|
-
const c = (new (this.constructor as any)(this.column, this.value)) as this;
|
|
418
|
-
Object.assign(c, this);
|
|
419
|
-
return c;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
get isSingle(): boolean {
|
|
423
|
-
return true;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
inverted(): this {
|
|
427
|
-
return this.clone().invert();
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
invert(): this {
|
|
431
|
-
this.notMatch = !this.notMatch;
|
|
432
|
-
return this;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
getSQL(options?: SQLExpressionOptions): SQLQuery {
|
|
436
|
-
const queries = [
|
|
437
|
-
'MATCH(',
|
|
438
|
-
this.column.getSQL(options),
|
|
439
|
-
') AGAINST(',
|
|
440
|
-
this.value.getSQL(options),
|
|
441
|
-
` ${this.searchModifier})`,
|
|
442
|
-
];
|
|
443
|
-
|
|
444
|
-
if (this.notMatch) {
|
|
445
|
-
queries.unshift('NOT ');
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
return joinSQLQuery(queries);
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
export class SQLWhereExists extends SQLWhere {
|
|
453
|
-
subquery: SQLExpression;
|
|
454
|
-
notExists = false;
|
|
455
|
-
|
|
456
|
-
constructor(subquery: SQLExpression) {
|
|
457
|
-
super();
|
|
458
|
-
this.subquery = subquery;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
clone(): this {
|
|
462
|
-
const c = (new (this.constructor as any)(this.subquery)) as this;
|
|
463
|
-
Object.assign(c, this);
|
|
464
|
-
return c;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
get isSingle(): boolean {
|
|
468
|
-
return true;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
inverted(): this {
|
|
472
|
-
return this.clone().invert();
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
invert(): this {
|
|
476
|
-
this.notExists = !this.notExists;
|
|
477
|
-
return this;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
get isAlways(): boolean | null {
|
|
481
|
-
if (this.subquery instanceof SQLSelect) {
|
|
482
|
-
const value = this.subquery.isAlways;
|
|
483
|
-
if (this.notExists) {
|
|
484
|
-
if (value === true) {
|
|
485
|
-
// If the subquery is always true, then NOT EXISTS is always false
|
|
486
|
-
return false;
|
|
487
|
-
}
|
|
488
|
-
if (value === false) {
|
|
489
|
-
// If the subquery is always false, then NOT EXISTS is always true
|
|
490
|
-
return true;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
return value;
|
|
494
|
-
}
|
|
495
|
-
return null;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
getSQL(options?: SQLExpressionOptions): SQLQuery {
|
|
499
|
-
return joinSQLQuery([
|
|
500
|
-
`${this.notExists ? 'NOT EXISTS' : 'EXISTS'} (`,
|
|
501
|
-
this.subquery.getSQL(options),
|
|
502
|
-
`)`,
|
|
503
|
-
]);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
/**
|
|
508
|
-
* Convenience helper which also caries a separate join that should be injected in the query for the where to work
|
|
509
|
-
*/
|
|
510
|
-
export class SQLWhereJoin extends SQLWhere {
|
|
511
|
-
join: SQLJoin;
|
|
512
|
-
where: SQLWhere;
|
|
513
|
-
|
|
514
|
-
/**
|
|
515
|
-
* When this is true, this means we know this relation will always exist.
|
|
516
|
-
*
|
|
517
|
-
* This information will be used to optimize the query.
|
|
518
|
-
*/
|
|
519
|
-
doesRelationAlwaysExist = false;
|
|
520
|
-
|
|
521
|
-
constructor(join: SQLJoin, where: SQLWhere, options?: { doesRelationAlwaysExist?: boolean }) {
|
|
522
|
-
super();
|
|
523
|
-
this.join = join;
|
|
524
|
-
this.where = where;
|
|
525
|
-
this.doesRelationAlwaysExist = options?.doesRelationAlwaysExist ?? false;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
get isSingle(): boolean {
|
|
529
|
-
return this.where.isSingle;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
get isAlways(): boolean | null {
|
|
533
|
-
return this.where.isAlways;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
getSQL(options?: SQLExpressionOptions): SQLQuery {
|
|
537
|
-
if (this.where.isAlways !== null && (this.doesRelationAlwaysExist || this.join.type === SQLJoinType.Left)) {
|
|
538
|
-
throw new Error('SQLWhereJoin: should not be included in query if result is determined');
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
return this.where.getSQL({
|
|
542
|
-
...options,
|
|
543
|
-
parentNamespace: options?.defaultNamespace,
|
|
544
|
-
defaultNamespace: this.join.table.getName(),
|
|
545
|
-
});
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
getJoins(): SQLJoin[] {
|
|
549
|
-
if (this.where.isAlways !== null && (this.doesRelationAlwaysExist || this.join.type === SQLJoinType.Left)) {
|
|
550
|
-
return [];
|
|
551
|
-
}
|
|
552
|
-
return [this.join, ...this.where.getJoins()];
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
clone(): this {
|
|
556
|
-
const c = (new (this.constructor as any)(this.join, this.where.clone())) as this;
|
|
557
|
-
c.doesRelationAlwaysExist = this.doesRelationAlwaysExist;
|
|
558
|
-
return c;
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
export class SQLWhereAnd extends SQLWhere {
|
|
563
|
-
children: SQLWhere[];
|
|
564
|
-
|
|
565
|
-
constructor(children: SQLWhere[]) {
|
|
566
|
-
super();
|
|
567
|
-
this.children = children;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
getSQL(options?: SQLExpressionOptions): SQLQuery {
|
|
571
|
-
if (this.isAlways === false) {
|
|
572
|
-
throw new Error('SQLWhereAnd: $and is always false and should be removed from the query');
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
return joinSQLQuery(
|
|
576
|
-
this.filteredChildren.map((c) => {
|
|
577
|
-
if (c.isSingle || this.filteredChildren.length === 1) {
|
|
578
|
-
return c.getSQL(options);
|
|
579
|
-
}
|
|
580
|
-
return joinSQLQuery(['(', c.getSQL(options), ')']);
|
|
581
|
-
}),
|
|
582
|
-
' AND ',
|
|
583
|
-
);
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
get filteredChildren(): SQLWhere[] {
|
|
587
|
-
// Children that always return true should not be included in the query (because the result only depends on the other children)
|
|
588
|
-
return this.children.filter(c => c.isAlways !== true).flatMap(c => c instanceof SQLWhereAnd ? c.filteredChildren : [c]);
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
getJoins(): SQLJoin[] {
|
|
592
|
-
return this.children.flatMap(c => c.getJoins()); // note: keep all joins
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
get isSingle(): boolean {
|
|
596
|
-
return this.filteredChildren.length === 1 && this.filteredChildren[0].isSingle;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
get isAlways(): boolean | null {
|
|
600
|
-
let allTrue = true;
|
|
601
|
-
for (const c of this.children) {
|
|
602
|
-
const v = c.isAlways;
|
|
603
|
-
if (v === false) {
|
|
604
|
-
// If any child is always false, the whole AND is false
|
|
605
|
-
return false;
|
|
606
|
-
}
|
|
607
|
-
if (v === null) {
|
|
608
|
-
allTrue = false;
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
return allTrue ? true : null;
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
inverted(): SQLWhereOr {
|
|
616
|
-
// NOT (A AND B) is the same as (NOT A OR NOT B)
|
|
617
|
-
return new SQLWhereOr(this.children.map(c => new SQLWhereNot(c)));
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
clone(): this {
|
|
621
|
-
const c = (new (this.constructor as any)(this.children.map(child => child.clone()))) as this;
|
|
622
|
-
return c;
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
export class SQLWhereOr extends SQLWhere {
|
|
627
|
-
children: SQLWhere[];
|
|
628
|
-
|
|
629
|
-
constructor(children: SQLWhere[]) {
|
|
630
|
-
super();
|
|
631
|
-
this.children = children;
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
getSQL(options?: SQLExpressionOptions): SQLQuery {
|
|
635
|
-
if (this.filteredChildren.length === 0) {
|
|
636
|
-
// Always false: throw an error (the parent should filter out this query)
|
|
637
|
-
throw new Error('SQLWhereOr: empty $or is always false and should be removed from the query');
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
return joinSQLQuery(
|
|
641
|
-
this.filteredChildren.map((c) => {
|
|
642
|
-
if (c.isSingle || this.filteredChildren.length === 1) {
|
|
643
|
-
return c.getSQL(options);
|
|
644
|
-
}
|
|
645
|
-
return joinSQLQuery(['(', c.getSQL(options), ')']);
|
|
646
|
-
}),
|
|
647
|
-
' OR ',
|
|
648
|
-
);
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
getJoins(): SQLJoin[] {
|
|
652
|
-
return this.children.flatMap(c => c.getJoins());
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
get filteredChildren(): SQLWhere[] {
|
|
656
|
-
// Children that always return false should not be included in the query (because the result only depends on the other children)
|
|
657
|
-
return this.children.filter(c => c.isAlways !== false).flatMap(c => c instanceof SQLWhereOr ? c.filteredChildren : [c]);
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
get isSingle(): boolean {
|
|
661
|
-
return this.filteredChildren.length === 1 && this.filteredChildren[0].isSingle;
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
get isAlways(): boolean | null {
|
|
665
|
-
let isAllFalse = true;
|
|
666
|
-
for (const c of this.children) {
|
|
667
|
-
const v = c.isAlways;
|
|
668
|
-
if (v === true) {
|
|
669
|
-
// If any child is always true, the whole OR is true
|
|
670
|
-
return true;
|
|
671
|
-
}
|
|
672
|
-
if (v === null) {
|
|
673
|
-
isAllFalse = false;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
return isAllFalse ? false : null;
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
inverted(): SQLWhereOr {
|
|
681
|
-
// NOT (A OR B) is the same as (NOT A AND NOT B)
|
|
682
|
-
return new SQLWhereAnd(this.children.map(c => new SQLWhereNot(c)));
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
clone(): this {
|
|
686
|
-
const c = (new (this.constructor as any)(this.children.map(child => child.clone()))) as this;
|
|
687
|
-
return c;
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
export class SQLWhereNot extends SQLWhere {
|
|
692
|
-
a: SQLWhere;
|
|
693
|
-
|
|
694
|
-
constructor(a: SQLWhere) {
|
|
695
|
-
super();
|
|
696
|
-
this.a = a;
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
get isSingle(): boolean {
|
|
700
|
-
if (this.a instanceof SQLWhereEqual || this.a instanceof SQLWhereAnd || this.a instanceof SQLWhereOr || this.a instanceof SQLWhereNot) {
|
|
701
|
-
return this.a.inverted().isSingle;
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
return this.a.isSingle;
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
getSQL(options?: SQLExpressionOptions): SQLQuery {
|
|
708
|
-
// Optimize query
|
|
709
|
-
if (this.a instanceof SQLWhereEqual || this.a instanceof SQLWhereAnd || this.a instanceof SQLWhereOr || this.a instanceof SQLWhereNot) {
|
|
710
|
-
return this.a.inverted().getSQL(options);
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
const sqlA = normalizeSQLQuery(this.a.getSQL(options));
|
|
714
|
-
|
|
715
|
-
return {
|
|
716
|
-
query: `NOT (${sqlA.query})`,
|
|
717
|
-
params: sqlA.params,
|
|
718
|
-
};
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
getJoins(): SQLJoin[] {
|
|
722
|
-
return this.a.getJoins();
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
get isAlways(): boolean | null {
|
|
726
|
-
const v = this.a.isAlways;
|
|
727
|
-
if (v === true) {
|
|
728
|
-
return false;
|
|
729
|
-
}
|
|
730
|
-
if (v === false) {
|
|
731
|
-
return true;
|
|
732
|
-
}
|
|
733
|
-
return null;
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
inverted(): SQLWhere {
|
|
737
|
-
return this.a; // NOT NOT A is just A
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
clone(): this {
|
|
741
|
-
const c = (new (this.constructor as any)(this.a.clone())) as this;
|
|
742
|
-
return c;
|
|
743
|
-
}
|
|
744
|
-
}
|