@simplysm/orm-common 13.0.68 → 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,318 @@
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";
7
+ import * as expected from "./update.expected";
8
+
9
+ describe("UPDATE - Basic", () => {
10
+ describe("simple UPDATE", () => {
11
+ const db = createTestDb();
12
+
13
+ const def = db
14
+ .employee()
15
+ .where((e) => [expr.eq(e.id, 1)])
16
+ .getUpdateQueryDef((_e) => ({
17
+ name: expr.val("string", "new name"),
18
+ }));
19
+
20
+ it("should validate QueryDef", () => {
21
+ expect(def).toEqual({
22
+ type: "update",
23
+ table: { database: "TestDb", schema: "TestSchema", name: "Employee" },
24
+ as: "T1",
25
+ record: {
26
+ name: { type: "value", value: "new name" },
27
+ },
28
+ where: [
29
+ {
30
+ type: "eq",
31
+ source: { type: "column", path: ["T1", "id"] },
32
+ target: { type: "value", value: 1 },
33
+ },
34
+ ],
35
+ });
36
+ });
37
+
38
+ it.each(dialects)("[%s] should validate SQL", (dialect) => {
39
+ const builder = createQueryBuilder(dialect);
40
+ expect(builder.build(def)).toMatchSql(expected.updateSimple[dialect]);
41
+ });
42
+ });
43
+
44
+ describe("UPDATE multiple columns", () => {
45
+ const db = createTestDb();
46
+
47
+ const def = db
48
+ .employee()
49
+ .where((e) => [expr.eq(e.id, 1)])
50
+ .getUpdateQueryDef(() => ({
51
+ name: expr.val("string", "New Name"),
52
+ departmentId: expr.val("number", 2),
53
+ }));
54
+
55
+ it("Verify QueryDef", () => {
56
+ expect(def).toEqual({
57
+ type: "update",
58
+ table: { database: "TestDb", schema: "TestSchema", name: "Employee" },
59
+ as: "T1",
60
+ record: {
61
+ name: { type: "value", value: "New Name" },
62
+ departmentId: { type: "value", value: 2 },
63
+ },
64
+ where: [
65
+ {
66
+ type: "eq",
67
+ source: { type: "column", path: ["T1", "id"] },
68
+ target: { type: "value", value: 1 },
69
+ },
70
+ ],
71
+ });
72
+ });
73
+
74
+ it.each(dialects)("[%s] should validate SQL", (dialect) => {
75
+ const builder = createQueryBuilder(dialect);
76
+ expect(builder.build(def)).toMatchSql(expected.updateMultiCol[dialect]);
77
+ });
78
+ });
79
+
80
+ describe("UPDATE with literal values (without expr.val)", () => {
81
+ const db = createTestDb();
82
+
83
+ const def = db
84
+ .employee()
85
+ .where((e) => [expr.eq(e.id, 1)])
86
+ .getUpdateQueryDef(() => ({
87
+ name: "New Name",
88
+ departmentId: 2,
89
+ }));
90
+
91
+ it("Verify QueryDef", () => {
92
+ expect(def).toEqual({
93
+ type: "update",
94
+ table: { database: "TestDb", schema: "TestSchema", name: "Employee" },
95
+ as: "T1",
96
+ record: {
97
+ name: { type: "value", value: "New Name" },
98
+ departmentId: { type: "value", value: 2 },
99
+ },
100
+ where: [
101
+ {
102
+ type: "eq",
103
+ source: { type: "column", path: ["T1", "id"] },
104
+ target: { type: "value", value: 1 },
105
+ },
106
+ ],
107
+ });
108
+ });
109
+
110
+ it.each(dialects)("[%s] should validate SQL", (dialect) => {
111
+ const builder = createQueryBuilder(dialect);
112
+ expect(builder.build(def)).toMatchSql(expected.updatePlainValues[dialect]);
113
+ });
114
+ });
115
+
116
+ describe("UPDATE mixing literal values and expressions", () => {
117
+ const db = createTestDb();
118
+
119
+ const def = db
120
+ .employee()
121
+ .where((e) => [expr.eq(e.id, 1)])
122
+ .getUpdateQueryDef((e) => ({
123
+ name: "New Name",
124
+ managerId: expr.raw("number")`${e.managerId} + 1`,
125
+ }));
126
+
127
+ it("Verify QueryDef", () => {
128
+ expect(def).toEqual({
129
+ type: "update",
130
+ table: { database: "TestDb", schema: "TestSchema", name: "Employee" },
131
+ as: "T1",
132
+ record: {
133
+ name: { type: "value", value: "New Name" },
134
+ managerId: {
135
+ type: "raw",
136
+ sql: "$1 + 1",
137
+ params: [{ type: "column", path: ["T1", "managerId"] }],
138
+ },
139
+ },
140
+ where: [
141
+ {
142
+ type: "eq",
143
+ source: { type: "column", path: ["T1", "id"] },
144
+ target: { type: "value", value: 1 },
145
+ },
146
+ ],
147
+ });
148
+ });
149
+
150
+ it.each(dialects)("[%s] should validate SQL", (dialect) => {
151
+ const builder = createQueryBuilder(dialect);
152
+ expect(builder.build(def)).toMatchSql(expected.updateMixed[dialect]);
153
+ });
154
+ });
155
+
156
+ describe("UPDATE referencing current values (e.g., count = count + 1)", () => {
157
+ const db = createTestDb();
158
+
159
+ const def = db
160
+ .employee()
161
+ .where((e) => [expr.eq(e.id, 1)])
162
+ .getUpdateQueryDef((e) => ({
163
+ // managerId = managerId + 1 (예시)
164
+ managerId: expr.raw("number")`${e.managerId} + 1`,
165
+ }));
166
+
167
+ it("Verify QueryDef", () => {
168
+ expect(def).toEqual({
169
+ type: "update",
170
+ table: { database: "TestDb", schema: "TestSchema", name: "Employee" },
171
+ as: "T1",
172
+ record: {
173
+ managerId: {
174
+ type: "raw",
175
+ sql: "$1 + 1",
176
+ params: [{ type: "column", path: ["T1", "managerId"] }],
177
+ },
178
+ },
179
+ where: [
180
+ {
181
+ type: "eq",
182
+ source: { type: "column", path: ["T1", "id"] },
183
+ target: { type: "value", value: 1 },
184
+ },
185
+ ],
186
+ });
187
+ });
188
+
189
+ it.each(dialects)("[%s] should validate SQL", (dialect) => {
190
+ const builder = createQueryBuilder(dialect);
191
+ expect(builder.build(def)).toMatchSql(expected.updateWithRef[dialect]);
192
+ });
193
+ });
194
+
195
+ describe("Specify output column", () => {
196
+ const db = createTestDb();
197
+
198
+ const def = db
199
+ .employee()
200
+ .where((e) => [expr.eq(e.id, 1)])
201
+ .getUpdateQueryDef(
202
+ () => ({
203
+ name: expr.val("string", "New Name"),
204
+ }),
205
+ ["id", "name"],
206
+ );
207
+
208
+ it("Verify QueryDef", () => {
209
+ expect(def).toEqual({
210
+ type: "update",
211
+ table: { database: "TestDb", schema: "TestSchema", name: "Employee" },
212
+ as: "T1",
213
+ record: {
214
+ name: { type: "value", value: "New Name" },
215
+ },
216
+ where: [
217
+ {
218
+ type: "eq",
219
+ source: { type: "column", path: ["T1", "id"] },
220
+ target: { type: "value", value: 1 },
221
+ },
222
+ ],
223
+ output: {
224
+ columns: ["id", "name"],
225
+ pkColNames: ["id"],
226
+ aiColName: "id",
227
+ },
228
+ });
229
+ });
230
+
231
+ it.each(dialects)("[%s] should validate SQL", (dialect) => {
232
+ const builder = createQueryBuilder(dialect);
233
+ expect(builder.build(def)).toMatchSql(expected.updateWithOutput[dialect]);
234
+ });
235
+ });
236
+
237
+ describe("Limit update count with TOP", () => {
238
+ const db = createTestDb();
239
+
240
+ const def = db
241
+ .employee()
242
+ .where((e) => [expr.eq(e.departmentId, 1)])
243
+ .top(10)
244
+ .getUpdateQueryDef(() => ({
245
+ name: expr.val("string", "New Name"),
246
+ }));
247
+
248
+ it("Verify QueryDef", () => {
249
+ expect(def).toEqual({
250
+ type: "update",
251
+ table: { database: "TestDb", schema: "TestSchema", name: "Employee" },
252
+ as: "T1",
253
+ record: {
254
+ name: { type: "value", value: "New Name" },
255
+ },
256
+ top: 10,
257
+ where: [
258
+ {
259
+ type: "eq",
260
+ source: { type: "column", path: ["T1", "departmentId"] },
261
+ target: { type: "value", value: 1 },
262
+ },
263
+ ],
264
+ });
265
+ });
266
+
267
+ it.each(dialects)("[%s] should validate SQL", (dialect) => {
268
+ const builder = createQueryBuilder(dialect);
269
+ expect(builder.build(def)).toMatchSql(expected.updateWithTop[dialect]);
270
+ });
271
+ });
272
+ });
273
+
274
+ describe("FK switch", () => {
275
+ describe("FK off", () => {
276
+ const db = createTestDb();
277
+
278
+ const def = db.getSwitchFkQueryDef(
279
+ { database: "TestDb", schema: "TestSchema", name: "Employee" },
280
+ "off",
281
+ );
282
+
283
+ it("Verify QueryDef", () => {
284
+ expect(def).toEqual({
285
+ type: "switchFk",
286
+ table: { database: "TestDb", schema: "TestSchema", name: "Employee" },
287
+ switch: "off",
288
+ });
289
+ });
290
+
291
+ it.each(dialects)("[%s] should validate SQL", (dialect) => {
292
+ const builder = createQueryBuilder(dialect);
293
+ expect(builder.build(def)).toMatchSql(expected.fkOff[dialect]);
294
+ });
295
+ });
296
+
297
+ describe("FK on", () => {
298
+ const db = createTestDb();
299
+
300
+ const def = db.getSwitchFkQueryDef(
301
+ { database: "TestDb", schema: "TestSchema", name: "Employee" },
302
+ "on",
303
+ );
304
+
305
+ it("Verify QueryDef", () => {
306
+ expect(def).toEqual({
307
+ type: "switchFk",
308
+ table: { database: "TestDb", schema: "TestSchema", name: "Employee" },
309
+ switch: "on",
310
+ });
311
+ });
312
+
313
+ it.each(dialects)("[%s] should validate SQL", (dialect) => {
314
+ const builder = createQueryBuilder(dialect);
315
+ expect(builder.build(def)).toMatchSql(expected.fkOn[dialect]);
316
+ });
317
+ });
318
+ });
@@ -0,0 +1,215 @@
1
+ /**
2
+ * UPSERT test expected SQL
3
+ */
4
+ import { mysql, pgsql, tsql } from "@simplysm/core-common";
5
+ import type { ExpectedSql } from "../setup/test-utils";
6
+
7
+ //#region ========== UPSERT - Basic ==========
8
+
9
+ export const upsertSimple: ExpectedSql = {
10
+ mysql: mysql`
11
+ UPDATE \`TestDb\`.\`Employee\` AS \`T1\`
12
+ SET \`T1\`.\`name\` = 'new name'
13
+ WHERE \`T1\`.\`id\` <=> 1;
14
+ INSERT INTO \`TestDb\`.\`Employee\` (\`name\`, \`departmentId\`)
15
+ SELECT 'new name', 1
16
+ WHERE NOT EXISTS (SELECT * FROM \`TestDb\`.\`Employee\` AS \`T1\` WHERE \`T1\`.\`id\` <=> 1)
17
+ `,
18
+ mssql: tsql`
19
+ MERGE [TestDb].[TestSchema].[Employee] AS [T1]
20
+ USING (SELECT 1 AS [_]) AS [_src]
21
+ ON (([T1].[id] IS NULL AND 1 IS NULL) OR [T1].[id] = 1)
22
+ WHEN MATCHED THEN
23
+ UPDATE SET [name] = N'new name'
24
+ WHEN NOT MATCHED THEN
25
+ INSERT ([name], [departmentId]) VALUES (N'new name', 1);
26
+ `,
27
+ postgresql: pgsql`
28
+ WITH matched AS (
29
+ SELECT "T1".* FROM "TestSchema"."Employee" AS "T1"
30
+ WHERE "T1"."id" IS NOT DISTINCT FROM 1
31
+ ),
32
+ updated AS (
33
+ UPDATE "TestSchema"."Employee" AS "T1"
34
+ SET "name" = 'new name'
35
+ WHERE "T1"."id" IS NOT DISTINCT FROM 1
36
+ RETURNING *
37
+ ),
38
+ inserted AS (
39
+ INSERT INTO "TestSchema"."Employee" ("name", "departmentId")
40
+ SELECT 'new name', 1
41
+ WHERE NOT EXISTS (SELECT 1 FROM matched)
42
+ RETURNING *
43
+ )
44
+ SELECT * FROM updated UNION ALL SELECT * FROM inserted
45
+ `,
46
+ };
47
+
48
+ export const upsertReuse: ExpectedSql = {
49
+ mysql: mysql`
50
+ UPDATE \`TestDb\`.\`Employee\` AS \`T1\`
51
+ SET \`T1\`.\`name\` = 'Gildong Hong', \`T1\`.\`departmentId\` = 2
52
+ WHERE \`T1\`.\`id\` <=> 1;
53
+ INSERT INTO \`TestDb\`.\`Employee\` (\`name\`, \`departmentId\`, \`managerId\`)
54
+ SELECT 'Gildong Hong', 2, 100
55
+ WHERE NOT EXISTS (SELECT * FROM \`TestDb\`.\`Employee\` AS \`T1\` WHERE \`T1\`.\`id\` <=> 1)
56
+ `,
57
+ mssql: tsql`
58
+ MERGE [TestDb].[TestSchema].[Employee] AS [T1]
59
+ USING (SELECT 1 AS [_]) AS [_src]
60
+ ON (([T1].[id] IS NULL AND 1 IS NULL) OR [T1].[id] = 1)
61
+ WHEN MATCHED THEN
62
+ UPDATE SET [name] = N'Gildong Hong', [departmentId] = 2
63
+ WHEN NOT MATCHED THEN
64
+ INSERT ([name], [departmentId], [managerId]) VALUES (N'Gildong Hong', 2, 100);
65
+ `,
66
+ postgresql: pgsql`
67
+ WITH matched AS (
68
+ SELECT "T1".* FROM "TestSchema"."Employee" AS "T1"
69
+ WHERE "T1"."id" IS NOT DISTINCT FROM 1
70
+ ),
71
+ updated AS (
72
+ UPDATE "TestSchema"."Employee" AS "T1"
73
+ SET "name" = 'Gildong Hong', "departmentId" = 2
74
+ WHERE "T1"."id" IS NOT DISTINCT FROM 1
75
+ RETURNING *
76
+ ),
77
+ inserted AS (
78
+ INSERT INTO "TestSchema"."Employee" ("name", "departmentId", "managerId")
79
+ SELECT 'Gildong Hong', 2, 100
80
+ WHERE NOT EXISTS (SELECT 1 FROM matched)
81
+ RETURNING *
82
+ )
83
+ SELECT * FROM updated UNION ALL SELECT * FROM inserted
84
+ `,
85
+ };
86
+
87
+ export const upsertWithOutput: ExpectedSql = {
88
+ mysql: mysql`
89
+ CREATE TEMPORARY TABLE \`SD_TEMP\` AS SELECT \`id\` FROM \`TestDb\`.\`Employee\` AS \`T1\` WHERE \`T1\`.\`id\` <=> 1;
90
+ UPDATE \`TestDb\`.\`Employee\` AS \`T1\`
91
+ SET \`T1\`.\`name\` = 'New Name'
92
+ WHERE \`T1\`.\`id\` <=> 1;
93
+ INSERT INTO \`TestDb\`.\`Employee\` (\`name\`)
94
+ SELECT 'New Name'
95
+ WHERE NOT EXISTS (SELECT * FROM \`TestDb\`.\`Employee\` AS \`T1\` WHERE \`T1\`.\`id\` <=> 1);
96
+ SELECT \`id\`, \`name\` FROM \`TestDb\`.\`Employee\`
97
+ WHERE \`TestDb\`.\`Employee\`.\`id\` IN (SELECT \`id\` FROM \`SD_TEMP\`)
98
+ UNION ALL
99
+ SELECT \`id\`, \`name\` FROM \`TestDb\`.\`Employee\`
100
+ WHERE \`id\` = LAST_INSERT_ID() AND NOT EXISTS (SELECT 1 FROM \`SD_TEMP\`);
101
+ DROP TEMPORARY TABLE \`SD_TEMP\`
102
+ `,
103
+ mssql: tsql`
104
+ MERGE [TestDb].[TestSchema].[Employee] AS [T1]
105
+ USING (SELECT 1 AS [_]) AS [_src]
106
+ ON (([T1].[id] IS NULL AND 1 IS NULL) OR [T1].[id] = 1)
107
+ WHEN MATCHED THEN
108
+ UPDATE SET [name] = N'New Name'
109
+ WHEN NOT MATCHED THEN
110
+ INSERT ([name]) VALUES (N'New Name')
111
+ OUTPUT INSERTED.[id], INSERTED.[name];
112
+ `,
113
+ postgresql: pgsql`
114
+ WITH matched AS (
115
+ SELECT "T1".* FROM "TestSchema"."Employee" AS "T1"
116
+ WHERE "T1"."id" IS NOT DISTINCT FROM 1
117
+ ),
118
+ updated AS (
119
+ UPDATE "TestSchema"."Employee" AS "T1"
120
+ SET "name" = 'New Name'
121
+ WHERE "T1"."id" IS NOT DISTINCT FROM 1
122
+ RETURNING "id", "name"
123
+ ),
124
+ inserted AS (
125
+ INSERT INTO "TestSchema"."Employee" ("name")
126
+ SELECT 'New Name'
127
+ WHERE NOT EXISTS (SELECT 1 FROM matched)
128
+ RETURNING "id", "name"
129
+ )
130
+ SELECT * FROM updated UNION ALL SELECT * FROM inserted
131
+ `,
132
+ };
133
+
134
+ export const upsertMultiWhere: ExpectedSql = {
135
+ mysql: mysql`
136
+ UPDATE \`TestDb\`.\`Employee\` AS \`T1\`
137
+ SET \`T1\`.\`managerId\` = 10
138
+ WHERE \`T1\`.\`name\` <=> 'Gildong Hong' AND \`T1\`.\`departmentId\` <=> 1;
139
+ INSERT INTO \`TestDb\`.\`Employee\` (\`name\`, \`departmentId\`, \`managerId\`)
140
+ SELECT 'Gildong Hong', 1, 10
141
+ WHERE NOT EXISTS (SELECT * FROM \`TestDb\`.\`Employee\` AS \`T1\` WHERE \`T1\`.\`name\` <=> 'Gildong Hong' AND \`T1\`.\`departmentId\` <=> 1)
142
+ `,
143
+ mssql: tsql`
144
+ MERGE [TestDb].[TestSchema].[Employee] AS [T1]
145
+ USING (SELECT 1 AS [_]) AS [_src]
146
+ ON (([T1].[name] IS NULL AND N'Gildong Hong' IS NULL) OR [T1].[name] = N'Gildong Hong')
147
+ AND (([T1].[departmentId] IS NULL AND 1 IS NULL) OR [T1].[departmentId] = 1)
148
+ WHEN MATCHED THEN
149
+ UPDATE SET [managerId] = 10
150
+ WHEN NOT MATCHED THEN
151
+ INSERT ([name], [departmentId], [managerId]) VALUES (N'Gildong Hong', 1, 10);
152
+ `,
153
+ postgresql: pgsql`
154
+ WITH matched AS (
155
+ SELECT "T1".* FROM "TestSchema"."Employee" AS "T1"
156
+ WHERE "T1"."name" IS NOT DISTINCT FROM 'Gildong Hong'
157
+ AND "T1"."departmentId" IS NOT DISTINCT FROM 1
158
+ ),
159
+ updated AS (
160
+ UPDATE "TestSchema"."Employee" AS "T1"
161
+ SET "managerId" = 10
162
+ WHERE "T1"."name" IS NOT DISTINCT FROM 'Gildong Hong'
163
+ AND "T1"."departmentId" IS NOT DISTINCT FROM 1
164
+ RETURNING *
165
+ ),
166
+ inserted AS (
167
+ INSERT INTO "TestSchema"."Employee" ("name", "departmentId", "managerId")
168
+ SELECT 'Gildong Hong', 1, 10
169
+ WHERE NOT EXISTS (SELECT 1 FROM matched)
170
+ RETURNING *
171
+ )
172
+ SELECT * FROM updated UNION ALL SELECT * FROM inserted
173
+ `,
174
+ };
175
+
176
+ export const upsertPlainValues: ExpectedSql = {
177
+ mysql: mysql`
178
+ UPDATE \`TestDb\`.\`Employee\` AS \`T1\`
179
+ SET \`T1\`.\`name\` = 'New Name'
180
+ WHERE \`T1\`.\`id\` <=> 1;
181
+ INSERT INTO \`TestDb\`.\`Employee\` (\`name\`, \`departmentId\`)
182
+ SELECT 'New Name', 1
183
+ WHERE NOT EXISTS (SELECT * FROM \`TestDb\`.\`Employee\` AS \`T1\` WHERE \`T1\`.\`id\` <=> 1)
184
+ `,
185
+ mssql: tsql`
186
+ MERGE [TestDb].[TestSchema].[Employee] AS [T1]
187
+ USING (SELECT 1 AS [_]) AS [_src]
188
+ ON (([T1].[id] IS NULL AND 1 IS NULL) OR [T1].[id] = 1)
189
+ WHEN MATCHED THEN
190
+ UPDATE SET [name] = N'New Name'
191
+ WHEN NOT MATCHED THEN
192
+ INSERT ([name], [departmentId]) VALUES (N'New Name', 1);
193
+ `,
194
+ postgresql: pgsql`
195
+ WITH matched AS (
196
+ SELECT "T1".* FROM "TestSchema"."Employee" AS "T1"
197
+ WHERE "T1"."id" IS NOT DISTINCT FROM 1
198
+ ),
199
+ updated AS (
200
+ UPDATE "TestSchema"."Employee" AS "T1"
201
+ SET "name" = 'New Name'
202
+ WHERE "T1"."id" IS NOT DISTINCT FROM 1
203
+ RETURNING *
204
+ ),
205
+ inserted AS (
206
+ INSERT INTO "TestSchema"."Employee" ("name", "departmentId")
207
+ SELECT 'New Name', 1
208
+ WHERE NOT EXISTS (SELECT 1 FROM matched)
209
+ RETURNING *
210
+ )
211
+ SELECT * FROM updated UNION ALL SELECT * FROM inserted
212
+ `,
213
+ };
214
+
215
+ //#endregion