@simplysm/orm-common 13.0.69 → 13.0.70

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 (204) hide show
  1. package/README.md +54 -1447
  2. package/dist/create-db-context.d.ts +10 -10
  3. package/dist/create-db-context.js +9 -9
  4. package/dist/create-db-context.js.map +1 -1
  5. package/dist/ddl/column-ddl.d.ts +4 -4
  6. package/dist/ddl/initialize.d.ts +17 -17
  7. package/dist/ddl/initialize.js +2 -2
  8. package/dist/ddl/initialize.js.map +1 -1
  9. package/dist/ddl/relation-ddl.d.ts +6 -6
  10. package/dist/ddl/schema-ddl.d.ts +4 -4
  11. package/dist/ddl/table-ddl.d.ts +24 -24
  12. package/dist/ddl/table-ddl.js +4 -4
  13. package/dist/ddl/table-ddl.js.map +1 -1
  14. package/dist/errors/db-transaction-error.d.ts +15 -15
  15. package/dist/errors/db-transaction-error.d.ts.map +1 -1
  16. package/dist/exec/executable.d.ts +23 -23
  17. package/dist/exec/executable.js +3 -3
  18. package/dist/exec/executable.js.map +1 -1
  19. package/dist/exec/queryable.d.ts +160 -160
  20. package/dist/exec/queryable.js +119 -119
  21. package/dist/exec/queryable.js.map +1 -1
  22. package/dist/exec/search-parser.d.ts +37 -37
  23. package/dist/exec/search-parser.d.ts.map +1 -1
  24. package/dist/expr/expr-unit.d.ts +4 -4
  25. package/dist/expr/expr.d.ts +257 -257
  26. package/dist/expr/expr.js +265 -265
  27. package/dist/expr/expr.js.map +1 -1
  28. package/dist/query-builder/base/expr-renderer-base.d.ts +9 -9
  29. package/dist/query-builder/base/expr-renderer-base.js +2 -2
  30. package/dist/query-builder/base/expr-renderer-base.js.map +1 -1
  31. package/dist/query-builder/base/query-builder-base.d.ts +26 -26
  32. package/dist/query-builder/base/query-builder-base.d.ts.map +1 -1
  33. package/dist/query-builder/base/query-builder-base.js +22 -22
  34. package/dist/query-builder/base/query-builder-base.js.map +1 -1
  35. package/dist/query-builder/mssql/mssql-expr-renderer.d.ts +4 -4
  36. package/dist/query-builder/mssql/mssql-expr-renderer.d.ts.map +1 -1
  37. package/dist/query-builder/mssql/mssql-expr-renderer.js +18 -18
  38. package/dist/query-builder/mssql/mssql-expr-renderer.js.map +1 -1
  39. package/dist/query-builder/mssql/mssql-query-builder.d.ts +2 -2
  40. package/dist/query-builder/mssql/mssql-query-builder.d.ts.map +1 -1
  41. package/dist/query-builder/mssql/mssql-query-builder.js +11 -11
  42. package/dist/query-builder/mssql/mssql-query-builder.js.map +1 -1
  43. package/dist/query-builder/mysql/mysql-expr-renderer.d.ts +4 -4
  44. package/dist/query-builder/mysql/mysql-expr-renderer.d.ts.map +1 -1
  45. package/dist/query-builder/mysql/mysql-expr-renderer.js +17 -17
  46. package/dist/query-builder/mysql/mysql-expr-renderer.js.map +1 -1
  47. package/dist/query-builder/mysql/mysql-query-builder.d.ts +8 -8
  48. package/dist/query-builder/mysql/mysql-query-builder.d.ts.map +1 -1
  49. package/dist/query-builder/mysql/mysql-query-builder.js +5 -5
  50. package/dist/query-builder/mysql/mysql-query-builder.js.map +1 -1
  51. package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts +4 -4
  52. package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts.map +1 -1
  53. package/dist/query-builder/postgresql/postgresql-expr-renderer.js +17 -17
  54. package/dist/query-builder/postgresql/postgresql-expr-renderer.js.map +1 -1
  55. package/dist/query-builder/postgresql/postgresql-query-builder.d.ts +5 -5
  56. package/dist/query-builder/postgresql/postgresql-query-builder.d.ts.map +1 -1
  57. package/dist/query-builder/postgresql/postgresql-query-builder.js +8 -8
  58. package/dist/query-builder/postgresql/postgresql-query-builder.js.map +1 -1
  59. package/dist/query-builder/query-builder.d.ts +1 -1
  60. package/dist/schema/factory/column-builder.d.ts +79 -79
  61. package/dist/schema/factory/column-builder.js +42 -42
  62. package/dist/schema/factory/index-builder.d.ts +39 -39
  63. package/dist/schema/factory/index-builder.js +26 -26
  64. package/dist/schema/factory/relation-builder.d.ts +99 -99
  65. package/dist/schema/factory/relation-builder.d.ts.map +1 -1
  66. package/dist/schema/factory/relation-builder.js +38 -38
  67. package/dist/schema/procedure-builder.d.ts +49 -49
  68. package/dist/schema/procedure-builder.d.ts.map +1 -1
  69. package/dist/schema/procedure-builder.js +33 -33
  70. package/dist/schema/table-builder.d.ts +59 -59
  71. package/dist/schema/table-builder.d.ts.map +1 -1
  72. package/dist/schema/table-builder.js +43 -43
  73. package/dist/schema/view-builder.d.ts +49 -49
  74. package/dist/schema/view-builder.d.ts.map +1 -1
  75. package/dist/schema/view-builder.js +32 -32
  76. package/dist/types/column.d.ts +22 -22
  77. package/dist/types/column.js +1 -1
  78. package/dist/types/column.js.map +1 -1
  79. package/dist/types/db.d.ts +40 -40
  80. package/dist/types/expr.d.ts +59 -59
  81. package/dist/types/expr.d.ts.map +1 -1
  82. package/dist/types/query-def.d.ts +44 -44
  83. package/dist/types/query-def.d.ts.map +1 -1
  84. package/dist/utils/result-parser.d.ts +11 -11
  85. package/dist/utils/result-parser.js +3 -3
  86. package/dist/utils/result-parser.js.map +1 -1
  87. package/package.json +5 -5
  88. package/src/create-db-context.ts +20 -20
  89. package/src/ddl/column-ddl.ts +4 -4
  90. package/src/ddl/initialize.ts +259 -259
  91. package/src/ddl/relation-ddl.ts +89 -89
  92. package/src/ddl/schema-ddl.ts +4 -4
  93. package/src/ddl/table-ddl.ts +189 -189
  94. package/src/errors/db-transaction-error.ts +13 -13
  95. package/src/exec/executable.ts +25 -25
  96. package/src/exec/queryable.ts +2033 -2033
  97. package/src/exec/search-parser.ts +57 -57
  98. package/src/expr/expr-unit.ts +4 -4
  99. package/src/expr/expr.ts +2140 -2140
  100. package/src/query-builder/base/expr-renderer-base.ts +237 -237
  101. package/src/query-builder/base/query-builder-base.ts +213 -213
  102. package/src/query-builder/mssql/mssql-expr-renderer.ts +607 -607
  103. package/src/query-builder/mssql/mssql-query-builder.ts +650 -650
  104. package/src/query-builder/mysql/mysql-expr-renderer.ts +613 -613
  105. package/src/query-builder/mysql/mysql-query-builder.ts +759 -759
  106. package/src/query-builder/postgresql/postgresql-expr-renderer.ts +611 -611
  107. package/src/query-builder/postgresql/postgresql-query-builder.ts +686 -686
  108. package/src/query-builder/query-builder.ts +19 -19
  109. package/src/schema/factory/column-builder.ts +423 -423
  110. package/src/schema/factory/index-builder.ts +164 -164
  111. package/src/schema/factory/relation-builder.ts +453 -453
  112. package/src/schema/procedure-builder.ts +232 -232
  113. package/src/schema/table-builder.ts +319 -319
  114. package/src/schema/view-builder.ts +221 -221
  115. package/src/types/column.ts +188 -188
  116. package/src/types/db.ts +208 -208
  117. package/src/types/expr.ts +697 -697
  118. package/src/types/query-def.ts +513 -513
  119. package/src/utils/result-parser.ts +458 -458
  120. package/tests/db-context/create-db-context.spec.ts +224 -0
  121. package/tests/db-context/define-db-context.spec.ts +68 -0
  122. package/tests/ddl/basic.expected.ts +341 -0
  123. package/tests/ddl/basic.spec.ts +714 -0
  124. package/tests/ddl/column-builder.expected.ts +310 -0
  125. package/tests/ddl/column-builder.spec.ts +637 -0
  126. package/tests/ddl/index-builder.expected.ts +38 -0
  127. package/tests/ddl/index-builder.spec.ts +202 -0
  128. package/tests/ddl/procedure-builder.expected.ts +52 -0
  129. package/tests/ddl/procedure-builder.spec.ts +234 -0
  130. package/tests/ddl/relation-builder.expected.ts +36 -0
  131. package/tests/ddl/relation-builder.spec.ts +372 -0
  132. package/tests/ddl/table-builder.expected.ts +113 -0
  133. package/tests/ddl/table-builder.spec.ts +433 -0
  134. package/tests/ddl/view-builder.expected.ts +38 -0
  135. package/tests/ddl/view-builder.spec.ts +176 -0
  136. package/tests/dml/delete.expected.ts +96 -0
  137. package/tests/dml/delete.spec.ts +160 -0
  138. package/tests/dml/insert.expected.ts +192 -0
  139. package/tests/dml/insert.spec.ts +288 -0
  140. package/tests/dml/update.expected.ts +176 -0
  141. package/tests/dml/update.spec.ts +318 -0
  142. package/tests/dml/upsert.expected.ts +215 -0
  143. package/tests/dml/upsert.spec.ts +242 -0
  144. package/tests/errors/queryable-errors.spec.ts +177 -0
  145. package/tests/escape.spec.ts +100 -0
  146. package/tests/examples/pivot.expected.ts +211 -0
  147. package/tests/examples/pivot.spec.ts +533 -0
  148. package/tests/examples/sampling.expected.ts +69 -0
  149. package/tests/examples/sampling.spec.ts +104 -0
  150. package/tests/examples/unpivot.expected.ts +120 -0
  151. package/tests/examples/unpivot.spec.ts +226 -0
  152. package/tests/exec/search-parser.spec.ts +283 -0
  153. package/tests/executable/basic.expected.ts +18 -0
  154. package/tests/executable/basic.spec.ts +54 -0
  155. package/tests/expr/comparison.expected.ts +282 -0
  156. package/tests/expr/comparison.spec.ts +400 -0
  157. package/tests/expr/conditional.expected.ts +134 -0
  158. package/tests/expr/conditional.spec.ts +276 -0
  159. package/tests/expr/date.expected.ts +332 -0
  160. package/tests/expr/date.spec.ts +526 -0
  161. package/tests/expr/math.expected.ts +62 -0
  162. package/tests/expr/math.spec.ts +106 -0
  163. package/tests/expr/string.expected.ts +218 -0
  164. package/tests/expr/string.spec.ts +356 -0
  165. package/tests/expr/utility.expected.ts +147 -0
  166. package/tests/expr/utility.spec.ts +182 -0
  167. package/tests/select/basic.expected.ts +322 -0
  168. package/tests/select/basic.spec.ts +502 -0
  169. package/tests/select/filter.expected.ts +357 -0
  170. package/tests/select/filter.spec.ts +1068 -0
  171. package/tests/select/group.expected.ts +169 -0
  172. package/tests/select/group.spec.ts +244 -0
  173. package/tests/select/join.expected.ts +582 -0
  174. package/tests/select/join.spec.ts +805 -0
  175. package/tests/select/order.expected.ts +150 -0
  176. package/tests/select/order.spec.ts +189 -0
  177. package/tests/select/recursive-cte.expected.ts +244 -0
  178. package/tests/select/recursive-cte.spec.ts +514 -0
  179. package/tests/select/result-meta.spec.ts +270 -0
  180. package/tests/select/subquery.expected.ts +363 -0
  181. package/tests/select/subquery.spec.ts +537 -0
  182. package/tests/select/view.expected.ts +155 -0
  183. package/tests/select/view.spec.ts +235 -0
  184. package/tests/select/window.expected.ts +345 -0
  185. package/tests/select/window.spec.ts +618 -0
  186. package/tests/setup/MockExecutor.ts +18 -0
  187. package/tests/setup/TestDbContext.ts +59 -0
  188. package/tests/setup/models/Company.ts +13 -0
  189. package/tests/setup/models/Employee.ts +10 -0
  190. package/tests/setup/models/MonthlySales.ts +11 -0
  191. package/tests/setup/models/Post.ts +16 -0
  192. package/tests/setup/models/Sales.ts +10 -0
  193. package/tests/setup/models/User.ts +19 -0
  194. package/tests/setup/procedure/GetAllUsers.ts +9 -0
  195. package/tests/setup/procedure/GetUserById.ts +12 -0
  196. package/tests/setup/test-utils.ts +72 -0
  197. package/tests/setup/views/ActiveUsers.ts +8 -0
  198. package/tests/setup/views/UserSummary.ts +11 -0
  199. package/tests/types/nullable-queryable-record.spec.ts +145 -0
  200. package/tests/utils/result-parser-perf.spec.ts +210 -0
  201. package/tests/utils/result-parser.spec.ts +701 -0
  202. package/docs/expressions.md +0 -172
  203. package/docs/queries.md +0 -444
  204. package/docs/schema.md +0 -245
@@ -0,0 +1,502 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createTestDb } from "../setup/TestDbContext";
3
+ import { expr } from "../../src/expr/expr";
4
+ import { createQueryBuilder } from "../../src/query-builder/query-builder";
5
+ import { dialects } from "../setup/test-utils";
6
+ import "../setup/test-utils"; // toMatchSql matcher
7
+ import * as expected from "./basic.expected";
8
+
9
+ describe("SELECT - Basic", () => {
10
+ describe("Select from table", () => {
11
+ const db = createTestDb();
12
+ const def = db.user().getSelectQueryDef();
13
+
14
+ it("Verify QueryDef", () => {
15
+ expect(def).toEqual({
16
+ type: "select",
17
+ as: "T1",
18
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
19
+ });
20
+ });
21
+
22
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
23
+ const builder = createQueryBuilder(dialect);
24
+ expect(builder.build(def)).toMatchSql(expected.selectAll[dialect]);
25
+ });
26
+ });
27
+
28
+ describe("Select columns", () => {
29
+ const db = createTestDb();
30
+ const def = db
31
+ .user()
32
+ .select((item) => ({
33
+ id: item.id,
34
+ name: item.name,
35
+ }))
36
+ .getSelectQueryDef();
37
+
38
+ it("Verify QueryDef", () => {
39
+ expect(def).toEqual({
40
+ type: "select",
41
+ as: "T1",
42
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
43
+ select: {
44
+ id: { type: "column", path: ["T1", "id"] },
45
+ name: { type: "column", path: ["T1", "name"] },
46
+ },
47
+ });
48
+ });
49
+
50
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
51
+ const builder = createQueryBuilder(dialect);
52
+ expect(builder.build(def)).toMatchSql(expected.selectColumns[dialect]);
53
+ });
54
+ });
55
+
56
+ describe("Use expressions (concat)", () => {
57
+ const db = createTestDb();
58
+ const def = db
59
+ .user()
60
+ .select((item) => ({
61
+ email: expr.concat(item.email, "@test.com"),
62
+ }))
63
+ .getSelectQueryDef();
64
+
65
+ it("Verify QueryDef", () => {
66
+ expect(def).toEqual({
67
+ type: "select",
68
+ as: "T1",
69
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
70
+ select: {
71
+ email: {
72
+ type: "concat",
73
+ args: [
74
+ { type: "column", path: ["T1", "email"] },
75
+ { type: "value", value: "@test.com" },
76
+ ],
77
+ },
78
+ },
79
+ });
80
+ });
81
+
82
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
83
+ const builder = createQueryBuilder(dialect);
84
+ expect(builder.build(def)).toMatchSql(expected.selectConcat[dialect]);
85
+ });
86
+ });
87
+
88
+ describe("Aggregate functions", () => {
89
+ const db = createTestDb();
90
+ const def = db
91
+ .user()
92
+ .select((item) => ({
93
+ cnt: expr.count(item.id),
94
+ total: expr.sum(item.age),
95
+ avg: expr.avg(item.age),
96
+ min: expr.min(item.age),
97
+ max: expr.max(item.age),
98
+ }))
99
+ .getSelectQueryDef();
100
+
101
+ it("Verify QueryDef", () => {
102
+ expect(def).toEqual({
103
+ type: "select",
104
+ as: "T1",
105
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
106
+ select: {
107
+ cnt: { type: "count", arg: { type: "column", path: ["T1", "id"] } },
108
+ total: { type: "sum", arg: { type: "column", path: ["T1", "age"] } },
109
+ avg: { type: "avg", arg: { type: "column", path: ["T1", "age"] } },
110
+ min: { type: "min", arg: { type: "column", path: ["T1", "age"] } },
111
+ max: { type: "max", arg: { type: "column", path: ["T1", "age"] } },
112
+ },
113
+ });
114
+ });
115
+
116
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
117
+ const builder = createQueryBuilder(dialect);
118
+ expect(builder.build(def)).toMatchSql(expected.selectAggregate[dialect]);
119
+ });
120
+ });
121
+
122
+ describe("ifNull (2 arguments)", () => {
123
+ const db = createTestDb();
124
+ const def = db
125
+ .user()
126
+ .select((item) => ({
127
+ email: expr.ifNull(item.email, "N/A"),
128
+ }))
129
+ .getSelectQueryDef();
130
+
131
+ it("Verify QueryDef", () => {
132
+ expect(def).toEqual({
133
+ type: "select",
134
+ as: "T1",
135
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
136
+ select: {
137
+ email: {
138
+ type: "ifNull",
139
+ args: [
140
+ { type: "column", path: ["T1", "email"] },
141
+ { type: "value", value: "N/A" },
142
+ ],
143
+ },
144
+ },
145
+ });
146
+ });
147
+
148
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
149
+ const builder = createQueryBuilder(dialect);
150
+ expect(builder.build(def)).toMatchSql(expected.selectIfNull2[dialect]);
151
+ });
152
+ });
153
+
154
+ describe("ifNull (3 arguments, COALESCE)", () => {
155
+ const db = createTestDb();
156
+ const def = db
157
+ .user()
158
+ .select((item) => ({
159
+ contact: expr.ifNull(item.email, item.name, "N/A"),
160
+ }))
161
+ .getSelectQueryDef();
162
+
163
+ it("Verify QueryDef", () => {
164
+ expect(def).toEqual({
165
+ type: "select",
166
+ as: "T1",
167
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
168
+ select: {
169
+ contact: {
170
+ type: "ifNull",
171
+ args: [
172
+ { type: "column", path: ["T1", "email"] },
173
+ { type: "column", path: ["T1", "name"] },
174
+ { type: "value", value: "N/A" },
175
+ ],
176
+ },
177
+ },
178
+ });
179
+ });
180
+
181
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
182
+ const builder = createQueryBuilder(dialect);
183
+ expect(builder.build(def)).toMatchSql(expected.selectIfNull3[dialect]);
184
+ });
185
+ });
186
+
187
+ describe("nullIf", () => {
188
+ const db = createTestDb();
189
+ const def = db
190
+ .user()
191
+ .select((item) => ({
192
+ name: expr.nullIf(item.name, "N/A"),
193
+ }))
194
+ .getSelectQueryDef();
195
+
196
+ it("Verify QueryDef", () => {
197
+ expect(def).toEqual({
198
+ type: "select",
199
+ as: "T1",
200
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
201
+ select: {
202
+ name: {
203
+ type: "nullIf",
204
+ source: { type: "column", path: ["T1", "name"] },
205
+ value: { type: "value", value: "N/A" },
206
+ },
207
+ },
208
+ });
209
+ });
210
+
211
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
212
+ const builder = createQueryBuilder(dialect);
213
+ expect(builder.build(def)).toMatchSql(expected.selectNullIf[dialect]);
214
+ });
215
+ });
216
+
217
+ describe("substring", () => {
218
+ const db = createTestDb();
219
+ const def = db
220
+ .user()
221
+ .select((item) => ({
222
+ shortName: expr.substring(item.name, 1, 3),
223
+ }))
224
+ .getSelectQueryDef();
225
+
226
+ it("Verify QueryDef", () => {
227
+ expect(def).toEqual({
228
+ type: "select",
229
+ as: "T1",
230
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
231
+ select: {
232
+ shortName: {
233
+ type: "substring",
234
+ source: { type: "column", path: ["T1", "name"] },
235
+ start: { type: "value", value: 1 },
236
+ length: { type: "value", value: 3 },
237
+ },
238
+ },
239
+ });
240
+ });
241
+
242
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
243
+ const builder = createQueryBuilder(dialect);
244
+ expect(builder.build(def)).toMatchSql(expected.selectSubstring[dialect]);
245
+ });
246
+ });
247
+
248
+ describe("substring (length omitted)", () => {
249
+ const db = createTestDb();
250
+ const def = db
251
+ .user()
252
+ .select((item) => ({
253
+ suffix: expr.substring(item.name, 3),
254
+ }))
255
+ .getSelectQueryDef();
256
+
257
+ it("Verify QueryDef", () => {
258
+ expect(def).toEqual({
259
+ type: "select",
260
+ as: "T1",
261
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
262
+ select: {
263
+ suffix: {
264
+ type: "substring",
265
+ source: { type: "column", path: ["T1", "name"] },
266
+ start: { type: "value", value: 3 },
267
+ },
268
+ },
269
+ });
270
+ });
271
+
272
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
273
+ const builder = createQueryBuilder(dialect);
274
+ expect(builder.build(def)).toMatchSql(expected.selectSubstringNoLength[dialect]);
275
+ });
276
+ });
277
+
278
+ describe("indexOf", () => {
279
+ const db = createTestDb();
280
+ const def = db
281
+ .user()
282
+ .select((item) => ({
283
+ atPos: expr.indexOf(item.email, "@"),
284
+ }))
285
+ .getSelectQueryDef();
286
+
287
+ it("Verify QueryDef", () => {
288
+ expect(def).toEqual({
289
+ type: "select",
290
+ as: "T1",
291
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
292
+ select: {
293
+ atPos: {
294
+ type: "indexOf",
295
+ source: { type: "column", path: ["T1", "email"] },
296
+ search: { type: "value", value: "@" },
297
+ },
298
+ },
299
+ });
300
+ });
301
+
302
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
303
+ const builder = createQueryBuilder(dialect);
304
+ expect(builder.build(def)).toMatchSql(expected.selectIndexOf[dialect]);
305
+ });
306
+ });
307
+
308
+ describe("least", () => {
309
+ const db = createTestDb();
310
+ const def = db
311
+ .user()
312
+ .select((item) => ({
313
+ minAge: expr.least(item.age, 50),
314
+ }))
315
+ .getSelectQueryDef();
316
+
317
+ it("Verify QueryDef", () => {
318
+ expect(def).toEqual({
319
+ type: "select",
320
+ as: "T1",
321
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
322
+ select: {
323
+ minAge: {
324
+ type: "least",
325
+ args: [
326
+ { type: "column", path: ["T1", "age"] },
327
+ { type: "value", value: 50 },
328
+ ],
329
+ },
330
+ },
331
+ });
332
+ });
333
+
334
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
335
+ const builder = createQueryBuilder(dialect);
336
+ expect(builder.build(def)).toMatchSql(expected.selectLeast[dialect]);
337
+ });
338
+ });
339
+
340
+ describe("greatest", () => {
341
+ const db = createTestDb();
342
+ const def = db
343
+ .user()
344
+ .select((item) => ({
345
+ maxAge: expr.greatest(item.age, 18),
346
+ }))
347
+ .getSelectQueryDef();
348
+
349
+ it("Verify QueryDef", () => {
350
+ expect(def).toEqual({
351
+ type: "select",
352
+ as: "T1",
353
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
354
+ select: {
355
+ maxAge: {
356
+ type: "greatest",
357
+ args: [
358
+ { type: "column", path: ["T1", "age"] },
359
+ { type: "value", value: 18 },
360
+ ],
361
+ },
362
+ },
363
+ });
364
+ });
365
+
366
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
367
+ const builder = createQueryBuilder(dialect);
368
+ expect(builder.build(def)).toMatchSql(expected.selectGreatest[dialect]);
369
+ });
370
+ });
371
+ });
372
+
373
+ describe("SELECT - Options", () => {
374
+ describe("DISTINCT", () => {
375
+ const db = createTestDb();
376
+ const def = db.user().distinct().getSelectQueryDef();
377
+
378
+ it("Verify QueryDef", () => {
379
+ expect(def).toEqual({
380
+ type: "select",
381
+ as: "T1",
382
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
383
+ distinct: true,
384
+ });
385
+ });
386
+
387
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
388
+ const builder = createQueryBuilder(dialect);
389
+ expect(builder.build(def)).toMatchSql(expected.selectDistinct[dialect]);
390
+ });
391
+ });
392
+
393
+ describe("LOCK", () => {
394
+ const db = createTestDb();
395
+ const def = db.user().lock().getSelectQueryDef();
396
+
397
+ it("Verify QueryDef", () => {
398
+ expect(def).toEqual({
399
+ type: "select",
400
+ as: "T1",
401
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
402
+ lock: true,
403
+ });
404
+ });
405
+
406
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
407
+ const builder = createQueryBuilder(dialect);
408
+ expect(builder.build(def)).toMatchSql(expected.selectLock[dialect]);
409
+ });
410
+ });
411
+
412
+ describe("DISTINCT + LOCK combination", () => {
413
+ const db = createTestDb();
414
+ const def = db.user().distinct().lock().getSelectQueryDef();
415
+
416
+ it("Verify QueryDef", () => {
417
+ expect(def).toEqual({
418
+ type: "select",
419
+ as: "T1",
420
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
421
+ distinct: true,
422
+ lock: true,
423
+ });
424
+ });
425
+
426
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
427
+ const builder = createQueryBuilder(dialect);
428
+ expect(builder.build(def)).toMatchSql(expected.selectDistinctLock[dialect]);
429
+ });
430
+ });
431
+ });
432
+
433
+ describe("SELECT - Limit", () => {
434
+ describe("TOP", () => {
435
+ const db = createTestDb();
436
+ const def = db.user().top(10).getSelectQueryDef();
437
+
438
+ it("Verify QueryDef", () => {
439
+ expect(def).toEqual({
440
+ type: "select",
441
+ as: "T1",
442
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
443
+ top: 10,
444
+ });
445
+ });
446
+
447
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
448
+ const builder = createQueryBuilder(dialect);
449
+ expect(builder.build(def)).toMatchSql(expected.selectTop[dialect]);
450
+ });
451
+ });
452
+
453
+ describe("LIMIT", () => {
454
+ const db = createTestDb();
455
+ const def = db
456
+ .user()
457
+ .orderBy((item) => item.id)
458
+ .limit(0, 10)
459
+ .getSelectQueryDef();
460
+
461
+ it("Verify QueryDef", () => {
462
+ expect(def).toEqual({
463
+ type: "select",
464
+ as: "T1",
465
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
466
+ orderBy: [[{ type: "column", path: ["T1", "id"] }]],
467
+ limit: [0, 10],
468
+ });
469
+ });
470
+
471
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
472
+ const builder = createQueryBuilder(dialect);
473
+ expect(builder.build(def)).toMatchSql(expected.selectLimit[dialect]);
474
+ });
475
+ });
476
+
477
+ describe("LIMIT - with offset", () => {
478
+ const db = createTestDb();
479
+ const def = db
480
+ .user()
481
+ .orderBy((item) => item.id)
482
+ .limit(20, 10)
483
+ .getSelectQueryDef();
484
+
485
+ it("Verify QueryDef", () => {
486
+ expect(def).toEqual({
487
+ type: "select",
488
+ as: "T1",
489
+ from: { database: "TestDb", schema: "TestSchema", name: "User" },
490
+ orderBy: [[{ type: "column", path: ["T1", "id"] }]],
491
+ limit: [20, 10],
492
+ });
493
+ });
494
+
495
+ it.each(dialects)("[%s] Verify SQL", (dialect) => {
496
+ const builder = createQueryBuilder(dialect);
497
+ expect(builder.build(def)).toMatchSql(expected.selectLimitOffset[dialect]);
498
+ });
499
+ });
500
+
501
+ // Random sampling see examples/sampling.spec.ts
502
+ });