@prisma-next/sql-runtime 0.3.0-dev.7 → 0.3.0-dev.71
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/LICENSE +201 -0
- package/README.md +137 -26
- package/dist/exports-BhZqJPVb.mjs +771 -0
- package/dist/exports-BhZqJPVb.mjs.map +1 -0
- package/dist/index-D59jqEKF.d.mts +159 -0
- package/dist/index-D59jqEKF.d.mts.map +1 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +3 -0
- package/dist/test/utils.d.mts +82 -0
- package/dist/test/utils.d.mts.map +1 -0
- package/dist/test/utils.mjs +212 -0
- package/dist/test/utils.mjs.map +1 -0
- package/package.json +32 -25
- package/src/codecs/decoding.ts +84 -3
- package/src/codecs/encoding.ts +15 -2
- package/src/codecs/json-schema-validation.ts +61 -0
- package/src/exports/index.ts +14 -6
- package/src/lower-sql-plan.ts +8 -8
- package/src/plugins/lints.ts +204 -0
- package/src/sql-context.ts +385 -98
- package/src/sql-family-adapter.ts +9 -5
- package/src/sql-marker.ts +2 -2
- package/src/sql-runtime.ts +131 -31
- package/test/async-iterable-result.test.ts +42 -34
- package/test/context.types.test-d.ts +68 -0
- package/test/execution-stack.test.ts +166 -0
- package/test/json-schema-validation.test.ts +653 -0
- package/test/lints.test.ts +330 -0
- package/test/parameterized-types.test.ts +539 -0
- package/test/sql-context.test.ts +292 -117
- package/test/sql-family-adapter.test.ts +7 -6
- package/test/sql-runtime.test.ts +218 -30
- package/test/utils.ts +80 -51
- package/dist/accelerate-EEKAFGN3-P6A6XJWJ.js +0 -137863
- package/dist/accelerate-EEKAFGN3-P6A6XJWJ.js.map +0 -1
- package/dist/amcheck-24VY6X5V.js +0 -13
- package/dist/amcheck-24VY6X5V.js.map +0 -1
- package/dist/bloom-VS74NLHT.js +0 -13
- package/dist/bloom-VS74NLHT.js.map +0 -1
- package/dist/btree_gin-WBC4EAAI.js +0 -13
- package/dist/btree_gin-WBC4EAAI.js.map +0 -1
- package/dist/btree_gist-UNC6QD3M.js +0 -13
- package/dist/btree_gist-UNC6QD3M.js.map +0 -1
- package/dist/chunk-3KTOEDFX.js +0 -49
- package/dist/chunk-3KTOEDFX.js.map +0 -1
- package/dist/chunk-47DZBRQC.js +0 -1280
- package/dist/chunk-47DZBRQC.js.map +0 -1
- package/dist/chunk-52N6AFZM.js +0 -133
- package/dist/chunk-52N6AFZM.js.map +0 -1
- package/dist/chunk-7D4SUZUM.js +0 -38
- package/dist/chunk-7D4SUZUM.js.map +0 -1
- package/dist/chunk-C6I3V3DM.js +0 -455
- package/dist/chunk-C6I3V3DM.js.map +0 -1
- package/dist/chunk-ECWIHLAT.js +0 -37
- package/dist/chunk-ECWIHLAT.js.map +0 -1
- package/dist/chunk-EI626SDC.js +0 -105
- package/dist/chunk-EI626SDC.js.map +0 -1
- package/dist/chunk-UKKOYUGL.js +0 -578
- package/dist/chunk-UKKOYUGL.js.map +0 -1
- package/dist/chunk-XPLNMXQV.js +0 -1537
- package/dist/chunk-XPLNMXQV.js.map +0 -1
- package/dist/citext-T7MXGUY7.js +0 -13
- package/dist/citext-T7MXGUY7.js.map +0 -1
- package/dist/client-5FENX6AW.js +0 -299
- package/dist/client-5FENX6AW.js.map +0 -1
- package/dist/cube-TFDQBZCI.js +0 -13
- package/dist/cube-TFDQBZCI.js.map +0 -1
- package/dist/dict_int-AEUOPGWP.js +0 -13
- package/dist/dict_int-AEUOPGWP.js.map +0 -1
- package/dist/dict_xsyn-DAAYX3FL.js +0 -13
- package/dist/dict_xsyn-DAAYX3FL.js.map +0 -1
- package/dist/dist-AQ3LWXOX.js +0 -570
- package/dist/dist-AQ3LWXOX.js.map +0 -1
- package/dist/dist-LBVX6BJW.js +0 -189
- package/dist/dist-LBVX6BJW.js.map +0 -1
- package/dist/dist-WLKUVDN2.js +0 -5127
- package/dist/dist-WLKUVDN2.js.map +0 -1
- package/dist/earthdistance-KIGTF4LE.js +0 -13
- package/dist/earthdistance-KIGTF4LE.js.map +0 -1
- package/dist/file_fdw-5N55UP6I.js +0 -13
- package/dist/file_fdw-5N55UP6I.js.map +0 -1
- package/dist/fuzzystrmatch-KN3YWBFP.js +0 -13
- package/dist/fuzzystrmatch-KN3YWBFP.js.map +0 -1
- package/dist/hstore-YX726NKN.js +0 -13
- package/dist/hstore-YX726NKN.js.map +0 -1
- package/dist/http-exception-FZY2H4OF.js +0 -8
- package/dist/http-exception-FZY2H4OF.js.map +0 -1
- package/dist/index.js +0 -30
- package/dist/index.js.map +0 -1
- package/dist/intarray-NKVXNO2D.js +0 -13
- package/dist/intarray-NKVXNO2D.js.map +0 -1
- package/dist/isn-FTEMJGEV.js +0 -13
- package/dist/isn-FTEMJGEV.js.map +0 -1
- package/dist/lo-DB7L4NGI.js +0 -13
- package/dist/lo-DB7L4NGI.js.map +0 -1
- package/dist/logger-WQ7SHNDD.js +0 -68
- package/dist/logger-WQ7SHNDD.js.map +0 -1
- package/dist/ltree-Z32TZT6W.js +0 -13
- package/dist/ltree-Z32TZT6W.js.map +0 -1
- package/dist/nodefs-NM46ACH7.js +0 -31
- package/dist/nodefs-NM46ACH7.js.map +0 -1
- package/dist/opfs-ahp-NJO33LVZ.js +0 -332
- package/dist/opfs-ahp-NJO33LVZ.js.map +0 -1
- package/dist/pageinspect-YP3IZR4X.js +0 -13
- package/dist/pageinspect-YP3IZR4X.js.map +0 -1
- package/dist/pg_buffercache-7TD5J2FB.js +0 -13
- package/dist/pg_buffercache-7TD5J2FB.js.map +0 -1
- package/dist/pg_dump-SG4KYBUB.js +0 -2492
- package/dist/pg_dump-SG4KYBUB.js.map +0 -1
- package/dist/pg_freespacemap-DZDNCPZK.js +0 -13
- package/dist/pg_freespacemap-DZDNCPZK.js.map +0 -1
- package/dist/pg_surgery-J2MUEWEP.js +0 -13
- package/dist/pg_surgery-J2MUEWEP.js.map +0 -1
- package/dist/pg_trgm-7VNQOYS6.js +0 -13
- package/dist/pg_trgm-7VNQOYS6.js.map +0 -1
- package/dist/pg_visibility-TTSIPHFL.js +0 -13
- package/dist/pg_visibility-TTSIPHFL.js.map +0 -1
- package/dist/pg_walinspect-KPFHSHRJ.js +0 -13
- package/dist/pg_walinspect-KPFHSHRJ.js.map +0 -1
- package/dist/proxy-signals-GUDAMDHV.js +0 -39
- package/dist/proxy-signals-GUDAMDHV.js.map +0 -1
- package/dist/seg-IYVDLE4O.js +0 -13
- package/dist/seg-IYVDLE4O.js.map +0 -1
- package/dist/src/codecs/decoding.d.ts +0 -4
- package/dist/src/codecs/decoding.d.ts.map +0 -1
- package/dist/src/codecs/encoding.d.ts +0 -5
- package/dist/src/codecs/encoding.d.ts.map +0 -1
- package/dist/src/codecs/validation.d.ts +0 -6
- package/dist/src/codecs/validation.d.ts.map +0 -1
- package/dist/src/exports/index.d.ts +0 -11
- package/dist/src/exports/index.d.ts.map +0 -1
- package/dist/src/index.d.ts +0 -2
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/lower-sql-plan.d.ts +0 -15
- package/dist/src/lower-sql-plan.d.ts.map +0 -1
- package/dist/src/sql-context.d.ts +0 -65
- package/dist/src/sql-context.d.ts.map +0 -1
- package/dist/src/sql-family-adapter.d.ts +0 -10
- package/dist/src/sql-family-adapter.d.ts.map +0 -1
- package/dist/src/sql-marker.d.ts +0 -22
- package/dist/src/sql-marker.d.ts.map +0 -1
- package/dist/src/sql-runtime.d.ts +0 -25
- package/dist/src/sql-runtime.d.ts.map +0 -1
- package/dist/tablefunc-EF4RCS7S.js +0 -13
- package/dist/tablefunc-EF4RCS7S.js.map +0 -1
- package/dist/tcn-3VT5BQYW.js +0 -13
- package/dist/tcn-3VT5BQYW.js.map +0 -1
- package/dist/test/utils.d.ts +0 -59
- package/dist/test/utils.d.ts.map +0 -1
- package/dist/test/utils.js +0 -24634
- package/dist/test/utils.js.map +0 -1
- package/dist/tiny-CW6F4GX6.js +0 -10
- package/dist/tiny-CW6F4GX6.js.map +0 -1
- package/dist/tsm_system_rows-ES7KNUQH.js +0 -13
- package/dist/tsm_system_rows-ES7KNUQH.js.map +0 -1
- package/dist/tsm_system_time-76WEIMBG.js +0 -13
- package/dist/tsm_system_time-76WEIMBG.js.map +0 -1
- package/dist/unaccent-7RYF3R64.js +0 -13
- package/dist/unaccent-7RYF3R64.js.map +0 -1
- package/dist/utility-Q5A254LJ-J4HTKZPT.js +0 -347
- package/dist/utility-Q5A254LJ-J4HTKZPT.js.map +0 -1
- package/dist/uuid_ossp-4ETE4FPE.js +0 -13
- package/dist/uuid_ossp-4ETE4FPE.js.map +0 -1
- package/dist/vector-74GPNV7V.js +0 -13
- package/dist/vector-74GPNV7V.js.map +0 -1
- package/src/index.ts +0 -1
package/test/sql-runtime.test.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { coreHash, type ExecutionPlan } from '@prisma-next/contract/types';
|
|
2
|
+
import type { ExecutionStackInstance } from '@prisma-next/core-execution-plane/stack';
|
|
3
|
+
import { instantiateExecutionStack } from '@prisma-next/core-execution-plane/stack';
|
|
4
|
+
import type {
|
|
5
|
+
RuntimeDriverInstance,
|
|
6
|
+
RuntimeExtensionInstance,
|
|
7
|
+
} from '@prisma-next/core-execution-plane/types';
|
|
2
8
|
import type { SqlContract, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
3
9
|
import type {
|
|
4
10
|
CodecRegistry,
|
|
@@ -8,15 +14,19 @@ import type {
|
|
|
8
14
|
} from '@prisma-next/sql-relational-core/ast';
|
|
9
15
|
import { codec, createCodecRegistry } from '@prisma-next/sql-relational-core/ast';
|
|
10
16
|
import { describe, expect, it, vi } from 'vitest';
|
|
11
|
-
import type {
|
|
17
|
+
import type {
|
|
18
|
+
SqlRuntimeAdapterDescriptor,
|
|
19
|
+
SqlRuntimeAdapterInstance,
|
|
20
|
+
SqlRuntimeTargetDescriptor,
|
|
21
|
+
} from '../src/sql-context';
|
|
22
|
+
import { createExecutionContext, createSqlExecutionStack } from '../src/sql-context';
|
|
12
23
|
import { createRuntime } from '../src/sql-runtime';
|
|
13
24
|
|
|
14
|
-
// Minimal test contract
|
|
15
25
|
const testContract: SqlContract<SqlStorage> = {
|
|
16
26
|
schemaVersion: '1',
|
|
17
27
|
targetFamily: 'sql',
|
|
18
28
|
target: 'postgres',
|
|
19
|
-
|
|
29
|
+
storageHash: coreHash('sha256:test'),
|
|
20
30
|
models: {},
|
|
21
31
|
relations: {},
|
|
22
32
|
storage: { tables: {} },
|
|
@@ -30,7 +40,14 @@ const testContract: SqlContract<SqlStorage> = {
|
|
|
30
40
|
},
|
|
31
41
|
};
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
interface DriverExecuteSpies {
|
|
44
|
+
rootExecute: ReturnType<typeof vi.fn>;
|
|
45
|
+
connectionExecute: ReturnType<typeof vi.fn>;
|
|
46
|
+
transactionExecute: ReturnType<typeof vi.fn>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type MockSqlDriver = SqlDriver & { __spies: DriverExecuteSpies };
|
|
50
|
+
|
|
34
51
|
function createStubCodecs(): CodecRegistry {
|
|
35
52
|
const registry = createCodecRegistry();
|
|
36
53
|
registry.register(
|
|
@@ -44,7 +61,6 @@ function createStubCodecs(): CodecRegistry {
|
|
|
44
61
|
return registry;
|
|
45
62
|
}
|
|
46
63
|
|
|
47
|
-
// Create a stub adapter
|
|
48
64
|
function createStubAdapter() {
|
|
49
65
|
const codecs = createStubCodecs();
|
|
50
66
|
return {
|
|
@@ -67,37 +83,141 @@ function createStubAdapter() {
|
|
|
67
83
|
};
|
|
68
84
|
}
|
|
69
85
|
|
|
70
|
-
|
|
71
|
-
function
|
|
72
|
-
const execute = vi.fn().mockImplementation(async function* (_request: SqlExecuteRequest) {
|
|
86
|
+
function createMockDriver(): MockSqlDriver {
|
|
87
|
+
const rootExecute = vi.fn().mockImplementation(async function* (_request: SqlExecuteRequest) {
|
|
73
88
|
yield { id: 1 };
|
|
74
89
|
});
|
|
90
|
+
const connectionExecute = vi.fn().mockImplementation(async function* (
|
|
91
|
+
_request: SqlExecuteRequest,
|
|
92
|
+
) {
|
|
93
|
+
yield { id: 2 };
|
|
94
|
+
});
|
|
95
|
+
const transactionExecute = vi.fn().mockImplementation(async function* (
|
|
96
|
+
_request: SqlExecuteRequest,
|
|
97
|
+
) {
|
|
98
|
+
yield { id: 3 };
|
|
99
|
+
});
|
|
75
100
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
101
|
+
const query = vi.fn().mockResolvedValue({ rows: [], rowCount: 0 });
|
|
102
|
+
|
|
103
|
+
const transaction = {
|
|
104
|
+
execute: transactionExecute,
|
|
105
|
+
query,
|
|
106
|
+
commit: vi.fn().mockResolvedValue(undefined),
|
|
107
|
+
rollback: vi.fn().mockResolvedValue(undefined),
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const connection = {
|
|
111
|
+
execute: connectionExecute,
|
|
112
|
+
query,
|
|
113
|
+
release: vi.fn().mockResolvedValue(undefined),
|
|
114
|
+
beginTransaction: vi.fn().mockResolvedValue(transaction),
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const driver: SqlDriver = {
|
|
118
|
+
execute: rootExecute,
|
|
119
|
+
query,
|
|
120
|
+
connect: vi.fn().mockImplementation(async (_binding?: undefined) => undefined),
|
|
121
|
+
acquireConnection: vi.fn().mockResolvedValue(connection),
|
|
80
122
|
close: vi.fn().mockResolvedValue(undefined),
|
|
81
123
|
};
|
|
124
|
+
|
|
125
|
+
return Object.assign(driver, {
|
|
126
|
+
__spies: {
|
|
127
|
+
rootExecute,
|
|
128
|
+
connectionExecute,
|
|
129
|
+
transactionExecute,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
82
132
|
}
|
|
83
133
|
|
|
84
|
-
|
|
85
|
-
|
|
134
|
+
function createTestTargetDescriptor(): SqlRuntimeTargetDescriptor<'postgres'> {
|
|
135
|
+
return {
|
|
136
|
+
kind: 'target',
|
|
137
|
+
id: 'postgres',
|
|
138
|
+
version: '0.0.1',
|
|
139
|
+
familyId: 'sql' as const,
|
|
140
|
+
targetId: 'postgres' as const,
|
|
141
|
+
codecs: () => createCodecRegistry(),
|
|
142
|
+
operationSignatures: () => [],
|
|
143
|
+
parameterizedCodecs: () => [],
|
|
144
|
+
create() {
|
|
145
|
+
return { familyId: 'sql' as const, targetId: 'postgres' as const };
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function createTestAdapterDescriptor(
|
|
151
|
+
adapter: ReturnType<typeof createStubAdapter>,
|
|
152
|
+
): SqlRuntimeAdapterDescriptor<'postgres'> {
|
|
153
|
+
const codecRegistry = adapter.profile.codecs();
|
|
154
|
+
return {
|
|
155
|
+
kind: 'adapter',
|
|
156
|
+
id: 'test-adapter',
|
|
157
|
+
version: '0.0.1',
|
|
158
|
+
familyId: 'sql' as const,
|
|
159
|
+
targetId: 'postgres' as const,
|
|
160
|
+
codecs: () => codecRegistry,
|
|
161
|
+
operationSignatures: () => [],
|
|
162
|
+
parameterizedCodecs: () => [],
|
|
163
|
+
create() {
|
|
164
|
+
return Object.assign(
|
|
165
|
+
{ familyId: 'sql' as const, targetId: 'postgres' as const },
|
|
166
|
+
adapter,
|
|
167
|
+
) as SqlRuntimeAdapterInstance<'postgres'>;
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function createTestSetup() {
|
|
86
173
|
const adapter = createStubAdapter();
|
|
174
|
+
const driver = createMockDriver();
|
|
175
|
+
|
|
176
|
+
const targetDescriptor = createTestTargetDescriptor();
|
|
177
|
+
const adapterDescriptor = createTestAdapterDescriptor(adapter);
|
|
178
|
+
|
|
179
|
+
const stack = createSqlExecutionStack({
|
|
180
|
+
target: targetDescriptor,
|
|
181
|
+
adapter: adapterDescriptor,
|
|
182
|
+
extensionPacks: [],
|
|
183
|
+
});
|
|
184
|
+
type SqlTestStackInstance = ExecutionStackInstance<
|
|
185
|
+
'sql',
|
|
186
|
+
'postgres',
|
|
187
|
+
SqlRuntimeAdapterInstance<'postgres'>,
|
|
188
|
+
RuntimeDriverInstance<'sql', 'postgres'>,
|
|
189
|
+
RuntimeExtensionInstance<'sql', 'postgres'>
|
|
190
|
+
>;
|
|
191
|
+
const stackInstance = instantiateExecutionStack(stack) as SqlTestStackInstance;
|
|
192
|
+
|
|
193
|
+
const context = createExecutionContext({
|
|
194
|
+
contract: testContract,
|
|
195
|
+
stack: { target: targetDescriptor, adapter: adapterDescriptor, extensionPacks: [] },
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
return { stackInstance, context, driver };
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function createRawExecutionPlan<Row = Record<string, unknown>>(): ExecutionPlan<Row> {
|
|
87
202
|
return {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
203
|
+
sql: 'select 1',
|
|
204
|
+
params: [],
|
|
205
|
+
meta: {
|
|
206
|
+
target: testContract.target,
|
|
207
|
+
targetFamily: testContract.targetFamily,
|
|
208
|
+
storageHash: testContract.storageHash,
|
|
209
|
+
lane: 'raw',
|
|
210
|
+
paramDescriptors: [],
|
|
211
|
+
},
|
|
92
212
|
};
|
|
93
213
|
}
|
|
94
214
|
|
|
95
215
|
describe('createRuntime', () => {
|
|
96
|
-
it('creates runtime with
|
|
97
|
-
const context =
|
|
98
|
-
const driver = createMockDriver();
|
|
216
|
+
it('creates runtime with context and driver', () => {
|
|
217
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
99
218
|
|
|
100
219
|
const runtime = createRuntime({
|
|
220
|
+
stackInstance,
|
|
101
221
|
context,
|
|
102
222
|
driver,
|
|
103
223
|
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
@@ -111,10 +231,10 @@ describe('createRuntime', () => {
|
|
|
111
231
|
});
|
|
112
232
|
|
|
113
233
|
it('returns operations registry', () => {
|
|
114
|
-
const context =
|
|
115
|
-
const driver = createMockDriver();
|
|
234
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
116
235
|
|
|
117
236
|
const runtime = createRuntime({
|
|
237
|
+
stackInstance,
|
|
118
238
|
context,
|
|
119
239
|
driver,
|
|
120
240
|
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
@@ -126,24 +246,23 @@ describe('createRuntime', () => {
|
|
|
126
246
|
});
|
|
127
247
|
|
|
128
248
|
it('returns null telemetry when no events', () => {
|
|
129
|
-
const context =
|
|
130
|
-
const driver = createMockDriver();
|
|
249
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
131
250
|
|
|
132
251
|
const runtime = createRuntime({
|
|
252
|
+
stackInstance,
|
|
133
253
|
context,
|
|
134
254
|
driver,
|
|
135
255
|
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
136
256
|
});
|
|
137
257
|
|
|
138
|
-
// Before any execution, telemetry should be null
|
|
139
258
|
expect(runtime.telemetry()).toBeNull();
|
|
140
259
|
});
|
|
141
260
|
|
|
142
|
-
it('closes runtime', async () => {
|
|
143
|
-
const context =
|
|
144
|
-
const driver = createMockDriver();
|
|
261
|
+
it('closes runtime and driver', async () => {
|
|
262
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
145
263
|
|
|
146
264
|
const runtime = createRuntime({
|
|
265
|
+
stackInstance,
|
|
147
266
|
context,
|
|
148
267
|
driver,
|
|
149
268
|
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
@@ -152,4 +271,73 @@ describe('createRuntime', () => {
|
|
|
152
271
|
await runtime.close();
|
|
153
272
|
expect(driver.close).toHaveBeenCalled();
|
|
154
273
|
});
|
|
274
|
+
|
|
275
|
+
it('validates codec registry at startup when verify mode is startup', () => {
|
|
276
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
277
|
+
|
|
278
|
+
const runtime = createRuntime({
|
|
279
|
+
stackInstance,
|
|
280
|
+
context,
|
|
281
|
+
driver,
|
|
282
|
+
verify: { mode: 'startup', requireMarker: false },
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
expect(runtime).toBeDefined();
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it('uses acquired connection queryable for connection.execute', async () => {
|
|
289
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
290
|
+
const runtime = createRuntime({
|
|
291
|
+
stackInstance,
|
|
292
|
+
context,
|
|
293
|
+
driver,
|
|
294
|
+
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
const connection = await runtime.connection();
|
|
298
|
+
await connection.execute(createRawExecutionPlan()).toArray();
|
|
299
|
+
|
|
300
|
+
expect(driver.__spies.connectionExecute).toHaveBeenCalledTimes(1);
|
|
301
|
+
expect(driver.__spies.transactionExecute).not.toHaveBeenCalled();
|
|
302
|
+
expect(driver.__spies.rootExecute).not.toHaveBeenCalled();
|
|
303
|
+
|
|
304
|
+
await connection.release();
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it('uses transaction queryable for transaction.execute', async () => {
|
|
308
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
309
|
+
const runtime = createRuntime({
|
|
310
|
+
stackInstance,
|
|
311
|
+
context,
|
|
312
|
+
driver,
|
|
313
|
+
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const connection = await runtime.connection();
|
|
317
|
+
const transaction = await connection.transaction();
|
|
318
|
+
await transaction.execute(createRawExecutionPlan()).toArray();
|
|
319
|
+
|
|
320
|
+
expect(driver.__spies.transactionExecute).toHaveBeenCalledTimes(1);
|
|
321
|
+
expect(driver.__spies.connectionExecute).not.toHaveBeenCalled();
|
|
322
|
+
expect(driver.__spies.rootExecute).not.toHaveBeenCalled();
|
|
323
|
+
|
|
324
|
+
await transaction.rollback();
|
|
325
|
+
await connection.release();
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it('keeps root execute on driver queryable for runtime.execute', async () => {
|
|
329
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
330
|
+
const runtime = createRuntime({
|
|
331
|
+
stackInstance,
|
|
332
|
+
context,
|
|
333
|
+
driver,
|
|
334
|
+
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
await runtime.execute(createRawExecutionPlan()).toArray();
|
|
338
|
+
|
|
339
|
+
expect(driver.__spies.rootExecute).toHaveBeenCalledTimes(1);
|
|
340
|
+
expect(driver.__spies.connectionExecute).not.toHaveBeenCalled();
|
|
341
|
+
expect(driver.__spies.transactionExecute).not.toHaveBeenCalled();
|
|
342
|
+
});
|
|
155
343
|
});
|
package/test/utils.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { ExecutionPlan, ResultType } from '@prisma-next/contract/types';
|
|
2
|
+
import { coreHash, profileHash } from '@prisma-next/contract/types';
|
|
3
|
+
import { instantiateExecutionStack } from '@prisma-next/core-execution-plane/stack';
|
|
4
|
+
import type { RuntimeDriverDescriptor } from '@prisma-next/core-execution-plane/types';
|
|
2
5
|
import type { SqlContract, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
3
6
|
import type { Adapter, LoweredStatement, SelectAst } from '@prisma-next/sql-relational-core/ast';
|
|
4
7
|
import { codec, createCodecRegistry } from '@prisma-next/sql-relational-core/ast';
|
|
@@ -7,16 +10,20 @@ import { collectAsync, drainAsyncIterable } from '@prisma-next/test-utils';
|
|
|
7
10
|
import type { Client } from 'pg';
|
|
8
11
|
import type { SqlStatement } from '../src/exports';
|
|
9
12
|
import {
|
|
13
|
+
createExecutionContext,
|
|
10
14
|
type createRuntime,
|
|
11
|
-
|
|
15
|
+
createSqlExecutionStack,
|
|
12
16
|
ensureSchemaStatement,
|
|
13
17
|
ensureTableStatement,
|
|
14
18
|
writeContractMarker,
|
|
15
19
|
} from '../src/exports';
|
|
16
20
|
import type {
|
|
17
|
-
|
|
21
|
+
ExecutionContext,
|
|
22
|
+
SqlRuntimeAdapterDescriptor,
|
|
18
23
|
SqlRuntimeAdapterInstance,
|
|
24
|
+
SqlRuntimeDriverInstance,
|
|
19
25
|
SqlRuntimeExtensionDescriptor,
|
|
26
|
+
SqlRuntimeTargetDescriptor,
|
|
20
27
|
} from '../src/sql-context';
|
|
21
28
|
|
|
22
29
|
/**
|
|
@@ -71,8 +78,8 @@ export async function setupTestDatabase(
|
|
|
71
78
|
await executeStatement(client, ensureSchemaStatement);
|
|
72
79
|
await executeStatement(client, ensureTableStatement);
|
|
73
80
|
const write = writeContractMarker({
|
|
74
|
-
|
|
75
|
-
profileHash: contract.profileHash ?? contract.
|
|
81
|
+
storageHash: contract.storageHash,
|
|
82
|
+
profileHash: contract.profileHash ?? contract.storageHash,
|
|
76
83
|
contractJson: contract,
|
|
77
84
|
canonicalVersion: 1,
|
|
78
85
|
});
|
|
@@ -88,8 +95,8 @@ export async function writeTestContractMarker(
|
|
|
88
95
|
contract: SqlContract<SqlStorage>,
|
|
89
96
|
): Promise<void> {
|
|
90
97
|
const write = writeContractMarker({
|
|
91
|
-
|
|
92
|
-
profileHash: contract.profileHash ?? contract.
|
|
98
|
+
storageHash: contract.storageHash,
|
|
99
|
+
profileHash: contract.profileHash ?? contract.storageHash,
|
|
93
100
|
contractJson: contract,
|
|
94
101
|
canonicalVersion: 1,
|
|
95
102
|
});
|
|
@@ -98,56 +105,41 @@ export async function writeTestContractMarker(
|
|
|
98
105
|
|
|
99
106
|
/**
|
|
100
107
|
* Creates a test adapter descriptor from a raw adapter.
|
|
101
|
-
*
|
|
102
|
-
*
|
|
108
|
+
* Wraps the adapter in an SqlRuntimeAdapterDescriptor with static contributions
|
|
109
|
+
* derived from the adapter's codec registry.
|
|
103
110
|
*/
|
|
104
|
-
function createTestAdapterDescriptor(
|
|
111
|
+
export function createTestAdapterDescriptor(
|
|
105
112
|
adapter: Adapter<SelectAst, SqlContract<SqlStorage>, LoweredStatement>,
|
|
106
|
-
): {
|
|
107
|
-
|
|
108
|
-
readonly id: string;
|
|
109
|
-
readonly version: string;
|
|
110
|
-
readonly familyId: 'sql';
|
|
111
|
-
readonly targetId: 'postgres';
|
|
112
|
-
create(): SqlRuntimeAdapterInstance<'postgres'>;
|
|
113
|
-
} {
|
|
113
|
+
): SqlRuntimeAdapterDescriptor<'postgres'> {
|
|
114
|
+
const codecRegistry = adapter.profile.codecs();
|
|
114
115
|
return {
|
|
115
116
|
kind: 'adapter' as const,
|
|
116
117
|
id: 'test-adapter',
|
|
117
118
|
version: '0.0.1',
|
|
118
119
|
familyId: 'sql' as const,
|
|
119
120
|
targetId: 'postgres' as const,
|
|
121
|
+
codecs: () => codecRegistry,
|
|
122
|
+
operationSignatures: () => [],
|
|
123
|
+
parameterizedCodecs: () => [],
|
|
120
124
|
create(): SqlRuntimeAdapterInstance<'postgres'> {
|
|
121
|
-
|
|
122
|
-
return Object.assign(
|
|
123
|
-
{
|
|
124
|
-
familyId: 'sql' as const,
|
|
125
|
-
targetId: 'postgres' as const,
|
|
126
|
-
},
|
|
127
|
-
adapter,
|
|
128
|
-
);
|
|
125
|
+
return Object.assign({ familyId: 'sql' as const, targetId: 'postgres' as const }, adapter);
|
|
129
126
|
},
|
|
130
127
|
};
|
|
131
128
|
}
|
|
132
129
|
|
|
133
130
|
/**
|
|
134
|
-
* Creates a test target descriptor.
|
|
135
|
-
* This is a minimal descriptor for descriptor-first context creation in tests.
|
|
131
|
+
* Creates a test target descriptor with empty static contributions.
|
|
136
132
|
*/
|
|
137
|
-
function createTestTargetDescriptor(): {
|
|
138
|
-
readonly kind: 'target';
|
|
139
|
-
readonly id: string;
|
|
140
|
-
readonly version: string;
|
|
141
|
-
readonly familyId: 'sql';
|
|
142
|
-
readonly targetId: 'postgres';
|
|
143
|
-
create(): { readonly familyId: 'sql'; readonly targetId: 'postgres' };
|
|
144
|
-
} {
|
|
133
|
+
export function createTestTargetDescriptor(): SqlRuntimeTargetDescriptor<'postgres'> {
|
|
145
134
|
return {
|
|
146
135
|
kind: 'target' as const,
|
|
147
136
|
id: 'postgres',
|
|
148
137
|
version: '0.0.1',
|
|
149
138
|
familyId: 'sql' as const,
|
|
150
139
|
targetId: 'postgres' as const,
|
|
140
|
+
codecs: () => createCodecRegistry(),
|
|
141
|
+
operationSignatures: () => [],
|
|
142
|
+
parameterizedCodecs: () => [],
|
|
151
143
|
create() {
|
|
152
144
|
return { familyId: 'sql' as const, targetId: 'postgres' as const };
|
|
153
145
|
},
|
|
@@ -155,7 +147,7 @@ function createTestTargetDescriptor(): {
|
|
|
155
147
|
}
|
|
156
148
|
|
|
157
149
|
/**
|
|
158
|
-
* Creates
|
|
150
|
+
* Creates an ExecutionContext for testing.
|
|
159
151
|
* This helper DRYs up the common pattern of context creation in tests.
|
|
160
152
|
*
|
|
161
153
|
* Accepts a raw adapter and optional extension descriptors, wrapping the
|
|
@@ -167,13 +159,34 @@ export function createTestContext<TContract extends SqlContract<SqlStorage>>(
|
|
|
167
159
|
options?: {
|
|
168
160
|
extensionPacks?: ReadonlyArray<SqlRuntimeExtensionDescriptor<'postgres'>>;
|
|
169
161
|
},
|
|
170
|
-
):
|
|
171
|
-
return
|
|
162
|
+
): ExecutionContext<TContract> {
|
|
163
|
+
return createExecutionContext({
|
|
172
164
|
contract,
|
|
165
|
+
stack: {
|
|
166
|
+
target: createTestTargetDescriptor(),
|
|
167
|
+
adapter: createTestAdapterDescriptor(adapter),
|
|
168
|
+
extensionPacks: options?.extensionPacks ?? [],
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function createTestStackInstance(options?: {
|
|
174
|
+
extensionPacks?: ReadonlyArray<SqlRuntimeExtensionDescriptor<'postgres'>>;
|
|
175
|
+
driver?: RuntimeDriverDescriptor<
|
|
176
|
+
'sql',
|
|
177
|
+
'postgres',
|
|
178
|
+
unknown,
|
|
179
|
+
SqlRuntimeDriverInstance<'postgres'>
|
|
180
|
+
>;
|
|
181
|
+
}) {
|
|
182
|
+
const stack = createSqlExecutionStack({
|
|
173
183
|
target: createTestTargetDescriptor(),
|
|
174
|
-
adapter: createTestAdapterDescriptor(
|
|
184
|
+
adapter: createTestAdapterDescriptor(createStubAdapter()),
|
|
185
|
+
driver: options?.driver,
|
|
175
186
|
extensionPacks: options?.extensionPacks ?? [],
|
|
176
187
|
});
|
|
188
|
+
|
|
189
|
+
return instantiateExecutionStack(stack);
|
|
177
190
|
}
|
|
178
191
|
|
|
179
192
|
/**
|
|
@@ -212,8 +225,7 @@ export function createStubAdapter(): Adapter<SelectAst, SqlContract<SqlStorage>,
|
|
|
212
225
|
typeId: 'pg/timestamptz@1',
|
|
213
226
|
targetTypes: ['timestamptz'],
|
|
214
227
|
encode: (value: string | Date) => (value instanceof Date ? value.toISOString() : value),
|
|
215
|
-
decode: (wire: string | Date) =>
|
|
216
|
-
typeof wire === 'string' ? wire : wire instanceof Date ? wire.toISOString() : String(wire),
|
|
228
|
+
decode: (wire: string | Date) => (wire instanceof Date ? wire : new Date(wire)),
|
|
217
229
|
}),
|
|
218
230
|
);
|
|
219
231
|
|
|
@@ -238,18 +250,35 @@ export function createStubAdapter(): Adapter<SelectAst, SqlContract<SqlStorage>,
|
|
|
238
250
|
|
|
239
251
|
/**
|
|
240
252
|
* Creates a valid test contract without using validateContract.
|
|
241
|
-
* Ensures
|
|
253
|
+
* Ensures all required fields are present (mappings, capabilities, extensionPacks, meta, sources)
|
|
254
|
+
* and returns the contract with proper typing.
|
|
242
255
|
* This helper allows tests to create contracts without depending on sql-query.
|
|
243
256
|
*/
|
|
244
|
-
export function createTestContract
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
return
|
|
257
|
+
export function createTestContract(
|
|
258
|
+
contract: Partial<Omit<SqlContract<SqlStorage>, 'storageHash' | 'profileHash'>> & {
|
|
259
|
+
storageHash?: string;
|
|
260
|
+
profileHash?: string;
|
|
261
|
+
},
|
|
262
|
+
): SqlContract<SqlStorage> {
|
|
263
|
+
const { execution, ...rest } = contract;
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
...rest,
|
|
267
|
+
schemaVersion: rest.schemaVersion ?? '1',
|
|
268
|
+
target: rest.target ?? 'postgres',
|
|
269
|
+
targetFamily: rest.targetFamily ?? 'sql',
|
|
270
|
+
storage: rest.storage ?? { tables: {} },
|
|
271
|
+
models: rest.models ?? {},
|
|
272
|
+
relations: rest.relations ?? {},
|
|
273
|
+
mappings: rest.mappings ?? { codecTypes: {}, operationTypes: {} },
|
|
274
|
+
capabilities: rest.capabilities ?? {},
|
|
275
|
+
extensionPacks: rest.extensionPacks ?? {},
|
|
276
|
+
meta: rest.meta ?? {},
|
|
277
|
+
sources: rest.sources ?? {},
|
|
278
|
+
...(execution ? { execution } : {}),
|
|
279
|
+
storageHash: coreHash(rest.storageHash ?? 'sha256:testcore'),
|
|
280
|
+
profileHash: profileHash(rest.profileHash ?? 'sha256:testprofile'),
|
|
281
|
+
} satisfies SqlContract<SqlStorage>;
|
|
253
282
|
}
|
|
254
283
|
|
|
255
284
|
// Re-export generic utilities from test-utils
|