@stamhoofd/sql 2.119.0 → 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.
Files changed (272) hide show
  1. package/dist/{src/ModelCache.d.ts → ModelCache.d.ts} +1 -1
  2. package/dist/ModelCache.d.ts.map +1 -0
  3. package/{src/ModelCache.ts → dist/ModelCache.js} +8 -16
  4. package/dist/ModelCache.js.map +1 -0
  5. package/dist/{src/QueryableModel.d.ts → QueryableModel.d.ts} +7 -6
  6. package/dist/QueryableModel.d.ts.map +1 -0
  7. package/dist/{src/QueryableModel.js → QueryableModel.js} +9 -13
  8. package/dist/QueryableModel.js.map +1 -0
  9. package/dist/{src/SQL.d.ts → SQL.d.ts} +7 -5
  10. package/dist/SQL.d.ts.map +1 -0
  11. package/dist/SQL.js +100 -0
  12. package/dist/SQL.js.map +1 -0
  13. package/dist/{src/SQLDelete.d.ts → SQLDelete.d.ts} +2 -2
  14. package/dist/SQLDelete.d.ts.map +1 -0
  15. package/dist/{src/SQLDelete.js → SQLDelete.js} +8 -12
  16. package/dist/SQLDelete.js.map +1 -0
  17. package/dist/SQLExpression.d.ts.map +1 -0
  18. package/dist/{src/SQLExpression.js → SQLExpression.js} +3 -8
  19. package/dist/SQLExpression.js.map +1 -0
  20. package/dist/{src/SQLExpressions.d.ts → SQLExpressions.d.ts} +2 -2
  21. package/dist/SQLExpressions.d.ts.map +1 -0
  22. package/dist/{src/SQLExpressions.js → SQLExpressions.js} +78 -115
  23. package/dist/SQLExpressions.js.map +1 -0
  24. package/dist/{src/SQLInsert.d.ts → SQLInsert.d.ts} +3 -2
  25. package/dist/SQLInsert.d.ts.map +1 -0
  26. package/dist/{src/SQLInsert.js → SQLInsert.js} +17 -21
  27. package/dist/SQLInsert.js.map +1 -0
  28. package/dist/{src/SQLJoin.d.ts → SQLJoin.d.ts} +1 -1
  29. package/dist/SQLJoin.d.ts.map +1 -0
  30. package/{src/SQLJoin.ts → dist/SQLJoin.js} +15 -18
  31. package/dist/SQLJoin.js.map +1 -0
  32. package/dist/{src/SQLJsonExpressions.d.ts → SQLJsonExpressions.d.ts} +2 -2
  33. package/dist/SQLJsonExpressions.d.ts.map +1 -0
  34. package/dist/{src/SQLJsonExpressions.js → SQLJsonExpressions.js} +31 -44
  35. package/dist/SQLJsonExpressions.js.map +1 -0
  36. package/dist/SQLLogger.d.ts.map +1 -0
  37. package/dist/{src/SQLLogger.js → SQLLogger.js} +5 -8
  38. package/dist/SQLLogger.js.map +1 -0
  39. package/dist/{src/SQLOrderBy.d.ts → SQLOrderBy.d.ts} +1 -1
  40. package/dist/SQLOrderBy.d.ts.map +1 -0
  41. package/dist/{src/SQLOrderBy.js → SQLOrderBy.js} +8 -13
  42. package/dist/SQLOrderBy.js.map +1 -0
  43. package/dist/{src/SQLSelect.d.ts → SQLSelect.d.ts} +3 -3
  44. package/dist/SQLSelect.d.ts.map +1 -0
  45. package/dist/{src/SQLSelect.js → SQLSelect.js} +24 -29
  46. package/dist/SQLSelect.js.map +1 -0
  47. package/dist/{src/SQLTranslatedStringHelper.d.ts → SQLTranslatedStringHelper.d.ts} +3 -2
  48. package/dist/SQLTranslatedStringHelper.d.ts.map +1 -0
  49. package/dist/SQLTranslatedStringHelper.js +33 -0
  50. package/dist/SQLTranslatedStringHelper.js.map +1 -0
  51. package/dist/{src/SQLUpdate.d.ts → SQLUpdate.d.ts} +3 -2
  52. package/dist/SQLUpdate.d.ts.map +1 -0
  53. package/{src/SQLUpdate.ts → dist/SQLUpdate.js} +18 -35
  54. package/dist/SQLUpdate.js.map +1 -0
  55. package/dist/{src/SQLWhere.d.ts → SQLWhere.d.ts} +3 -3
  56. package/dist/SQLWhere.d.ts.map +1 -0
  57. package/dist/{src/SQLWhere.js → SQLWhere.js} +42 -56
  58. package/dist/SQLWhere.js.map +1 -0
  59. package/dist/{src/filters → filters}/SQLFilter.d.ts +5 -5
  60. package/dist/filters/SQLFilter.d.ts.map +1 -0
  61. package/{src/filters/SQLFilter.ts → dist/filters/SQLFilter.js} +55 -121
  62. package/dist/filters/SQLFilter.js.map +1 -0
  63. package/dist/{src/filters → filters}/SQLSorter.d.ts +6 -6
  64. package/dist/filters/SQLSorter.d.ts.map +1 -0
  65. package/dist/{src/filters → filters}/SQLSorter.js +4 -7
  66. package/dist/filters/SQLSorter.js.map +1 -0
  67. package/dist/filters/compilers/contains.d.ts +4 -0
  68. package/dist/filters/compilers/contains.d.ts.map +1 -0
  69. package/{src/filters/compilers/contains.ts → dist/filters/compilers/contains.js} +7 -25
  70. package/dist/filters/compilers/contains.js.map +1 -0
  71. package/dist/filters/compilers/equals.d.ts +4 -0
  72. package/dist/filters/compilers/equals.d.ts.map +1 -0
  73. package/dist/filters/compilers/equals.js +44 -0
  74. package/dist/filters/compilers/equals.js.map +1 -0
  75. package/dist/filters/compilers/greater.d.ts +4 -0
  76. package/dist/filters/compilers/greater.d.ts.map +1 -0
  77. package/dist/filters/compilers/greater.js +15 -0
  78. package/dist/filters/compilers/greater.js.map +1 -0
  79. package/dist/filters/compilers/in.d.ts +4 -0
  80. package/dist/filters/compilers/in.d.ts.map +1 -0
  81. package/{src/filters/compilers/in.ts → dist/filters/compilers/in.js} +7 -21
  82. package/dist/filters/compilers/in.js.map +1 -0
  83. package/dist/filters/compilers/index.d.ts.map +1 -0
  84. package/{src/filters/compilers/index.ts → dist/filters/compilers/index.js} +1 -0
  85. package/dist/filters/compilers/index.js.map +1 -0
  86. package/dist/filters/compilers/less.d.ts +4 -0
  87. package/dist/filters/compilers/less.d.ts.map +1 -0
  88. package/dist/filters/compilers/less.js +15 -0
  89. package/dist/filters/compilers/less.js.map +1 -0
  90. package/dist/filters/helpers/isJSONColumn.d.ts +5 -0
  91. package/dist/filters/helpers/isJSONColumn.d.ts.map +1 -0
  92. package/{src/filters/helpers/isJSONColumn.ts → dist/filters/helpers/isJSONColumn.js} +4 -5
  93. package/dist/filters/helpers/isJSONColumn.js.map +1 -0
  94. package/dist/{src/filters → filters}/helpers/normalizeCompareValue.d.ts +1 -1
  95. package/dist/filters/helpers/normalizeCompareValue.d.ts.map +1 -0
  96. package/{src/filters/helpers/normalizeCompareValue.ts → dist/filters/helpers/normalizeCompareValue.js} +2 -20
  97. package/dist/filters/helpers/normalizeCompareValue.js.map +1 -0
  98. package/dist/index.d.ts +14 -14
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +14 -25
  101. package/dist/index.js.map +1 -1
  102. package/package.json +6 -6
  103. package/dist/src/ModelCache.d.ts.map +0 -1
  104. package/dist/src/ModelCache.js +0 -57
  105. package/dist/src/ModelCache.js.map +0 -1
  106. package/dist/src/QueryableModel.d.ts.map +0 -1
  107. package/dist/src/QueryableModel.js.map +0 -1
  108. package/dist/src/SQL.d.ts.map +0 -1
  109. package/dist/src/SQL.js +0 -103
  110. package/dist/src/SQL.js.map +0 -1
  111. package/dist/src/SQLDelete.d.ts.map +0 -1
  112. package/dist/src/SQLDelete.js.map +0 -1
  113. package/dist/src/SQLExpression.d.ts.map +0 -1
  114. package/dist/src/SQLExpression.js.map +0 -1
  115. package/dist/src/SQLExpressions.d.ts.map +0 -1
  116. package/dist/src/SQLExpressions.js.map +0 -1
  117. package/dist/src/SQLInsert.d.ts.map +0 -1
  118. package/dist/src/SQLInsert.js.map +0 -1
  119. package/dist/src/SQLJoin.d.ts.map +0 -1
  120. package/dist/src/SQLJoin.js +0 -61
  121. package/dist/src/SQLJoin.js.map +0 -1
  122. package/dist/src/SQLJsonExpressions.d.ts.map +0 -1
  123. package/dist/src/SQLJsonExpressions.js.map +0 -1
  124. package/dist/src/SQLLogger.d.ts.map +0 -1
  125. package/dist/src/SQLLogger.js.map +0 -1
  126. package/dist/src/SQLOrderBy.d.ts.map +0 -1
  127. package/dist/src/SQLOrderBy.js.map +0 -1
  128. package/dist/src/SQLSelect.d.ts.map +0 -1
  129. package/dist/src/SQLSelect.js.map +0 -1
  130. package/dist/src/SQLTranslatedStringHelper.d.ts.map +0 -1
  131. package/dist/src/SQLTranslatedStringHelper.js +0 -37
  132. package/dist/src/SQLTranslatedStringHelper.js.map +0 -1
  133. package/dist/src/SQLUpdate.d.ts.map +0 -1
  134. package/dist/src/SQLUpdate.js +0 -60
  135. package/dist/src/SQLUpdate.js.map +0 -1
  136. package/dist/src/SQLWhere.d.ts.map +0 -1
  137. package/dist/src/SQLWhere.js.map +0 -1
  138. package/dist/src/filters/SQLFilter.d.ts.map +0 -1
  139. package/dist/src/filters/SQLFilter.js +0 -220
  140. package/dist/src/filters/SQLFilter.js.map +0 -1
  141. package/dist/src/filters/SQLSorter.d.ts.map +0 -1
  142. package/dist/src/filters/SQLSorter.js.map +0 -1
  143. package/dist/src/filters/compilers/contains.d.ts +0 -4
  144. package/dist/src/filters/compilers/contains.d.ts.map +0 -1
  145. package/dist/src/filters/compilers/contains.js +0 -29
  146. package/dist/src/filters/compilers/contains.js.map +0 -1
  147. package/dist/src/filters/compilers/equals.d.ts +0 -4
  148. package/dist/src/filters/compilers/equals.d.ts.map +0 -1
  149. package/dist/src/filters/compilers/equals.js +0 -47
  150. package/dist/src/filters/compilers/equals.js.map +0 -1
  151. package/dist/src/filters/compilers/greater.d.ts +0 -4
  152. package/dist/src/filters/compilers/greater.d.ts.map +0 -1
  153. package/dist/src/filters/compilers/greater.js +0 -18
  154. package/dist/src/filters/compilers/greater.js.map +0 -1
  155. package/dist/src/filters/compilers/in.d.ts +0 -4
  156. package/dist/src/filters/compilers/in.d.ts.map +0 -1
  157. package/dist/src/filters/compilers/in.js +0 -51
  158. package/dist/src/filters/compilers/in.js.map +0 -1
  159. package/dist/src/filters/compilers/index.d.ts.map +0 -1
  160. package/dist/src/filters/compilers/index.js +0 -8
  161. package/dist/src/filters/compilers/index.js.map +0 -1
  162. package/dist/src/filters/compilers/less.d.ts +0 -4
  163. package/dist/src/filters/compilers/less.d.ts.map +0 -1
  164. package/dist/src/filters/compilers/less.js +0 -18
  165. package/dist/src/filters/compilers/less.js.map +0 -1
  166. package/dist/src/filters/helpers/isJSONColumn.d.ts +0 -4
  167. package/dist/src/filters/helpers/isJSONColumn.d.ts.map +0 -1
  168. package/dist/src/filters/helpers/isJSONColumn.js +0 -17
  169. package/dist/src/filters/helpers/isJSONColumn.js.map +0 -1
  170. package/dist/src/filters/helpers/normalizeCompareValue.d.ts.map +0 -1
  171. package/dist/src/filters/helpers/normalizeCompareValue.js +0 -87
  172. package/dist/src/filters/helpers/normalizeCompareValue.js.map +0 -1
  173. package/dist/tests/filters/$and.test.d.ts +0 -2
  174. package/dist/tests/filters/$and.test.d.ts.map +0 -1
  175. package/dist/tests/filters/$and.test.js +0 -216
  176. package/dist/tests/filters/$and.test.js.map +0 -1
  177. package/dist/tests/filters/$contains.test.d.ts +0 -2
  178. package/dist/tests/filters/$contains.test.d.ts.map +0 -1
  179. package/dist/tests/filters/$contains.test.js +0 -917
  180. package/dist/tests/filters/$contains.test.js.map +0 -1
  181. package/dist/tests/filters/$eq.test.d.ts +0 -2
  182. package/dist/tests/filters/$eq.test.d.ts.map +0 -1
  183. package/dist/tests/filters/$eq.test.js +0 -1464
  184. package/dist/tests/filters/$eq.test.js.map +0 -1
  185. package/dist/tests/filters/$gt.test.d.ts +0 -2
  186. package/dist/tests/filters/$gt.test.d.ts.map +0 -1
  187. package/dist/tests/filters/$gt.test.js +0 -641
  188. package/dist/tests/filters/$gt.test.js.map +0 -1
  189. package/dist/tests/filters/$gte.test.d.ts +0 -2
  190. package/dist/tests/filters/$gte.test.d.ts.map +0 -1
  191. package/dist/tests/filters/$gte.test.js +0 -433
  192. package/dist/tests/filters/$gte.test.js.map +0 -1
  193. package/dist/tests/filters/$in.test.d.ts +0 -2
  194. package/dist/tests/filters/$in.test.d.ts.map +0 -1
  195. package/dist/tests/filters/$in.test.js +0 -773
  196. package/dist/tests/filters/$in.test.js.map +0 -1
  197. package/dist/tests/filters/$lt.test.d.ts +0 -2
  198. package/dist/tests/filters/$lt.test.d.ts.map +0 -1
  199. package/dist/tests/filters/$lt.test.js +0 -433
  200. package/dist/tests/filters/$lt.test.js.map +0 -1
  201. package/dist/tests/filters/$lte.test.d.ts +0 -2
  202. package/dist/tests/filters/$lte.test.d.ts.map +0 -1
  203. package/dist/tests/filters/$lte.test.js +0 -472
  204. package/dist/tests/filters/$lte.test.js.map +0 -1
  205. package/dist/tests/filters/$neq.test.d.ts +0 -2
  206. package/dist/tests/filters/$neq.test.d.ts.map +0 -1
  207. package/dist/tests/filters/$neq.test.js +0 -32
  208. package/dist/tests/filters/$neq.test.js.map +0 -1
  209. package/dist/tests/filters/$not.test.d.ts +0 -2
  210. package/dist/tests/filters/$not.test.d.ts.map +0 -1
  211. package/dist/tests/filters/$not.test.js +0 -50
  212. package/dist/tests/filters/$not.test.js.map +0 -1
  213. package/dist/tests/filters/$or.test.d.ts +0 -2
  214. package/dist/tests/filters/$or.test.d.ts.map +0 -1
  215. package/dist/tests/filters/$or.test.js +0 -185
  216. package/dist/tests/filters/$or.test.js.map +0 -1
  217. package/dist/tests/filters/SQLTranslatedStringHelper.test.d.ts +0 -2
  218. package/dist/tests/filters/SQLTranslatedStringHelper.test.d.ts.map +0 -1
  219. package/dist/tests/filters/SQLTranslatedStringHelper.test.js +0 -491
  220. package/dist/tests/filters/SQLTranslatedStringHelper.test.js.map +0 -1
  221. package/dist/tests/filters/dot-syntax.test.d.ts +0 -2
  222. package/dist/tests/filters/dot-syntax.test.d.ts.map +0 -1
  223. package/dist/tests/filters/dot-syntax.test.js +0 -210
  224. package/dist/tests/filters/dot-syntax.test.js.map +0 -1
  225. package/dist/tests/filters/exists.test.d.ts +0 -2
  226. package/dist/tests/filters/exists.test.d.ts.map +0 -1
  227. package/dist/tests/filters/exists.test.js +0 -96
  228. package/dist/tests/filters/exists.test.js.map +0 -1
  229. package/dist/tests/filters/joined-relations.test.d.ts +0 -2
  230. package/dist/tests/filters/joined-relations.test.d.ts.map +0 -1
  231. package/dist/tests/filters/joined-relations.test.js +0 -167
  232. package/dist/tests/filters/joined-relations.test.js.map +0 -1
  233. package/dist/tests/filters/special-cases.test.d.ts +0 -2
  234. package/dist/tests/filters/special-cases.test.d.ts.map +0 -1
  235. package/dist/tests/filters/special-cases.test.js +0 -114
  236. package/dist/tests/filters/special-cases.test.js.map +0 -1
  237. package/dist/tests/filters/wildcard.test.d.ts +0 -2
  238. package/dist/tests/filters/wildcard.test.d.ts.map +0 -1
  239. package/dist/tests/filters/wildcard.test.js +0 -67
  240. package/dist/tests/filters/wildcard.test.js.map +0 -1
  241. package/dist/tests/jest.global.setup.d.ts +0 -3
  242. package/dist/tests/jest.global.setup.d.ts.map +0 -1
  243. package/dist/tests/jest.global.setup.js +0 -7
  244. package/dist/tests/jest.global.setup.js.map +0 -1
  245. package/dist/tests/jest.setup.d.ts +0 -2
  246. package/dist/tests/jest.setup.d.ts.map +0 -1
  247. package/dist/tests/jest.setup.js +0 -5
  248. package/dist/tests/jest.setup.js.map +0 -1
  249. package/dist/tests/utils/index.d.ts +0 -57
  250. package/dist/tests/utils/index.d.ts.map +0 -1
  251. package/dist/tests/utils/index.js +0 -206
  252. package/dist/tests/utils/index.js.map +0 -1
  253. package/dist/tsconfig.tsbuildinfo +0 -1
  254. package/src/QueryableModel.ts +0 -134
  255. package/src/SQL.ts +0 -128
  256. package/src/SQLDelete.ts +0 -73
  257. package/src/SQLExpression.ts +0 -34
  258. package/src/SQLExpressions.ts +0 -587
  259. package/src/SQLInsert.ts +0 -113
  260. package/src/SQLJsonExpressions.ts +0 -283
  261. package/src/SQLLogger.ts +0 -82
  262. package/src/SQLOrderBy.ts +0 -69
  263. package/src/SQLSelect.ts +0 -520
  264. package/src/SQLTranslatedStringHelper.ts +0 -40
  265. package/src/SQLWhere.ts +0 -744
  266. package/src/filters/SQLSorter.ts +0 -60
  267. package/src/filters/compilers/equals.ts +0 -73
  268. package/src/filters/compilers/greater.ts +0 -21
  269. package/src/filters/compilers/less.ts +0 -20
  270. /package/dist/{src/SQLExpression.d.ts → SQLExpression.d.ts} +0 -0
  271. /package/dist/{src/SQLLogger.d.ts → SQLLogger.d.ts} +0 -0
  272. /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
- }