@fragno-dev/db 0.1.13 → 0.1.15
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/.turbo/turbo-build.log +179 -132
- package/CHANGELOG.md +30 -0
- package/dist/adapters/adapters.d.ts +27 -1
- package/dist/adapters/adapters.d.ts.map +1 -1
- package/dist/adapters/adapters.js.map +1 -1
- package/dist/adapters/drizzle/drizzle-adapter.d.ts +5 -1
- package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
- package/dist/adapters/drizzle/drizzle-adapter.js +15 -3
- package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
- package/dist/adapters/drizzle/drizzle-query.js +7 -5
- package/dist/adapters/drizzle/drizzle-query.js.map +1 -1
- package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -1
- package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +1 -1
- package/dist/adapters/drizzle/drizzle-uow-compiler.js +76 -44
- package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +1 -1
- package/dist/adapters/drizzle/drizzle-uow-decoder.js +23 -16
- package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +1 -1
- package/dist/adapters/drizzle/drizzle-uow-executor.js +18 -7
- package/dist/adapters/drizzle/drizzle-uow-executor.js.map +1 -1
- package/dist/adapters/drizzle/generate.d.ts +4 -1
- package/dist/adapters/drizzle/generate.d.ts.map +1 -1
- package/dist/adapters/drizzle/generate.js +11 -18
- package/dist/adapters/drizzle/generate.js.map +1 -1
- package/dist/adapters/drizzle/shared.d.ts +14 -1
- package/dist/adapters/drizzle/shared.d.ts.map +1 -0
- package/dist/adapters/kysely/kysely-adapter.d.ts +5 -1
- package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
- package/dist/adapters/kysely/kysely-adapter.js +14 -3
- package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
- package/dist/adapters/kysely/kysely-query-builder.js +1 -1
- package/dist/adapters/kysely/kysely-query-compiler.js +3 -2
- package/dist/adapters/kysely/kysely-query-compiler.js.map +1 -1
- package/dist/adapters/kysely/kysely-query.d.ts +1 -0
- package/dist/adapters/kysely/kysely-query.d.ts.map +1 -1
- package/dist/adapters/kysely/kysely-query.js +28 -19
- package/dist/adapters/kysely/kysely-query.js.map +1 -1
- package/dist/adapters/kysely/kysely-shared.d.ts +14 -0
- package/dist/adapters/kysely/kysely-shared.d.ts.map +1 -0
- package/dist/adapters/kysely/kysely-shared.js +16 -1
- package/dist/adapters/kysely/kysely-shared.js.map +1 -1
- package/dist/adapters/kysely/kysely-uow-compiler.js +68 -16
- package/dist/adapters/kysely/kysely-uow-compiler.js.map +1 -1
- package/dist/adapters/kysely/kysely-uow-executor.js +8 -4
- package/dist/adapters/kysely/kysely-uow-executor.js.map +1 -1
- package/dist/adapters/kysely/migration/execute-base.js +1 -1
- package/dist/adapters/kysely/migration/execute-base.js.map +1 -1
- package/dist/db-fragment-definition-builder.d.ts +152 -0
- package/dist/db-fragment-definition-builder.d.ts.map +1 -0
- package/dist/db-fragment-definition-builder.js +137 -0
- package/dist/db-fragment-definition-builder.js.map +1 -0
- package/dist/fragments/internal-fragment.d.ts +19 -0
- package/dist/fragments/internal-fragment.d.ts.map +1 -0
- package/dist/fragments/internal-fragment.js +39 -0
- package/dist/fragments/internal-fragment.js.map +1 -0
- package/dist/migration-engine/generation-engine.d.ts.map +1 -1
- package/dist/migration-engine/generation-engine.js +35 -15
- package/dist/migration-engine/generation-engine.js.map +1 -1
- package/dist/mod.d.ts +8 -18
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +7 -34
- package/dist/mod.js.map +1 -1
- package/dist/node_modules/.pnpm/rou3@0.7.8/node_modules/rou3/dist/index.js +165 -0
- package/dist/node_modules/.pnpm/rou3@0.7.8/node_modules/rou3/dist/index.js.map +1 -0
- package/dist/packages/fragno/dist/api/bind-services.js +20 -0
- package/dist/packages/fragno/dist/api/bind-services.js.map +1 -0
- package/dist/packages/fragno/dist/api/error.js +48 -0
- package/dist/packages/fragno/dist/api/error.js.map +1 -0
- package/dist/packages/fragno/dist/api/fragment-definition-builder.js +320 -0
- package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -0
- package/dist/packages/fragno/dist/api/fragment-instantiator.js +487 -0
- package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -0
- package/dist/packages/fragno/dist/api/fragno-response.js +73 -0
- package/dist/packages/fragno/dist/api/fragno-response.js.map +1 -0
- package/dist/packages/fragno/dist/api/internal/response-stream.js +81 -0
- package/dist/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
- package/dist/packages/fragno/dist/api/internal/route.js +10 -0
- package/dist/packages/fragno/dist/api/internal/route.js.map +1 -0
- package/dist/packages/fragno/dist/api/mutable-request-state.js +97 -0
- package/dist/packages/fragno/dist/api/mutable-request-state.js.map +1 -0
- package/dist/packages/fragno/dist/api/request-context-storage.js +43 -0
- package/dist/packages/fragno/dist/api/request-context-storage.js.map +1 -0
- package/dist/packages/fragno/dist/api/request-input-context.js +118 -0
- package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -0
- package/dist/packages/fragno/dist/api/request-middleware.js +83 -0
- package/dist/packages/fragno/dist/api/request-middleware.js.map +1 -0
- package/dist/packages/fragno/dist/api/request-output-context.js +119 -0
- package/dist/packages/fragno/dist/api/request-output-context.js.map +1 -0
- package/dist/packages/fragno/dist/api/route.js +17 -0
- package/dist/packages/fragno/dist/api/route.js.map +1 -0
- package/dist/packages/fragno/dist/internal/symbols.js +10 -0
- package/dist/packages/fragno/dist/internal/symbols.js.map +1 -0
- package/dist/query/cursor.d.ts +10 -2
- package/dist/query/cursor.d.ts.map +1 -1
- package/dist/query/cursor.js +11 -4
- package/dist/query/cursor.js.map +1 -1
- package/dist/query/execute-unit-of-work.d.ts +123 -0
- package/dist/query/execute-unit-of-work.d.ts.map +1 -0
- package/dist/query/execute-unit-of-work.js +184 -0
- package/dist/query/execute-unit-of-work.js.map +1 -0
- package/dist/query/query.d.ts +3 -3
- package/dist/query/query.d.ts.map +1 -1
- package/dist/query/result-transform.js +4 -2
- package/dist/query/result-transform.js.map +1 -1
- package/dist/query/retry-policy.d.ts +88 -0
- package/dist/query/retry-policy.d.ts.map +1 -0
- package/dist/query/retry-policy.js +61 -0
- package/dist/query/retry-policy.js.map +1 -0
- package/dist/query/unit-of-work.d.ts +171 -32
- package/dist/query/unit-of-work.d.ts.map +1 -1
- package/dist/query/unit-of-work.js +530 -133
- package/dist/query/unit-of-work.js.map +1 -1
- package/dist/schema/serialize.js +12 -7
- package/dist/schema/serialize.js.map +1 -1
- package/dist/with-database.d.ts +28 -0
- package/dist/with-database.d.ts.map +1 -0
- package/dist/with-database.js +34 -0
- package/dist/with-database.js.map +1 -0
- package/package.json +10 -3
- package/src/adapters/adapters.ts +30 -0
- package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +86 -17
- package/src/adapters/drizzle/drizzle-adapter-sqlite.test.ts +291 -7
- package/src/adapters/drizzle/drizzle-adapter.test.ts +3 -51
- package/src/adapters/drizzle/drizzle-adapter.ts +35 -7
- package/src/adapters/drizzle/drizzle-query.ts +25 -15
- package/src/adapters/drizzle/drizzle-uow-compiler-mysql.test.ts +1442 -0
- package/src/adapters/drizzle/drizzle-uow-compiler-sqlite.test.ts +1414 -0
- package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +78 -61
- package/src/adapters/drizzle/drizzle-uow-compiler.ts +123 -42
- package/src/adapters/drizzle/drizzle-uow-decoder.ts +34 -27
- package/src/adapters/drizzle/drizzle-uow-executor.ts +41 -8
- package/src/adapters/drizzle/generate.test.ts +102 -269
- package/src/adapters/drizzle/generate.ts +12 -30
- package/src/adapters/drizzle/test-utils.ts +36 -5
- package/src/adapters/kysely/kysely-adapter-pglite.test.ts +66 -22
- package/src/adapters/kysely/kysely-adapter-sqlite.test.ts +156 -0
- package/src/adapters/kysely/kysely-adapter.ts +25 -2
- package/src/adapters/kysely/kysely-query-compiler.ts +3 -8
- package/src/adapters/kysely/kysely-query.ts +57 -37
- package/src/adapters/kysely/kysely-shared.ts +34 -0
- package/src/adapters/kysely/kysely-uow-compiler.test.ts +62 -74
- package/src/adapters/kysely/kysely-uow-compiler.ts +92 -24
- package/src/adapters/kysely/kysely-uow-executor.ts +26 -7
- package/src/adapters/kysely/kysely-uow-joins.test.ts +33 -50
- package/src/adapters/kysely/migration/execute-base.ts +1 -1
- package/src/db-fragment-definition-builder.test.ts +887 -0
- package/src/db-fragment-definition-builder.ts +506 -0
- package/src/db-fragment-instantiator.test.ts +467 -0
- package/src/db-fragment-integration.test.ts +408 -0
- package/src/fragments/internal-fragment.test.ts +160 -0
- package/src/fragments/internal-fragment.ts +85 -0
- package/src/migration-engine/generation-engine.test.ts +58 -15
- package/src/migration-engine/generation-engine.ts +78 -25
- package/src/mod.ts +35 -43
- package/src/query/cursor.test.ts +119 -0
- package/src/query/cursor.ts +17 -4
- package/src/query/execute-unit-of-work.test.ts +1310 -0
- package/src/query/execute-unit-of-work.ts +463 -0
- package/src/query/query.ts +4 -4
- package/src/query/result-transform.test.ts +129 -0
- package/src/query/result-transform.ts +4 -1
- package/src/query/retry-policy.test.ts +217 -0
- package/src/query/retry-policy.ts +141 -0
- package/src/query/unit-of-work-coordinator.test.ts +833 -0
- package/src/query/unit-of-work-types.test.ts +15 -2
- package/src/query/unit-of-work.test.ts +878 -200
- package/src/query/unit-of-work.ts +963 -321
- package/src/schema/serialize.ts +22 -11
- package/src/with-database.ts +140 -0
- package/tsdown.config.ts +1 -0
- package/dist/fragment.d.ts +0 -54
- package/dist/fragment.d.ts.map +0 -1
- package/dist/fragment.js +0 -92
- package/dist/fragment.js.map +0 -1
- package/dist/shared/settings-schema.js +0 -36
- package/dist/shared/settings-schema.js.map +0 -1
- package/src/fragment.test.ts +0 -341
- package/src/fragment.ts +0 -198
- package/src/shared/settings-schema.ts +0 -61
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { assert, beforeAll, describe, expect, it } from "vitest";
|
|
1
|
+
import { assert, describe, expect, it } from "vitest";
|
|
3
2
|
import { column, FragnoId, idColumn, referenceColumn, schema } from "../../schema/create";
|
|
4
3
|
import { UnitOfWork, type UOWDecoder } from "../../query/unit-of-work";
|
|
5
4
|
import { createKyselyUOWCompiler } from "./kysely-uow-compiler";
|
|
6
|
-
import type { ConnectionPool } from "../../shared/connection-pool";
|
|
7
|
-
import { createKyselyConnectionPool } from "./kysely-connection-pool";
|
|
8
5
|
import { Cursor } from "../../query/cursor";
|
|
9
6
|
|
|
10
7
|
describe("kysely-uow-compiler", () => {
|
|
@@ -86,47 +83,21 @@ describe("kysely-uow-compiler", () => {
|
|
|
86
83
|
});
|
|
87
84
|
});
|
|
88
85
|
|
|
89
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
90
|
-
let kysely: Kysely<any>;
|
|
91
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
92
|
-
let pool: ConnectionPool<Kysely<any>>;
|
|
93
|
-
|
|
94
|
-
beforeAll(() => {
|
|
95
|
-
// Create a mock Kysely instance (we won't execute queries, just compile them)
|
|
96
|
-
// We need a minimal pool that won't actually connect
|
|
97
|
-
const mockPool = {
|
|
98
|
-
connect: () => Promise.reject(new Error("Mock pool - no actual connections")),
|
|
99
|
-
end: () => Promise.resolve(),
|
|
100
|
-
on: () => {},
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
kysely = new Kysely({
|
|
104
|
-
dialect: new PostgresDialect({
|
|
105
|
-
// Safe: we're only compiling queries, not executing them
|
|
106
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
107
|
-
pool: mockPool as any,
|
|
108
|
-
}),
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
// Wrap in connection pool
|
|
112
|
-
pool = createKyselyConnectionPool(kysely);
|
|
113
|
-
});
|
|
114
|
-
|
|
115
86
|
// Helper to create UnitOfWork for testing
|
|
116
87
|
function createTestUOW(name?: string) {
|
|
117
|
-
const mockCompiler = createKyselyUOWCompiler(
|
|
88
|
+
const mockCompiler = createKyselyUOWCompiler("postgresql");
|
|
118
89
|
const mockExecutor = {
|
|
119
90
|
executeRetrievalPhase: async () => [],
|
|
120
91
|
executeMutationPhase: async () => ({ success: true, createdInternalIds: [] }),
|
|
121
92
|
};
|
|
122
|
-
const mockDecoder: UOWDecoder
|
|
93
|
+
const mockDecoder: UOWDecoder = (rawResults, operations) => {
|
|
123
94
|
if (rawResults.length !== operations.length) {
|
|
124
95
|
throw new Error("rawResults and ops must have the same length");
|
|
125
96
|
}
|
|
126
97
|
return rawResults;
|
|
127
98
|
};
|
|
128
99
|
// Pass undefined for decoder since we're only testing compilation, not execution
|
|
129
|
-
return new UnitOfWork(
|
|
100
|
+
return new UnitOfWork(mockCompiler, mockExecutor, mockDecoder, name).forSchema(testSchema);
|
|
130
101
|
}
|
|
131
102
|
|
|
132
103
|
describe("compileRetrievalOperation", () => {
|
|
@@ -136,7 +107,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
136
107
|
b.whereIndex("idx_email", (eb) => eb("email", "=", "test@example.com")),
|
|
137
108
|
);
|
|
138
109
|
|
|
139
|
-
const compiler = createKyselyUOWCompiler(
|
|
110
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
140
111
|
const compiled = uow.compile(compiler);
|
|
141
112
|
|
|
142
113
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -152,7 +123,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
152
123
|
b.whereIndex("idx_name", (eb) => eb("name", "=", "Alice")).select(["id", "name"]),
|
|
153
124
|
);
|
|
154
125
|
|
|
155
|
-
const compiler = createKyselyUOWCompiler(
|
|
126
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
156
127
|
const compiled = uow.compile(compiler);
|
|
157
128
|
|
|
158
129
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -166,7 +137,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
166
137
|
const uow = createTestUOW();
|
|
167
138
|
uow.find("users", (b) => b.whereIndex("primary").pageSize(10));
|
|
168
139
|
|
|
169
|
-
const compiler = createKyselyUOWCompiler(
|
|
140
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
170
141
|
const compiled = uow.compile(compiler);
|
|
171
142
|
|
|
172
143
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -180,7 +151,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
180
151
|
const uow = createTestUOW();
|
|
181
152
|
uow.find("users", (b) => b.whereIndex("primary").orderByIndex("primary", "desc"));
|
|
182
153
|
|
|
183
|
-
const compiler = createKyselyUOWCompiler(
|
|
154
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
184
155
|
const compiled = uow.compile(compiler);
|
|
185
156
|
|
|
186
157
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -193,7 +164,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
193
164
|
const uow = createTestUOW();
|
|
194
165
|
uow.find("users", (b) => b.whereIndex("idx_name").orderByIndex("idx_name", "desc"));
|
|
195
166
|
|
|
196
|
-
const compiler = createKyselyUOWCompiler(
|
|
167
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
197
168
|
const compiled = uow.compile(compiler);
|
|
198
169
|
|
|
199
170
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -209,7 +180,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
209
180
|
);
|
|
210
181
|
uow.find("posts", (b) => b.whereIndex("idx_title", (eb) => eb("title", "contains", "test")));
|
|
211
182
|
|
|
212
|
-
const compiler = createKyselyUOWCompiler(
|
|
183
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
213
184
|
const compiled = uow.compile(compiler);
|
|
214
185
|
|
|
215
186
|
expect(compiled.retrievalBatch).toHaveLength(2);
|
|
@@ -228,7 +199,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
228
199
|
return b;
|
|
229
200
|
});
|
|
230
201
|
|
|
231
|
-
const compiler = createKyselyUOWCompiler(
|
|
202
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
232
203
|
const compiled = uow.compile(compiler);
|
|
233
204
|
|
|
234
205
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -241,7 +212,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
241
212
|
const uow = createTestUOW();
|
|
242
213
|
uow.find("users", (b) => b.whereIndex("idx_age", (eb) => eb("age", ">", 25)).selectCount());
|
|
243
214
|
|
|
244
|
-
const compiler = createKyselyUOWCompiler(
|
|
215
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
245
216
|
const compiled = uow.compile(compiler);
|
|
246
217
|
|
|
247
218
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -263,7 +234,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
263
234
|
b.whereIndex("idx_name").orderByIndex("idx_name", "asc").after(cursor).pageSize(10),
|
|
264
235
|
);
|
|
265
236
|
|
|
266
|
-
const compiler = createKyselyUOWCompiler(
|
|
237
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
267
238
|
const compiled = uow.compile(compiler);
|
|
268
239
|
|
|
269
240
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -285,7 +256,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
285
256
|
b.whereIndex("idx_name").orderByIndex("idx_name", "desc").before(cursor).pageSize(10),
|
|
286
257
|
);
|
|
287
258
|
|
|
288
|
-
const compiler = createKyselyUOWCompiler(
|
|
259
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
289
260
|
const compiled = uow.compile(compiler);
|
|
290
261
|
|
|
291
262
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -311,7 +282,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
311
282
|
.pageSize(5),
|
|
312
283
|
);
|
|
313
284
|
|
|
314
|
-
const compiler = createKyselyUOWCompiler(
|
|
285
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
315
286
|
const compiled = uow.compile(compiler);
|
|
316
287
|
|
|
317
288
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -331,7 +302,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
331
302
|
age: 30,
|
|
332
303
|
});
|
|
333
304
|
|
|
334
|
-
const compiler = createKyselyUOWCompiler(
|
|
305
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
335
306
|
const compiled = uow.compile(compiler);
|
|
336
307
|
const [batch] = compiled.mutationBatch;
|
|
337
308
|
assert(batch);
|
|
@@ -357,7 +328,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
357
328
|
}),
|
|
358
329
|
);
|
|
359
330
|
|
|
360
|
-
const compiler = createKyselyUOWCompiler(
|
|
331
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
361
332
|
const compiled = uow.compile(compiler);
|
|
362
333
|
const [batch] = compiled.mutationBatch;
|
|
363
334
|
assert(batch);
|
|
@@ -373,7 +344,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
373
344
|
const userId = FragnoId.fromExternal("user123", 5);
|
|
374
345
|
uow.update("users", userId, (b) => b.set({ age: 18 }).check());
|
|
375
346
|
|
|
376
|
-
const compiler = createKyselyUOWCompiler(
|
|
347
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
377
348
|
const compiled = uow.compile(compiler);
|
|
378
349
|
const [batch] = compiled.mutationBatch;
|
|
379
350
|
assert(batch);
|
|
@@ -389,7 +360,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
389
360
|
const userId = FragnoId.fromExternal("user123", 0);
|
|
390
361
|
uow.delete("users", userId);
|
|
391
362
|
|
|
392
|
-
const compiler = createKyselyUOWCompiler(
|
|
363
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
393
364
|
const compiled = uow.compile(compiler);
|
|
394
365
|
const [batch] = compiled.mutationBatch;
|
|
395
366
|
assert(batch);
|
|
@@ -405,7 +376,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
405
376
|
const userId = FragnoId.fromExternal("user123", 3);
|
|
406
377
|
uow.delete("users", userId, (b) => b.check());
|
|
407
378
|
|
|
408
|
-
const compiler = createKyselyUOWCompiler(
|
|
379
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
409
380
|
const compiled = uow.compile(compiler);
|
|
410
381
|
const [batch] = compiled.mutationBatch;
|
|
411
382
|
assert(batch);
|
|
@@ -425,7 +396,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
425
396
|
}),
|
|
426
397
|
);
|
|
427
398
|
|
|
428
|
-
const compiler = createKyselyUOWCompiler(
|
|
399
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
429
400
|
const compiled = uow.compile(compiler);
|
|
430
401
|
const [batch] = compiled.mutationBatch;
|
|
431
402
|
assert(batch);
|
|
@@ -440,7 +411,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
440
411
|
const uow = createTestUOW();
|
|
441
412
|
uow.delete("users", "user123");
|
|
442
413
|
|
|
443
|
-
const compiler = createKyselyUOWCompiler(
|
|
414
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
444
415
|
const compiled = uow.compile(compiler);
|
|
445
416
|
const [batch] = compiled.mutationBatch;
|
|
446
417
|
assert(batch);
|
|
@@ -480,7 +451,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
480
451
|
const userId = FragnoId.fromExternal("user456", 0);
|
|
481
452
|
uow.delete("posts", userId);
|
|
482
453
|
|
|
483
|
-
const compiler = createKyselyUOWCompiler(
|
|
454
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
484
455
|
const compiled = uow.compile(compiler);
|
|
485
456
|
const [createBatch, updateBatch, deleteBatch] = compiled.mutationBatch;
|
|
486
457
|
|
|
@@ -519,7 +490,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
519
490
|
const userId = FragnoId.fromExternal("user123", 3);
|
|
520
491
|
uow.update("users", userId, (b) => b.set({ age: 31 }).check());
|
|
521
492
|
|
|
522
|
-
const compiler = createKyselyUOWCompiler(
|
|
493
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
523
494
|
const compiled = uow.compile(compiler);
|
|
524
495
|
|
|
525
496
|
expect(compiled.name).toBe("update-user-balance");
|
|
@@ -551,7 +522,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
551
522
|
),
|
|
552
523
|
);
|
|
553
524
|
|
|
554
|
-
const compiler = createKyselyUOWCompiler(
|
|
525
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
555
526
|
const compiled = uow.compile(compiler);
|
|
556
527
|
|
|
557
528
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -565,7 +536,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
565
536
|
const uow = createTestUOW();
|
|
566
537
|
uow.find("users", (b) => b.whereIndex("primary", () => false));
|
|
567
538
|
|
|
568
|
-
const compiler = createKyselyUOWCompiler(
|
|
539
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
569
540
|
const compiled = uow.compile(compiler);
|
|
570
541
|
|
|
571
542
|
// When condition is false, the operation should return null and not be added to batch
|
|
@@ -576,7 +547,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
576
547
|
const uow = createTestUOW();
|
|
577
548
|
uow.find("users", (b) => b.whereIndex("primary", () => true));
|
|
578
549
|
|
|
579
|
-
const compiler = createKyselyUOWCompiler(
|
|
550
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
580
551
|
const compiled = uow.compile(compiler);
|
|
581
552
|
|
|
582
553
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -593,7 +564,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
593
564
|
const userId = FragnoId.fromExternal("user123", 5);
|
|
594
565
|
uow.update("users", userId, (b) => b.set({ age: 31 }).check());
|
|
595
566
|
|
|
596
|
-
const compiler = createKyselyUOWCompiler(
|
|
567
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
597
568
|
const compiled = uow.compile(compiler);
|
|
598
569
|
const [batch] = compiled.mutationBatch;
|
|
599
570
|
assert(batch);
|
|
@@ -610,7 +581,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
610
581
|
const userId = FragnoId.fromExternal("user456", 3);
|
|
611
582
|
uow.delete("users", userId, (b) => b.check());
|
|
612
583
|
|
|
613
|
-
const compiler = createKyselyUOWCompiler(
|
|
584
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
614
585
|
const compiled = uow.compile(compiler);
|
|
615
586
|
const [batch] = compiled.mutationBatch;
|
|
616
587
|
assert(batch);
|
|
@@ -630,7 +601,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
630
601
|
uow.update("users", userId, (b) => b.set({ age: 30 }).check());
|
|
631
602
|
uow.update("posts", postId, (b) => b.set({ viewCount: 100 }).check());
|
|
632
603
|
|
|
633
|
-
const compiler = createKyselyUOWCompiler(
|
|
604
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
634
605
|
const compiled = uow.compile(compiler);
|
|
635
606
|
const [userBatch, postBatch] = compiled.mutationBatch;
|
|
636
607
|
|
|
@@ -657,7 +628,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
657
628
|
const userId = FragnoId.fromExternal("user1", 0);
|
|
658
629
|
uow.update("users", userId, (b) => b.set({ age: 25 }));
|
|
659
630
|
|
|
660
|
-
const compiler = createKyselyUOWCompiler(
|
|
631
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
661
632
|
const compiled = uow.compile(compiler);
|
|
662
633
|
const [batch] = compiled.mutationBatch;
|
|
663
634
|
assert(batch);
|
|
@@ -676,7 +647,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
676
647
|
b.whereIndex("primary").join((jb) => jb.author((ab) => ab.select(["name", "email"]))),
|
|
677
648
|
);
|
|
678
649
|
|
|
679
|
-
const compiler = createKyselyUOWCompiler(
|
|
650
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
680
651
|
const compiled = uow.compile(compiler);
|
|
681
652
|
|
|
682
653
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -700,7 +671,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
700
671
|
),
|
|
701
672
|
);
|
|
702
673
|
|
|
703
|
-
const compiler = createKyselyUOWCompiler(
|
|
674
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
704
675
|
const compiled = uow.compile(compiler);
|
|
705
676
|
|
|
706
677
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -719,7 +690,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
719
690
|
.join((jb) => jb.author((ab) => ab.select(["name"]).orderByIndex("idx_name", "desc"))),
|
|
720
691
|
);
|
|
721
692
|
|
|
722
|
-
const compiler = createKyselyUOWCompiler(
|
|
693
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
723
694
|
const compiled = uow.compile(compiler);
|
|
724
695
|
|
|
725
696
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -735,7 +706,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
735
706
|
b.whereIndex("primary").join((jb) => jb.author((ab) => ab.select(["name"]).pageSize(5))),
|
|
736
707
|
);
|
|
737
708
|
|
|
738
|
-
const compiler = createKyselyUOWCompiler(
|
|
709
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
739
710
|
const compiled = uow.compile(compiler);
|
|
740
711
|
|
|
741
712
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -766,7 +737,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
766
737
|
),
|
|
767
738
|
);
|
|
768
739
|
|
|
769
|
-
const compiler = createKyselyUOWCompiler(
|
|
740
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
770
741
|
const compiled = uow.compile(compiler);
|
|
771
742
|
|
|
772
743
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -785,7 +756,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
785
756
|
.join((jb) => jb.post((pb) => pb.select(["title"])).author((ab) => ab.select(["name"]))),
|
|
786
757
|
);
|
|
787
758
|
|
|
788
|
-
const compiler = createKyselyUOWCompiler(
|
|
759
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
789
760
|
const compiled = uow.compile(compiler);
|
|
790
761
|
|
|
791
762
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -803,7 +774,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
803
774
|
b.whereIndex("primary").join((jb) => jb.inviter((ib) => ib.select(["name", "email"]))),
|
|
804
775
|
);
|
|
805
776
|
|
|
806
|
-
const compiler = createKyselyUOWCompiler(
|
|
777
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
807
778
|
const compiled = uow.compile(compiler);
|
|
808
779
|
|
|
809
780
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -833,7 +804,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
833
804
|
),
|
|
834
805
|
);
|
|
835
806
|
|
|
836
|
-
const compiler = createKyselyUOWCompiler(
|
|
807
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
837
808
|
const compiled = uow.compile(compiler);
|
|
838
809
|
|
|
839
810
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -856,7 +827,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
856
827
|
.join((jb) => jb.post((pb) => pb.select(["title"])).tag((tb) => tb.select(["name"]))),
|
|
857
828
|
);
|
|
858
829
|
|
|
859
|
-
const compiler = createKyselyUOWCompiler(
|
|
830
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
860
831
|
const compiled = uow.compile(compiler);
|
|
861
832
|
|
|
862
833
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -881,7 +852,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
881
852
|
),
|
|
882
853
|
);
|
|
883
854
|
|
|
884
|
-
const compiler = createKyselyUOWCompiler(
|
|
855
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
885
856
|
const compiled = uow.compile(compiler);
|
|
886
857
|
|
|
887
858
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -897,7 +868,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
897
868
|
it("should handle UOW with no operations", () => {
|
|
898
869
|
const uow = createTestUOW();
|
|
899
870
|
|
|
900
|
-
const compiler = createKyselyUOWCompiler(
|
|
871
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
901
872
|
const compiled = uow.compile(compiler);
|
|
902
873
|
|
|
903
874
|
expect(compiled.retrievalBatch).toHaveLength(0);
|
|
@@ -908,7 +879,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
908
879
|
const uow = createTestUOW();
|
|
909
880
|
uow.find("users");
|
|
910
881
|
|
|
911
|
-
const compiler = createKyselyUOWCompiler(
|
|
882
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
912
883
|
const compiled = uow.compile(compiler);
|
|
913
884
|
|
|
914
885
|
expect(compiled.retrievalBatch).toHaveLength(1);
|
|
@@ -922,7 +893,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
922
893
|
email: "test@example.com",
|
|
923
894
|
});
|
|
924
895
|
|
|
925
|
-
const compiler = createKyselyUOWCompiler(
|
|
896
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
926
897
|
const compiled = uow.compile(compiler);
|
|
927
898
|
|
|
928
899
|
expect(compiled.retrievalBatch).toHaveLength(0);
|
|
@@ -949,7 +920,7 @@ describe("kysely-uow-compiler", () => {
|
|
|
949
920
|
content: "This is my first post",
|
|
950
921
|
});
|
|
951
922
|
|
|
952
|
-
const compiler = createKyselyUOWCompiler(
|
|
923
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
953
924
|
const compiled = uow.compile(compiler);
|
|
954
925
|
|
|
955
926
|
// Should have no retrieval operations
|
|
@@ -994,5 +965,22 @@ describe("kysely-uow-compiler", () => {
|
|
|
994
965
|
internalId: undefined,
|
|
995
966
|
});
|
|
996
967
|
});
|
|
968
|
+
|
|
969
|
+
it("should compile check operation", () => {
|
|
970
|
+
const uow = createTestUOW();
|
|
971
|
+
const userId = FragnoId.fromExternal("user123", 5);
|
|
972
|
+
uow.check("users", userId);
|
|
973
|
+
|
|
974
|
+
const compiler = createKyselyUOWCompiler("postgresql");
|
|
975
|
+
const compiled = uow.compile(compiler);
|
|
976
|
+
const [batch] = compiled.mutationBatch;
|
|
977
|
+
assert(batch);
|
|
978
|
+
expect(batch.expectedAffectedRows).toBe(null);
|
|
979
|
+
expect(batch.expectedReturnedRows).toBe(1);
|
|
980
|
+
expect(batch.query.sql).toMatchInlineSnapshot(
|
|
981
|
+
`"select 1 as "exists" from "users" where ("users"."id" = $1 and "users"."_version" = $2) limit $3"`,
|
|
982
|
+
);
|
|
983
|
+
expect(batch.query.parameters).toMatchObject(["user123", 5, 1]);
|
|
984
|
+
});
|
|
997
985
|
});
|
|
998
986
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type CompiledQuery, sql } from "kysely";
|
|
2
2
|
import type { AnyColumn, AnySchema, FragnoId } from "../../schema/create";
|
|
3
3
|
import type {
|
|
4
4
|
CompiledMutation,
|
|
@@ -7,41 +7,69 @@ import type {
|
|
|
7
7
|
UOWCompiler,
|
|
8
8
|
} from "../../query/unit-of-work";
|
|
9
9
|
import { createKyselyQueryCompiler } from "./kysely-query-compiler";
|
|
10
|
-
import { createKyselyQueryBuilder } from "./kysely-query-builder";
|
|
10
|
+
import { createKyselyQueryBuilder, buildWhere } from "./kysely-query-builder";
|
|
11
11
|
import { buildCondition, type Condition } from "../../query/condition-builder";
|
|
12
12
|
import { decodeCursor, serializeCursorValues } from "../../query/cursor";
|
|
13
13
|
import type { AnySelectClause } from "../../query/query";
|
|
14
|
-
import type
|
|
15
|
-
import type { ConnectionPool } from "../../shared/connection-pool";
|
|
14
|
+
import { type TableNameMapper, createKysely, createTableNameMapper } from "./kysely-shared";
|
|
16
15
|
import type { SQLProvider } from "../../shared/providers";
|
|
17
16
|
|
|
18
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
|
-
type KyselyAny = Kysely<any>;
|
|
20
|
-
|
|
21
17
|
/**
|
|
22
18
|
* Create a Kysely-specific Unit of Work compiler
|
|
23
19
|
*
|
|
24
20
|
* This compiler translates UOW operations into Kysely CompiledQuery objects
|
|
25
21
|
* that can be executed as a batch/transaction.
|
|
26
22
|
*
|
|
27
|
-
* @param schema - The database schema
|
|
28
23
|
* @param pool - Connection pool for acquiring database connections
|
|
29
24
|
* @param provider - SQL provider (postgresql, mysql, sqlite, etc.)
|
|
30
|
-
* @param mapper - Optional table name mapper for namespace prefixing
|
|
25
|
+
* @param mapper - Optional table name mapper for namespace prefixing (fallback for operations without explicit namespace)
|
|
31
26
|
* @returns A UOWCompiler instance for Kysely
|
|
32
27
|
*/
|
|
33
|
-
export function createKyselyUOWCompiler
|
|
34
|
-
schema: TSchema,
|
|
35
|
-
pool: ConnectionPool<KyselyAny>,
|
|
28
|
+
export function createKyselyUOWCompiler(
|
|
36
29
|
provider: SQLProvider,
|
|
37
30
|
mapper?: TableNameMapper,
|
|
38
|
-
): UOWCompiler<
|
|
39
|
-
const queryCompiler = createKyselyQueryCompiler(schema, pool, provider, mapper);
|
|
31
|
+
): UOWCompiler<CompiledQuery> {
|
|
40
32
|
// Get kysely instance for query building (compilation doesn't execute, just builds SQL)
|
|
41
|
-
const kysely =
|
|
42
|
-
|
|
33
|
+
const kysely = createKysely(provider);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get the mapper for a specific operation
|
|
37
|
+
* Uses operation's namespace if provided, otherwise falls back to the default mapper
|
|
38
|
+
*/
|
|
39
|
+
function getMapperForOperation(namespace: string | undefined): TableNameMapper | undefined {
|
|
40
|
+
if (namespace) {
|
|
41
|
+
return createTableNameMapper(namespace);
|
|
42
|
+
}
|
|
43
|
+
return mapper;
|
|
44
|
+
}
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
// Cache query compilers and builders by namespace for performance
|
|
47
|
+
const compilerCache = new Map<string | undefined, ReturnType<typeof createKyselyQueryCompiler>>();
|
|
48
|
+
const builderCache = new Map<string | undefined, ReturnType<typeof createKyselyQueryBuilder>>();
|
|
49
|
+
|
|
50
|
+
function getQueryCompiler(schema: AnySchema, namespace: string | undefined) {
|
|
51
|
+
const cacheKey = namespace;
|
|
52
|
+
let compiler = compilerCache.get(cacheKey);
|
|
53
|
+
if (!compiler) {
|
|
54
|
+
const opMapper = getMapperForOperation(namespace);
|
|
55
|
+
compiler = createKyselyQueryCompiler(schema, provider, opMapper);
|
|
56
|
+
compilerCache.set(cacheKey, compiler);
|
|
57
|
+
}
|
|
58
|
+
return compiler;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getQueryBuilder(namespace: string | undefined) {
|
|
62
|
+
const cacheKey = namespace;
|
|
63
|
+
let builder = builderCache.get(cacheKey);
|
|
64
|
+
if (!builder) {
|
|
65
|
+
const opMapper = getMapperForOperation(namespace);
|
|
66
|
+
builder = createKyselyQueryBuilder(kysely, provider, opMapper);
|
|
67
|
+
builderCache.set(cacheKey, builder);
|
|
68
|
+
}
|
|
69
|
+
return builder;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function toTable(schema: AnySchema, name: unknown) {
|
|
45
73
|
const table = schema.tables[name as string];
|
|
46
74
|
if (!table) {
|
|
47
75
|
throw new Error(`Invalid table name ${name}.`);
|
|
@@ -50,7 +78,8 @@ export function createKyselyUOWCompiler<TSchema extends AnySchema>(
|
|
|
50
78
|
}
|
|
51
79
|
|
|
52
80
|
return {
|
|
53
|
-
compileRetrievalOperation(op: RetrievalOperation<
|
|
81
|
+
compileRetrievalOperation(op: RetrievalOperation<AnySchema>): CompiledQuery | null {
|
|
82
|
+
const queryCompiler = getQueryCompiler(op.schema, op.namespace);
|
|
54
83
|
switch (op.type) {
|
|
55
84
|
case "count": {
|
|
56
85
|
return queryCompiler.count(op.table.name, {
|
|
@@ -159,14 +188,19 @@ export function createKyselyUOWCompiler<TSchema extends AnySchema>(
|
|
|
159
188
|
}
|
|
160
189
|
}
|
|
161
190
|
|
|
162
|
-
//
|
|
191
|
+
// For cursor pagination, fetch one extra item to determine if there's a next page
|
|
192
|
+
// Only apply this when using the high-level findWithCursor() API (op.withCursor === true)
|
|
193
|
+
const effectiveLimit = pageSize && op.withCursor ? pageSize + 1 : pageSize;
|
|
194
|
+
|
|
195
|
+
// When we have joins or need to bypass buildFindOptions, use operation-specific queryBuilder
|
|
163
196
|
if (join && join.length > 0) {
|
|
197
|
+
const queryBuilder = getQueryBuilder(op.namespace);
|
|
164
198
|
return queryBuilder.findMany(op.table, {
|
|
165
199
|
// Safe cast: select from UOW matches SimplifyFindOptions requirement
|
|
166
200
|
select: (findManyOptions.select ?? true) as AnySelectClause,
|
|
167
201
|
where: combinedWhere,
|
|
168
202
|
orderBy,
|
|
169
|
-
limit:
|
|
203
|
+
limit: effectiveLimit,
|
|
170
204
|
join,
|
|
171
205
|
});
|
|
172
206
|
}
|
|
@@ -175,25 +209,27 @@ export function createKyselyUOWCompiler<TSchema extends AnySchema>(
|
|
|
175
209
|
...findManyOptions,
|
|
176
210
|
where: combinedWhere ? () => combinedWhere! : undefined,
|
|
177
211
|
orderBy: orderBy?.map(([col, dir]) => [col.ormName, dir]),
|
|
178
|
-
limit:
|
|
212
|
+
limit: effectiveLimit,
|
|
179
213
|
});
|
|
180
214
|
}
|
|
181
215
|
}
|
|
182
216
|
},
|
|
183
217
|
|
|
184
218
|
compileMutationOperation(
|
|
185
|
-
op: MutationOperation<
|
|
219
|
+
op: MutationOperation<AnySchema>,
|
|
186
220
|
): CompiledMutation<CompiledQuery> | null {
|
|
221
|
+
const queryCompiler = getQueryCompiler(op.schema, op.namespace);
|
|
187
222
|
switch (op.type) {
|
|
188
223
|
case "create":
|
|
189
224
|
// queryCompiler.create() calls encodeValues() which handles runtime defaults
|
|
190
225
|
return {
|
|
191
226
|
query: queryCompiler.create(op.table, op.values),
|
|
192
227
|
expectedAffectedRows: null, // creates don't need affected row checks
|
|
228
|
+
expectedReturnedRows: null,
|
|
193
229
|
};
|
|
194
230
|
|
|
195
231
|
case "update": {
|
|
196
|
-
const table = toTable(op.table);
|
|
232
|
+
const table = toTable(op.schema, op.table);
|
|
197
233
|
const idColumn = table.getIdColumn();
|
|
198
234
|
const versionColumn = table.getVersionColumn();
|
|
199
235
|
|
|
@@ -221,12 +257,13 @@ export function createKyselyUOWCompiler<TSchema extends AnySchema>(
|
|
|
221
257
|
? {
|
|
222
258
|
query,
|
|
223
259
|
expectedAffectedRows: op.checkVersion ? 1 : null,
|
|
260
|
+
expectedReturnedRows: null,
|
|
224
261
|
}
|
|
225
262
|
: null;
|
|
226
263
|
}
|
|
227
264
|
|
|
228
265
|
case "delete": {
|
|
229
|
-
const table = toTable(op.table);
|
|
266
|
+
const table = toTable(op.schema, op.table);
|
|
230
267
|
const idColumn = table.getIdColumn();
|
|
231
268
|
const versionColumn = table.getVersionColumn();
|
|
232
269
|
|
|
@@ -254,9 +291,40 @@ export function createKyselyUOWCompiler<TSchema extends AnySchema>(
|
|
|
254
291
|
? {
|
|
255
292
|
query,
|
|
256
293
|
expectedAffectedRows: op.checkVersion ? 1 : null,
|
|
294
|
+
expectedReturnedRows: null,
|
|
257
295
|
}
|
|
258
296
|
: null;
|
|
259
297
|
}
|
|
298
|
+
|
|
299
|
+
case "check": {
|
|
300
|
+
const table = toTable(op.schema, op.table);
|
|
301
|
+
const idColumn = table.getIdColumn();
|
|
302
|
+
const versionColumn = table.getVersionColumn();
|
|
303
|
+
const mapper = getMapperForOperation(op.namespace);
|
|
304
|
+
const tableName = mapper ? mapper.toPhysical(op.table) : op.table;
|
|
305
|
+
|
|
306
|
+
const externalId = op.id.externalId;
|
|
307
|
+
const version = op.id.version;
|
|
308
|
+
|
|
309
|
+
// Build a SELECT 1 query to check if the row exists with the correct version
|
|
310
|
+
const condition = buildCondition(table.columns, (eb) =>
|
|
311
|
+
eb.and(eb(idColumn.ormName, "=", externalId), eb(versionColumn.ormName, "=", version)),
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
let query = kysely.selectFrom(tableName).select(sql<number>`1`.as("exists"));
|
|
315
|
+
|
|
316
|
+
if (typeof condition === "boolean") {
|
|
317
|
+
throw new Error("Condition is a boolean, but should be a condition object.");
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
query = query.where((eb) => buildWhere(condition, eb, provider, mapper, table)).limit(1);
|
|
321
|
+
|
|
322
|
+
return {
|
|
323
|
+
query: query.compile(),
|
|
324
|
+
expectedAffectedRows: null,
|
|
325
|
+
expectedReturnedRows: 1, // Check that exactly 1 row was returned
|
|
326
|
+
};
|
|
327
|
+
}
|
|
260
328
|
}
|
|
261
329
|
},
|
|
262
330
|
};
|