@prisma-next/sql-runtime 0.3.0-dev.12 → 0.3.0-dev.123
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 +141 -24
- package/dist/exports-BKjZvwMh.mjs +971 -0
- package/dist/exports-BKjZvwMh.mjs.map +1 -0
- package/dist/index-eHiENgIB.d.mts +182 -0
- package/dist/index-eHiENgIB.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 +221 -0
- package/dist/test/utils.mjs.map +1 -0
- package/package.json +29 -22
- package/src/codecs/decoding.ts +84 -3
- package/src/codecs/encoding.ts +5 -15
- package/src/codecs/json-schema-validation.ts +61 -0
- package/src/exports/index.ts +19 -7
- package/src/lower-sql-plan.ts +8 -8
- package/src/plugins/budgets.ts +375 -0
- package/src/plugins/lints.ts +211 -0
- package/src/sql-context.ts +448 -98
- package/src/sql-family-adapter.ts +9 -5
- package/src/sql-marker.ts +2 -2
- package/src/sql-runtime.ts +126 -30
- package/test/async-iterable-result.test.ts +43 -35
- package/test/budgets.test.ts +481 -0
- package/test/context.types.test-d.ts +68 -0
- package/test/execution-stack.test.ts +166 -0
- package/test/json-schema-validation.test.ts +575 -0
- package/test/lints.test.ts +161 -0
- package/test/mutation-default-generators.test.ts +256 -0
- package/test/parameterized-types.test.ts +536 -0
- package/test/sql-context.test.ts +293 -121
- package/test/sql-family-adapter.test.ts +8 -10
- package/test/sql-runtime.test.ts +219 -34
- package/test/utils.ts +90 -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: {} },
|
|
@@ -24,13 +34,17 @@ const testContract: SqlContract<SqlStorage> = {
|
|
|
24
34
|
capabilities: {},
|
|
25
35
|
meta: {},
|
|
26
36
|
sources: {},
|
|
27
|
-
mappings: {
|
|
28
|
-
codecTypes: {},
|
|
29
|
-
operationTypes: {},
|
|
30
|
-
},
|
|
37
|
+
mappings: {},
|
|
31
38
|
};
|
|
32
39
|
|
|
33
|
-
|
|
40
|
+
interface DriverExecuteSpies {
|
|
41
|
+
rootExecute: ReturnType<typeof vi.fn>;
|
|
42
|
+
connectionExecute: ReturnType<typeof vi.fn>;
|
|
43
|
+
transactionExecute: ReturnType<typeof vi.fn>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
type MockSqlDriver = SqlDriver & { __spies: DriverExecuteSpies };
|
|
47
|
+
|
|
34
48
|
function createStubCodecs(): CodecRegistry {
|
|
35
49
|
const registry = createCodecRegistry();
|
|
36
50
|
registry.register(
|
|
@@ -44,7 +58,6 @@ function createStubCodecs(): CodecRegistry {
|
|
|
44
58
|
return registry;
|
|
45
59
|
}
|
|
46
60
|
|
|
47
|
-
// Create a stub adapter
|
|
48
61
|
function createStubAdapter() {
|
|
49
62
|
const codecs = createStubCodecs();
|
|
50
63
|
return {
|
|
@@ -67,37 +80,141 @@ function createStubAdapter() {
|
|
|
67
80
|
};
|
|
68
81
|
}
|
|
69
82
|
|
|
70
|
-
|
|
71
|
-
function
|
|
72
|
-
const execute = vi.fn().mockImplementation(async function* (_request: SqlExecuteRequest) {
|
|
83
|
+
function createMockDriver(): MockSqlDriver {
|
|
84
|
+
const rootExecute = vi.fn().mockImplementation(async function* (_request: SqlExecuteRequest) {
|
|
73
85
|
yield { id: 1 };
|
|
74
86
|
});
|
|
87
|
+
const connectionExecute = vi.fn().mockImplementation(async function* (
|
|
88
|
+
_request: SqlExecuteRequest,
|
|
89
|
+
) {
|
|
90
|
+
yield { id: 2 };
|
|
91
|
+
});
|
|
92
|
+
const transactionExecute = vi.fn().mockImplementation(async function* (
|
|
93
|
+
_request: SqlExecuteRequest,
|
|
94
|
+
) {
|
|
95
|
+
yield { id: 3 };
|
|
96
|
+
});
|
|
75
97
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
98
|
+
const query = vi.fn().mockResolvedValue({ rows: [], rowCount: 0 });
|
|
99
|
+
|
|
100
|
+
const transaction = {
|
|
101
|
+
execute: transactionExecute,
|
|
102
|
+
query,
|
|
103
|
+
commit: vi.fn().mockResolvedValue(undefined),
|
|
104
|
+
rollback: vi.fn().mockResolvedValue(undefined),
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const connection = {
|
|
108
|
+
execute: connectionExecute,
|
|
109
|
+
query,
|
|
110
|
+
release: vi.fn().mockResolvedValue(undefined),
|
|
111
|
+
beginTransaction: vi.fn().mockResolvedValue(transaction),
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const driver: SqlDriver = {
|
|
115
|
+
execute: rootExecute,
|
|
116
|
+
query,
|
|
117
|
+
connect: vi.fn().mockImplementation(async (_binding?: undefined) => undefined),
|
|
118
|
+
acquireConnection: vi.fn().mockResolvedValue(connection),
|
|
80
119
|
close: vi.fn().mockResolvedValue(undefined),
|
|
81
120
|
};
|
|
121
|
+
|
|
122
|
+
return Object.assign(driver, {
|
|
123
|
+
__spies: {
|
|
124
|
+
rootExecute,
|
|
125
|
+
connectionExecute,
|
|
126
|
+
transactionExecute,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
82
129
|
}
|
|
83
130
|
|
|
84
|
-
|
|
85
|
-
|
|
131
|
+
function createTestTargetDescriptor(): SqlRuntimeTargetDescriptor<'postgres'> {
|
|
132
|
+
return {
|
|
133
|
+
kind: 'target',
|
|
134
|
+
id: 'postgres',
|
|
135
|
+
version: '0.0.1',
|
|
136
|
+
familyId: 'sql' as const,
|
|
137
|
+
targetId: 'postgres' as const,
|
|
138
|
+
codecs: () => createCodecRegistry(),
|
|
139
|
+
operationSignatures: () => [],
|
|
140
|
+
parameterizedCodecs: () => [],
|
|
141
|
+
create() {
|
|
142
|
+
return { familyId: 'sql' as const, targetId: 'postgres' as const };
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function createTestAdapterDescriptor(
|
|
148
|
+
adapter: ReturnType<typeof createStubAdapter>,
|
|
149
|
+
): SqlRuntimeAdapterDescriptor<'postgres'> {
|
|
150
|
+
const codecRegistry = adapter.profile.codecs();
|
|
151
|
+
return {
|
|
152
|
+
kind: 'adapter',
|
|
153
|
+
id: 'test-adapter',
|
|
154
|
+
version: '0.0.1',
|
|
155
|
+
familyId: 'sql' as const,
|
|
156
|
+
targetId: 'postgres' as const,
|
|
157
|
+
codecs: () => codecRegistry,
|
|
158
|
+
operationSignatures: () => [],
|
|
159
|
+
parameterizedCodecs: () => [],
|
|
160
|
+
create() {
|
|
161
|
+
return Object.assign(
|
|
162
|
+
{ familyId: 'sql' as const, targetId: 'postgres' as const },
|
|
163
|
+
adapter,
|
|
164
|
+
) as SqlRuntimeAdapterInstance<'postgres'>;
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function createTestSetup() {
|
|
86
170
|
const adapter = createStubAdapter();
|
|
171
|
+
const driver = createMockDriver();
|
|
172
|
+
|
|
173
|
+
const targetDescriptor = createTestTargetDescriptor();
|
|
174
|
+
const adapterDescriptor = createTestAdapterDescriptor(adapter);
|
|
175
|
+
|
|
176
|
+
const stack = createSqlExecutionStack({
|
|
177
|
+
target: targetDescriptor,
|
|
178
|
+
adapter: adapterDescriptor,
|
|
179
|
+
extensionPacks: [],
|
|
180
|
+
});
|
|
181
|
+
type SqlTestStackInstance = ExecutionStackInstance<
|
|
182
|
+
'sql',
|
|
183
|
+
'postgres',
|
|
184
|
+
SqlRuntimeAdapterInstance<'postgres'>,
|
|
185
|
+
RuntimeDriverInstance<'sql', 'postgres'>,
|
|
186
|
+
RuntimeExtensionInstance<'sql', 'postgres'>
|
|
187
|
+
>;
|
|
188
|
+
const stackInstance = instantiateExecutionStack(stack) as SqlTestStackInstance;
|
|
189
|
+
|
|
190
|
+
const context = createExecutionContext({
|
|
191
|
+
contract: testContract,
|
|
192
|
+
stack: { target: targetDescriptor, adapter: adapterDescriptor, extensionPacks: [] },
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
return { stackInstance, context, driver };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function createRawExecutionPlan<Row = Record<string, unknown>>(): ExecutionPlan<Row> {
|
|
87
199
|
return {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
200
|
+
sql: 'select 1',
|
|
201
|
+
params: [],
|
|
202
|
+
meta: {
|
|
203
|
+
target: testContract.target,
|
|
204
|
+
targetFamily: testContract.targetFamily,
|
|
205
|
+
storageHash: testContract.storageHash,
|
|
206
|
+
lane: 'raw',
|
|
207
|
+
paramDescriptors: [],
|
|
208
|
+
},
|
|
92
209
|
};
|
|
93
210
|
}
|
|
94
211
|
|
|
95
212
|
describe('createRuntime', () => {
|
|
96
|
-
it('creates runtime with
|
|
97
|
-
const context =
|
|
98
|
-
const driver = createMockDriver();
|
|
213
|
+
it('creates runtime with context and driver', () => {
|
|
214
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
99
215
|
|
|
100
216
|
const runtime = createRuntime({
|
|
217
|
+
stackInstance,
|
|
101
218
|
context,
|
|
102
219
|
driver,
|
|
103
220
|
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
@@ -111,10 +228,10 @@ describe('createRuntime', () => {
|
|
|
111
228
|
});
|
|
112
229
|
|
|
113
230
|
it('returns operations registry', () => {
|
|
114
|
-
const context =
|
|
115
|
-
const driver = createMockDriver();
|
|
231
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
116
232
|
|
|
117
233
|
const runtime = createRuntime({
|
|
234
|
+
stackInstance,
|
|
118
235
|
context,
|
|
119
236
|
driver,
|
|
120
237
|
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
@@ -126,24 +243,23 @@ describe('createRuntime', () => {
|
|
|
126
243
|
});
|
|
127
244
|
|
|
128
245
|
it('returns null telemetry when no events', () => {
|
|
129
|
-
const context =
|
|
130
|
-
const driver = createMockDriver();
|
|
246
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
131
247
|
|
|
132
248
|
const runtime = createRuntime({
|
|
249
|
+
stackInstance,
|
|
133
250
|
context,
|
|
134
251
|
driver,
|
|
135
252
|
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
136
253
|
});
|
|
137
254
|
|
|
138
|
-
// Before any execution, telemetry should be null
|
|
139
255
|
expect(runtime.telemetry()).toBeNull();
|
|
140
256
|
});
|
|
141
257
|
|
|
142
|
-
it('closes runtime', async () => {
|
|
143
|
-
const context =
|
|
144
|
-
const driver = createMockDriver();
|
|
258
|
+
it('closes runtime and driver', async () => {
|
|
259
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
145
260
|
|
|
146
261
|
const runtime = createRuntime({
|
|
262
|
+
stackInstance,
|
|
147
263
|
context,
|
|
148
264
|
driver,
|
|
149
265
|
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
@@ -152,4 +268,73 @@ describe('createRuntime', () => {
|
|
|
152
268
|
await runtime.close();
|
|
153
269
|
expect(driver.close).toHaveBeenCalled();
|
|
154
270
|
});
|
|
271
|
+
|
|
272
|
+
it('validates codec registry at startup when verify mode is startup', () => {
|
|
273
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
274
|
+
|
|
275
|
+
const runtime = createRuntime({
|
|
276
|
+
stackInstance,
|
|
277
|
+
context,
|
|
278
|
+
driver,
|
|
279
|
+
verify: { mode: 'startup', requireMarker: false },
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
expect(runtime).toBeDefined();
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it('uses acquired connection queryable for connection.execute', async () => {
|
|
286
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
287
|
+
const runtime = createRuntime({
|
|
288
|
+
stackInstance,
|
|
289
|
+
context,
|
|
290
|
+
driver,
|
|
291
|
+
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
const connection = await runtime.connection();
|
|
295
|
+
await connection.execute(createRawExecutionPlan()).toArray();
|
|
296
|
+
|
|
297
|
+
expect(driver.__spies.connectionExecute).toHaveBeenCalledTimes(1);
|
|
298
|
+
expect(driver.__spies.transactionExecute).not.toHaveBeenCalled();
|
|
299
|
+
expect(driver.__spies.rootExecute).not.toHaveBeenCalled();
|
|
300
|
+
|
|
301
|
+
await connection.release();
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('uses transaction queryable for transaction.execute', async () => {
|
|
305
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
306
|
+
const runtime = createRuntime({
|
|
307
|
+
stackInstance,
|
|
308
|
+
context,
|
|
309
|
+
driver,
|
|
310
|
+
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
const connection = await runtime.connection();
|
|
314
|
+
const transaction = await connection.transaction();
|
|
315
|
+
await transaction.execute(createRawExecutionPlan()).toArray();
|
|
316
|
+
|
|
317
|
+
expect(driver.__spies.transactionExecute).toHaveBeenCalledTimes(1);
|
|
318
|
+
expect(driver.__spies.connectionExecute).not.toHaveBeenCalled();
|
|
319
|
+
expect(driver.__spies.rootExecute).not.toHaveBeenCalled();
|
|
320
|
+
|
|
321
|
+
await transaction.rollback();
|
|
322
|
+
await connection.release();
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it('keeps root execute on driver queryable for runtime.execute', async () => {
|
|
326
|
+
const { stackInstance, context, driver } = createTestSetup();
|
|
327
|
+
const runtime = createRuntime({
|
|
328
|
+
stackInstance,
|
|
329
|
+
context,
|
|
330
|
+
driver,
|
|
331
|
+
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
await runtime.execute(createRawExecutionPlan()).toArray();
|
|
335
|
+
|
|
336
|
+
expect(driver.__spies.rootExecute).toHaveBeenCalledTimes(1);
|
|
337
|
+
expect(driver.__spies.connectionExecute).not.toHaveBeenCalled();
|
|
338
|
+
expect(driver.__spies.transactionExecute).not.toHaveBeenCalled();
|
|
339
|
+
});
|
|
155
340
|
});
|
package/test/utils.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
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';
|
|
5
|
+
import { builtinGeneratorIds } from '@prisma-next/ids';
|
|
6
|
+
import { generateId } from '@prisma-next/ids/runtime';
|
|
2
7
|
import type { SqlContract, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
3
8
|
import type { Adapter, LoweredStatement, SelectAst } from '@prisma-next/sql-relational-core/ast';
|
|
4
9
|
import { codec, createCodecRegistry } from '@prisma-next/sql-relational-core/ast';
|
|
@@ -7,18 +12,29 @@ import { collectAsync, drainAsyncIterable } from '@prisma-next/test-utils';
|
|
|
7
12
|
import type { Client } from 'pg';
|
|
8
13
|
import type { SqlStatement } from '../src/exports';
|
|
9
14
|
import {
|
|
15
|
+
createExecutionContext,
|
|
10
16
|
type createRuntime,
|
|
11
|
-
|
|
17
|
+
createSqlExecutionStack,
|
|
12
18
|
ensureSchemaStatement,
|
|
13
19
|
ensureTableStatement,
|
|
14
20
|
writeContractMarker,
|
|
15
21
|
} from '../src/exports';
|
|
16
22
|
import type {
|
|
17
|
-
|
|
23
|
+
ExecutionContext,
|
|
24
|
+
SqlRuntimeAdapterDescriptor,
|
|
18
25
|
SqlRuntimeAdapterInstance,
|
|
26
|
+
SqlRuntimeDriverInstance,
|
|
19
27
|
SqlRuntimeExtensionDescriptor,
|
|
28
|
+
SqlRuntimeTargetDescriptor,
|
|
20
29
|
} from '../src/sql-context';
|
|
21
30
|
|
|
31
|
+
function createTestMutationDefaultGenerators() {
|
|
32
|
+
return builtinGeneratorIds.map((id) => ({
|
|
33
|
+
id,
|
|
34
|
+
generate: (params?: Record<string, unknown>) => generateId(params ? { id, params } : { id }),
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
|
|
22
38
|
/**
|
|
23
39
|
* Executes a plan and collects all results into an array.
|
|
24
40
|
* This helper DRYs up the common pattern of executing plans in tests.
|
|
@@ -71,8 +87,8 @@ export async function setupTestDatabase(
|
|
|
71
87
|
await executeStatement(client, ensureSchemaStatement);
|
|
72
88
|
await executeStatement(client, ensureTableStatement);
|
|
73
89
|
const write = writeContractMarker({
|
|
74
|
-
|
|
75
|
-
profileHash: contract.profileHash ?? contract.
|
|
90
|
+
storageHash: contract.storageHash,
|
|
91
|
+
profileHash: contract.profileHash ?? contract.storageHash,
|
|
76
92
|
contractJson: contract,
|
|
77
93
|
canonicalVersion: 1,
|
|
78
94
|
});
|
|
@@ -88,8 +104,8 @@ export async function writeTestContractMarker(
|
|
|
88
104
|
contract: SqlContract<SqlStorage>,
|
|
89
105
|
): Promise<void> {
|
|
90
106
|
const write = writeContractMarker({
|
|
91
|
-
|
|
92
|
-
profileHash: contract.profileHash ?? contract.
|
|
107
|
+
storageHash: contract.storageHash,
|
|
108
|
+
profileHash: contract.profileHash ?? contract.storageHash,
|
|
93
109
|
contractJson: contract,
|
|
94
110
|
canonicalVersion: 1,
|
|
95
111
|
});
|
|
@@ -98,56 +114,42 @@ export async function writeTestContractMarker(
|
|
|
98
114
|
|
|
99
115
|
/**
|
|
100
116
|
* Creates a test adapter descriptor from a raw adapter.
|
|
101
|
-
*
|
|
102
|
-
*
|
|
117
|
+
* Wraps the adapter in an SqlRuntimeAdapterDescriptor with static contributions
|
|
118
|
+
* derived from the adapter's codec registry.
|
|
103
119
|
*/
|
|
104
|
-
function createTestAdapterDescriptor(
|
|
120
|
+
export function createTestAdapterDescriptor(
|
|
105
121
|
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
|
-
} {
|
|
122
|
+
): SqlRuntimeAdapterDescriptor<'postgres'> {
|
|
123
|
+
const codecRegistry = adapter.profile.codecs();
|
|
114
124
|
return {
|
|
115
125
|
kind: 'adapter' as const,
|
|
116
126
|
id: 'test-adapter',
|
|
117
127
|
version: '0.0.1',
|
|
118
128
|
familyId: 'sql' as const,
|
|
119
129
|
targetId: 'postgres' as const,
|
|
130
|
+
codecs: () => codecRegistry,
|
|
131
|
+
operationSignatures: () => [],
|
|
132
|
+
parameterizedCodecs: () => [],
|
|
133
|
+
mutationDefaultGenerators: createTestMutationDefaultGenerators,
|
|
120
134
|
create(): SqlRuntimeAdapterInstance<'postgres'> {
|
|
121
|
-
|
|
122
|
-
return Object.assign(
|
|
123
|
-
{
|
|
124
|
-
familyId: 'sql' as const,
|
|
125
|
-
targetId: 'postgres' as const,
|
|
126
|
-
},
|
|
127
|
-
adapter,
|
|
128
|
-
);
|
|
135
|
+
return Object.assign({ familyId: 'sql' as const, targetId: 'postgres' as const }, adapter);
|
|
129
136
|
},
|
|
130
137
|
};
|
|
131
138
|
}
|
|
132
139
|
|
|
133
140
|
/**
|
|
134
|
-
* Creates a test target descriptor.
|
|
135
|
-
* This is a minimal descriptor for descriptor-first context creation in tests.
|
|
141
|
+
* Creates a test target descriptor with empty static contributions.
|
|
136
142
|
*/
|
|
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
|
-
} {
|
|
143
|
+
export function createTestTargetDescriptor(): SqlRuntimeTargetDescriptor<'postgres'> {
|
|
145
144
|
return {
|
|
146
145
|
kind: 'target' as const,
|
|
147
146
|
id: 'postgres',
|
|
148
147
|
version: '0.0.1',
|
|
149
148
|
familyId: 'sql' as const,
|
|
150
149
|
targetId: 'postgres' as const,
|
|
150
|
+
codecs: () => createCodecRegistry(),
|
|
151
|
+
operationSignatures: () => [],
|
|
152
|
+
parameterizedCodecs: () => [],
|
|
151
153
|
create() {
|
|
152
154
|
return { familyId: 'sql' as const, targetId: 'postgres' as const };
|
|
153
155
|
},
|
|
@@ -155,7 +157,7 @@ function createTestTargetDescriptor(): {
|
|
|
155
157
|
}
|
|
156
158
|
|
|
157
159
|
/**
|
|
158
|
-
* Creates
|
|
160
|
+
* Creates an ExecutionContext for testing.
|
|
159
161
|
* This helper DRYs up the common pattern of context creation in tests.
|
|
160
162
|
*
|
|
161
163
|
* Accepts a raw adapter and optional extension descriptors, wrapping the
|
|
@@ -167,13 +169,34 @@ export function createTestContext<TContract extends SqlContract<SqlStorage>>(
|
|
|
167
169
|
options?: {
|
|
168
170
|
extensionPacks?: ReadonlyArray<SqlRuntimeExtensionDescriptor<'postgres'>>;
|
|
169
171
|
},
|
|
170
|
-
):
|
|
171
|
-
return
|
|
172
|
+
): ExecutionContext<TContract> {
|
|
173
|
+
return createExecutionContext({
|
|
172
174
|
contract,
|
|
175
|
+
stack: {
|
|
176
|
+
target: createTestTargetDescriptor(),
|
|
177
|
+
adapter: createTestAdapterDescriptor(adapter),
|
|
178
|
+
extensionPacks: options?.extensionPacks ?? [],
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export function createTestStackInstance(options?: {
|
|
184
|
+
extensionPacks?: ReadonlyArray<SqlRuntimeExtensionDescriptor<'postgres'>>;
|
|
185
|
+
driver?: RuntimeDriverDescriptor<
|
|
186
|
+
'sql',
|
|
187
|
+
'postgres',
|
|
188
|
+
unknown,
|
|
189
|
+
SqlRuntimeDriverInstance<'postgres'>
|
|
190
|
+
>;
|
|
191
|
+
}) {
|
|
192
|
+
const stack = createSqlExecutionStack({
|
|
173
193
|
target: createTestTargetDescriptor(),
|
|
174
|
-
adapter: createTestAdapterDescriptor(
|
|
194
|
+
adapter: createTestAdapterDescriptor(createStubAdapter()),
|
|
195
|
+
driver: options?.driver,
|
|
175
196
|
extensionPacks: options?.extensionPacks ?? [],
|
|
176
197
|
});
|
|
198
|
+
|
|
199
|
+
return instantiateExecutionStack(stack);
|
|
177
200
|
}
|
|
178
201
|
|
|
179
202
|
/**
|
|
@@ -212,8 +235,7 @@ export function createStubAdapter(): Adapter<SelectAst, SqlContract<SqlStorage>,
|
|
|
212
235
|
typeId: 'pg/timestamptz@1',
|
|
213
236
|
targetTypes: ['timestamptz'],
|
|
214
237
|
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),
|
|
238
|
+
decode: (wire: string | Date) => (wire instanceof Date ? wire : new Date(wire)),
|
|
217
239
|
}),
|
|
218
240
|
);
|
|
219
241
|
|
|
@@ -238,18 +260,35 @@ export function createStubAdapter(): Adapter<SelectAst, SqlContract<SqlStorage>,
|
|
|
238
260
|
|
|
239
261
|
/**
|
|
240
262
|
* Creates a valid test contract without using validateContract.
|
|
241
|
-
* Ensures
|
|
263
|
+
* Ensures all required fields are present (mappings, capabilities, extensionPacks, meta, sources)
|
|
264
|
+
* and returns the contract with proper typing.
|
|
242
265
|
* This helper allows tests to create contracts without depending on sql-query.
|
|
243
266
|
*/
|
|
244
|
-
export function createTestContract
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
return
|
|
267
|
+
export function createTestContract(
|
|
268
|
+
contract: Partial<Omit<SqlContract<SqlStorage>, 'storageHash' | 'profileHash'>> & {
|
|
269
|
+
storageHash?: string;
|
|
270
|
+
profileHash?: string;
|
|
271
|
+
},
|
|
272
|
+
): SqlContract<SqlStorage> {
|
|
273
|
+
const { execution, ...rest } = contract;
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
...rest,
|
|
277
|
+
schemaVersion: rest.schemaVersion ?? '1',
|
|
278
|
+
target: rest.target ?? 'postgres',
|
|
279
|
+
targetFamily: rest.targetFamily ?? 'sql',
|
|
280
|
+
storage: rest.storage ?? { tables: {} },
|
|
281
|
+
models: rest.models ?? {},
|
|
282
|
+
relations: rest.relations ?? {},
|
|
283
|
+
mappings: rest.mappings ?? {},
|
|
284
|
+
capabilities: rest.capabilities ?? {},
|
|
285
|
+
extensionPacks: rest.extensionPacks ?? {},
|
|
286
|
+
meta: rest.meta ?? {},
|
|
287
|
+
sources: rest.sources ?? {},
|
|
288
|
+
...(execution ? { execution } : {}),
|
|
289
|
+
storageHash: coreHash(rest.storageHash ?? 'sha256:testcore'),
|
|
290
|
+
profileHash: profileHash(rest.profileHash ?? 'sha256:testprofile'),
|
|
291
|
+
} satisfies SqlContract<SqlStorage>;
|
|
253
292
|
}
|
|
254
293
|
|
|
255
294
|
// Re-export generic utilities from test-utils
|