@prisma-next/sql-runtime 0.3.0-pr.99.6 → 0.4.0-dev.1
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-BO6Fl7yn.mjs +889 -0
- package/dist/exports-BO6Fl7yn.mjs.map +1 -0
- package/dist/index-n6z6trta.d.mts +186 -0
- package/dist/index-n6z6trta.d.mts.map +1 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +3 -0
- package/dist/test/utils.d.mts +77 -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 +26 -20
- 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/codecs/validation.ts +7 -6
- package/src/exports/index.ts +20 -9
- package/src/lower-sql-plan.ts +9 -9
- package/src/middleware/budgets.ts +256 -0
- package/src/middleware/lints.ts +192 -0
- package/src/middleware/sql-middleware.ts +26 -0
- package/src/sql-context.ts +357 -257
- package/src/sql-family-adapter.ts +17 -23
- package/src/sql-marker.ts +2 -2
- package/src/sql-runtime.ts +136 -61
- package/test/async-iterable-result.test.ts +42 -37
- package/test/budgets.test.ts +431 -0
- package/test/context.types.test-d.ts +18 -20
- package/test/execution-stack.test.ts +164 -0
- package/test/json-schema-validation.test.ts +571 -0
- package/test/lints.test.ts +159 -0
- package/test/mutation-default-generators.test.ts +254 -0
- package/test/parameterized-types.test.ts +181 -205
- package/test/sql-context.test.ts +301 -134
- package/test/sql-family-adapter.test.ts +37 -20
- package/test/sql-runtime.test.ts +261 -49
- package/test/utils.ts +101 -67
- 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-APA6GHYY.js +0 -537
- package/dist/chunk-APA6GHYY.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 -130
- 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 -60
- package/dist/test/utils.d.ts.map +0 -1
- package/dist/test/utils.js +0 -24635
- 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
|
@@ -1,28 +1,18 @@
|
|
|
1
|
-
import type { ExecutionPlan } from '@prisma-next/contract/types';
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from '@prisma-next/runtime-executor';
|
|
7
|
-
import { runtimeError } from '@prisma-next/runtime-executor';
|
|
8
|
-
import type { SqlContract, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
9
|
-
import { readContractMarker } from './sql-marker';
|
|
1
|
+
import type { Contract, ExecutionPlan } from '@prisma-next/contract/types';
|
|
2
|
+
import { runtimeError } from '@prisma-next/framework-components/runtime';
|
|
3
|
+
import type { MarkerReader, RuntimeFamilyAdapter } from '@prisma-next/runtime-executor';
|
|
4
|
+
import type { SqlStorage } from '@prisma-next/sql-contract/types';
|
|
5
|
+
import type { AdapterProfile } from '@prisma-next/sql-relational-core/ast';
|
|
10
6
|
|
|
11
|
-
class
|
|
12
|
-
readMarkerStatement(): MarkerStatement {
|
|
13
|
-
return readContractMarker();
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class SqlFamilyAdapter<TContract extends SqlContract<SqlStorage>>
|
|
7
|
+
export class SqlFamilyAdapter<TContract extends Contract<SqlStorage>>
|
|
18
8
|
implements RuntimeFamilyAdapter<TContract>
|
|
19
9
|
{
|
|
20
10
|
readonly contract: TContract;
|
|
21
11
|
readonly markerReader: MarkerReader;
|
|
22
12
|
|
|
23
|
-
constructor(contract: TContract) {
|
|
13
|
+
constructor(contract: TContract, adapterProfile: AdapterProfile) {
|
|
24
14
|
this.contract = contract;
|
|
25
|
-
this.markerReader =
|
|
15
|
+
this.markerReader = adapterProfile;
|
|
26
16
|
}
|
|
27
17
|
|
|
28
18
|
validatePlan(plan: ExecutionPlan, contract: TContract): void {
|
|
@@ -33,11 +23,15 @@ export class SqlFamilyAdapter<TContract extends SqlContract<SqlStorage>>
|
|
|
33
23
|
});
|
|
34
24
|
}
|
|
35
25
|
|
|
36
|
-
if (plan.meta.
|
|
37
|
-
throw runtimeError(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
26
|
+
if (plan.meta.storageHash !== contract.storage.storageHash) {
|
|
27
|
+
throw runtimeError(
|
|
28
|
+
'PLAN.HASH_MISMATCH',
|
|
29
|
+
'Plan storage hash does not match runtime contract',
|
|
30
|
+
{
|
|
31
|
+
planStorageHash: plan.meta.storageHash,
|
|
32
|
+
runtimeStorageHash: contract.storage.storageHash,
|
|
33
|
+
},
|
|
34
|
+
);
|
|
41
35
|
}
|
|
42
36
|
}
|
|
43
37
|
}
|
package/src/sql-marker.ts
CHANGED
|
@@ -6,7 +6,7 @@ export interface SqlStatement {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export interface WriteMarkerInput {
|
|
9
|
-
readonly
|
|
9
|
+
readonly storageHash: string;
|
|
10
10
|
readonly profileHash: string;
|
|
11
11
|
readonly contractJson?: unknown;
|
|
12
12
|
readonly canonicalVersion?: number;
|
|
@@ -57,7 +57,7 @@ export interface WriteContractMarkerStatements {
|
|
|
57
57
|
export function writeContractMarker(input: WriteMarkerInput): WriteContractMarkerStatements {
|
|
58
58
|
const baseParams: readonly unknown[] = [
|
|
59
59
|
1,
|
|
60
|
-
input.
|
|
60
|
+
input.storageHash,
|
|
61
61
|
input.profileHash,
|
|
62
62
|
input.contractJson ?? null,
|
|
63
63
|
input.canonicalVersion ?? null,
|
package/src/sql-runtime.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import type { ExecutionPlan } from '@prisma-next/contract/types';
|
|
2
|
-
import type {
|
|
1
|
+
import type { Contract, ExecutionPlan } from '@prisma-next/contract/types';
|
|
2
|
+
import type {
|
|
3
|
+
ExecutionStackInstance,
|
|
4
|
+
RuntimeDriverInstance,
|
|
5
|
+
} from '@prisma-next/framework-components/execution';
|
|
6
|
+
import { checkMiddlewareCompatibility } from '@prisma-next/framework-components/runtime';
|
|
3
7
|
import type {
|
|
4
8
|
Log,
|
|
5
|
-
|
|
9
|
+
Middleware,
|
|
6
10
|
RuntimeCore,
|
|
7
11
|
RuntimeCoreOptions,
|
|
8
12
|
RuntimeTelemetryEvent,
|
|
@@ -10,86 +14,118 @@ import type {
|
|
|
10
14
|
TelemetryOutcome,
|
|
11
15
|
} from '@prisma-next/runtime-executor';
|
|
12
16
|
import { AsyncIterableResult, createRuntimeCore } from '@prisma-next/runtime-executor';
|
|
13
|
-
import type {
|
|
17
|
+
import type { SqlStorage } from '@prisma-next/sql-contract/types';
|
|
14
18
|
import type {
|
|
15
19
|
Adapter,
|
|
20
|
+
AnyQueryAst,
|
|
16
21
|
CodecRegistry,
|
|
17
22
|
LoweredStatement,
|
|
18
|
-
SelectAst,
|
|
19
23
|
SqlDriver,
|
|
20
24
|
} from '@prisma-next/sql-relational-core/ast';
|
|
21
25
|
import type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';
|
|
26
|
+
import type { JsonSchemaValidatorRegistry } from '@prisma-next/sql-relational-core/query-lane-context';
|
|
27
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
22
28
|
import { decodeRow } from './codecs/decoding';
|
|
23
29
|
import { encodeParams } from './codecs/encoding';
|
|
24
30
|
import { validateCodecRegistryCompleteness } from './codecs/validation';
|
|
25
31
|
import { lowerSqlPlan } from './lower-sql-plan';
|
|
26
|
-
import type {
|
|
32
|
+
import type {
|
|
33
|
+
ExecutionContext,
|
|
34
|
+
SqlRuntimeAdapterInstance,
|
|
35
|
+
SqlRuntimeExtensionInstance,
|
|
36
|
+
} from './sql-context';
|
|
27
37
|
import { SqlFamilyAdapter } from './sql-family-adapter';
|
|
28
38
|
|
|
29
|
-
export interface RuntimeOptions<
|
|
30
|
-
|
|
39
|
+
export interface RuntimeOptions<TContract extends Contract<SqlStorage> = Contract<SqlStorage>> {
|
|
40
|
+
readonly context: ExecutionContext<TContract>;
|
|
41
|
+
readonly adapter: Adapter<AnyQueryAst, Contract<SqlStorage>, LoweredStatement>;
|
|
42
|
+
readonly driver: SqlDriver<unknown>;
|
|
43
|
+
readonly verify: RuntimeVerifyOptions;
|
|
44
|
+
readonly middleware?: readonly Middleware<TContract>[];
|
|
45
|
+
readonly mode?: 'strict' | 'permissive';
|
|
46
|
+
readonly log?: Log;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface CreateRuntimeOptions<
|
|
50
|
+
TContract extends Contract<SqlStorage> = Contract<SqlStorage>,
|
|
51
|
+
TTargetId extends string = string,
|
|
31
52
|
> {
|
|
32
|
-
readonly
|
|
53
|
+
readonly stackInstance: ExecutionStackInstance<
|
|
54
|
+
'sql',
|
|
55
|
+
TTargetId,
|
|
56
|
+
SqlRuntimeAdapterInstance<TTargetId>,
|
|
57
|
+
RuntimeDriverInstance<'sql', TTargetId>,
|
|
58
|
+
SqlRuntimeExtensionInstance<TTargetId>
|
|
59
|
+
>;
|
|
60
|
+
readonly context: ExecutionContext<TContract>;
|
|
61
|
+
readonly driver: SqlDriver<unknown>;
|
|
33
62
|
readonly verify: RuntimeVerifyOptions;
|
|
34
|
-
readonly
|
|
35
|
-
readonly plugins?: readonly Plugin<
|
|
36
|
-
TContract,
|
|
37
|
-
Adapter<SelectAst, SqlContract<SqlStorage>, LoweredStatement>,
|
|
38
|
-
SqlDriver
|
|
39
|
-
>[];
|
|
63
|
+
readonly middleware?: readonly Middleware<TContract>[];
|
|
40
64
|
readonly mode?: 'strict' | 'permissive';
|
|
41
65
|
readonly log?: Log;
|
|
42
66
|
}
|
|
43
67
|
|
|
44
|
-
export interface Runtime {
|
|
68
|
+
export interface Runtime extends RuntimeQueryable {
|
|
69
|
+
connection(): Promise<RuntimeConnection>;
|
|
70
|
+
telemetry(): RuntimeTelemetryEvent | null;
|
|
71
|
+
close(): Promise<void>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface RuntimeConnection extends RuntimeQueryable {
|
|
75
|
+
transaction(): Promise<RuntimeTransaction>;
|
|
76
|
+
release(): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface RuntimeTransaction extends RuntimeQueryable {
|
|
80
|
+
commit(): Promise<void>;
|
|
81
|
+
rollback(): Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface RuntimeQueryable {
|
|
45
85
|
execute<Row = Record<string, unknown>>(
|
|
46
86
|
plan: ExecutionPlan<Row> | SqlQueryPlan<Row>,
|
|
47
87
|
): AsyncIterableResult<Row>;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface CoreQueryable {
|
|
91
|
+
execute<Row = Record<string, unknown>>(plan: ExecutionPlan<Row>): AsyncIterableResult<Row>;
|
|
51
92
|
}
|
|
52
93
|
|
|
53
94
|
export type { RuntimeTelemetryEvent, RuntimeVerifyOptions, TelemetryOutcome };
|
|
54
95
|
|
|
55
|
-
class SqlRuntimeImpl<TContract extends
|
|
96
|
+
class SqlRuntimeImpl<TContract extends Contract<SqlStorage> = Contract<SqlStorage>>
|
|
56
97
|
implements Runtime
|
|
57
98
|
{
|
|
58
|
-
private readonly core: RuntimeCore<
|
|
59
|
-
TContract,
|
|
60
|
-
Adapter<SelectAst, SqlContract<SqlStorage>, LoweredStatement>,
|
|
61
|
-
SqlDriver
|
|
62
|
-
>;
|
|
99
|
+
private readonly core: RuntimeCore<TContract, SqlDriver<unknown>>;
|
|
63
100
|
private readonly contract: TContract;
|
|
64
|
-
private readonly
|
|
101
|
+
private readonly adapter: Adapter<AnyQueryAst, Contract<SqlStorage>, LoweredStatement>;
|
|
65
102
|
private readonly codecRegistry: CodecRegistry;
|
|
103
|
+
private readonly jsonSchemaValidators: JsonSchemaValidatorRegistry | undefined;
|
|
66
104
|
private codecRegistryValidated: boolean;
|
|
67
105
|
|
|
68
106
|
constructor(options: RuntimeOptions<TContract>) {
|
|
69
|
-
const { context, driver, verify,
|
|
107
|
+
const { context, adapter, driver, verify, middleware, mode, log } = options;
|
|
70
108
|
this.contract = context.contract;
|
|
71
|
-
this.
|
|
109
|
+
this.adapter = adapter;
|
|
72
110
|
this.codecRegistry = context.codecs;
|
|
111
|
+
this.jsonSchemaValidators = context.jsonSchemaValidators;
|
|
73
112
|
this.codecRegistryValidated = false;
|
|
74
113
|
|
|
75
|
-
|
|
114
|
+
if (middleware) {
|
|
115
|
+
for (const mw of middleware) {
|
|
116
|
+
checkMiddlewareCompatibility(mw, 'sql', context.contract.target);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const familyAdapter = new SqlFamilyAdapter(context.contract, adapter.profile);
|
|
76
121
|
|
|
77
|
-
const coreOptions: RuntimeCoreOptions<
|
|
78
|
-
TContract,
|
|
79
|
-
Adapter<SelectAst, SqlContract<SqlStorage>, LoweredStatement>,
|
|
80
|
-
SqlDriver
|
|
81
|
-
> = {
|
|
122
|
+
const coreOptions: RuntimeCoreOptions<TContract, SqlDriver<unknown>> = {
|
|
82
123
|
familyAdapter,
|
|
83
124
|
driver,
|
|
84
125
|
verify,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
SqlDriver
|
|
89
|
-
>[],
|
|
90
|
-
...(mode !== undefined ? { mode } : {}),
|
|
91
|
-
...(log !== undefined ? { log } : {}),
|
|
92
|
-
operationRegistry: context.operations,
|
|
126
|
+
...ifDefined('middleware', middleware),
|
|
127
|
+
...ifDefined('mode', mode),
|
|
128
|
+
...ifDefined('log', log),
|
|
93
129
|
};
|
|
94
130
|
|
|
95
131
|
this.core = createRuntimeCore(coreOptions);
|
|
@@ -100,27 +136,27 @@ class SqlRuntimeImpl<TContract extends SqlContract<SqlStorage> = SqlContract<Sql
|
|
|
100
136
|
}
|
|
101
137
|
}
|
|
102
138
|
|
|
103
|
-
private ensureCodecRegistryValidated(contract:
|
|
139
|
+
private ensureCodecRegistryValidated(contract: Contract<SqlStorage>): void {
|
|
104
140
|
if (!this.codecRegistryValidated) {
|
|
105
141
|
validateCodecRegistryCompleteness(this.codecRegistry, contract);
|
|
106
142
|
this.codecRegistryValidated = true;
|
|
107
143
|
}
|
|
108
144
|
}
|
|
109
145
|
|
|
110
|
-
|
|
111
|
-
plan: ExecutionPlan<Row> | SqlQueryPlan<Row>,
|
|
112
|
-
): AsyncIterableResult<Row> {
|
|
113
|
-
this.ensureCodecRegistryValidated(this.contract);
|
|
114
|
-
|
|
115
|
-
// Check if plan is SqlQueryPlan (has ast but no sql)
|
|
146
|
+
private toExecutionPlan<Row>(plan: ExecutionPlan<Row> | SqlQueryPlan<Row>): ExecutionPlan<Row> {
|
|
116
147
|
const isSqlQueryPlan = (p: ExecutionPlan<Row> | SqlQueryPlan<Row>): p is SqlQueryPlan<Row> => {
|
|
117
148
|
return 'ast' in p && !('sql' in p);
|
|
118
149
|
};
|
|
119
150
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
151
|
+
return isSqlQueryPlan(plan) ? lowerSqlPlan(this.adapter, this.contract, plan) : plan;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private executeAgainstQueryable<Row = Record<string, unknown>>(
|
|
155
|
+
plan: ExecutionPlan<Row> | SqlQueryPlan<Row>,
|
|
156
|
+
queryable: CoreQueryable,
|
|
157
|
+
): AsyncIterableResult<Row> {
|
|
158
|
+
this.ensureCodecRegistryValidated(this.contract);
|
|
159
|
+
const executablePlan = this.toExecutionPlan(plan);
|
|
124
160
|
|
|
125
161
|
const iterator = async function* (
|
|
126
162
|
self: SqlRuntimeImpl<TContract>,
|
|
@@ -131,13 +167,14 @@ class SqlRuntimeImpl<TContract extends SqlContract<SqlStorage> = SqlContract<Sql
|
|
|
131
167
|
params: encodedParams,
|
|
132
168
|
};
|
|
133
169
|
|
|
134
|
-
const coreIterator =
|
|
170
|
+
const coreIterator = queryable.execute(planWithEncodedParams);
|
|
135
171
|
|
|
136
172
|
for await (const rawRow of coreIterator) {
|
|
137
173
|
const decodedRow = decodeRow(
|
|
138
174
|
rawRow as Record<string, unknown>,
|
|
139
175
|
executablePlan,
|
|
140
176
|
self.codecRegistry,
|
|
177
|
+
self.jsonSchemaValidators,
|
|
141
178
|
);
|
|
142
179
|
yield decodedRow as Row;
|
|
143
180
|
}
|
|
@@ -146,12 +183,40 @@ class SqlRuntimeImpl<TContract extends SqlContract<SqlStorage> = SqlContract<Sql
|
|
|
146
183
|
return new AsyncIterableResult(iterator(this));
|
|
147
184
|
}
|
|
148
185
|
|
|
149
|
-
|
|
150
|
-
|
|
186
|
+
execute<Row = Record<string, unknown>>(
|
|
187
|
+
plan: ExecutionPlan<Row> | SqlQueryPlan<Row>,
|
|
188
|
+
): AsyncIterableResult<Row> {
|
|
189
|
+
return this.executeAgainstQueryable(plan, this.core);
|
|
151
190
|
}
|
|
152
191
|
|
|
153
|
-
|
|
154
|
-
|
|
192
|
+
async connection(): Promise<RuntimeConnection> {
|
|
193
|
+
const coreConn = await this.core.connection();
|
|
194
|
+
const self = this;
|
|
195
|
+
const wrappedConnection: RuntimeConnection = {
|
|
196
|
+
async transaction(): Promise<RuntimeTransaction> {
|
|
197
|
+
const coreTx = await coreConn.transaction();
|
|
198
|
+
return {
|
|
199
|
+
commit: coreTx.commit.bind(coreTx),
|
|
200
|
+
rollback: coreTx.rollback.bind(coreTx),
|
|
201
|
+
execute<Row = Record<string, unknown>>(
|
|
202
|
+
plan: ExecutionPlan<Row> | SqlQueryPlan<Row>,
|
|
203
|
+
): AsyncIterableResult<Row> {
|
|
204
|
+
return self.executeAgainstQueryable(plan, coreTx);
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
},
|
|
208
|
+
release: coreConn.release.bind(coreConn),
|
|
209
|
+
execute<Row = Record<string, unknown>>(
|
|
210
|
+
plan: ExecutionPlan<Row> | SqlQueryPlan<Row>,
|
|
211
|
+
): AsyncIterableResult<Row> {
|
|
212
|
+
return self.executeAgainstQueryable(plan, coreConn);
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
return wrappedConnection;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
telemetry(): RuntimeTelemetryEvent | null {
|
|
219
|
+
return this.core.telemetry();
|
|
155
220
|
}
|
|
156
221
|
|
|
157
222
|
close(): Promise<void> {
|
|
@@ -159,8 +224,18 @@ class SqlRuntimeImpl<TContract extends SqlContract<SqlStorage> = SqlContract<Sql
|
|
|
159
224
|
}
|
|
160
225
|
}
|
|
161
226
|
|
|
162
|
-
export function createRuntime<TContract extends
|
|
163
|
-
options:
|
|
227
|
+
export function createRuntime<TContract extends Contract<SqlStorage>, TTargetId extends string>(
|
|
228
|
+
options: CreateRuntimeOptions<TContract, TTargetId>,
|
|
164
229
|
): Runtime {
|
|
165
|
-
|
|
230
|
+
const { stackInstance, context, driver, verify, middleware, mode, log } = options;
|
|
231
|
+
|
|
232
|
+
return new SqlRuntimeImpl({
|
|
233
|
+
context,
|
|
234
|
+
adapter: stackInstance.adapter,
|
|
235
|
+
driver,
|
|
236
|
+
verify,
|
|
237
|
+
...ifDefined('middleware', middleware),
|
|
238
|
+
...ifDefined('mode', mode),
|
|
239
|
+
...ifDefined('log', log),
|
|
240
|
+
});
|
|
166
241
|
}
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import type { ExecutionPlan } from '@prisma-next/contract/types';
|
|
2
|
+
import { instantiateExecutionStack } from '@prisma-next/framework-components/execution';
|
|
2
3
|
import type { AsyncIterableResult } from '@prisma-next/runtime-executor';
|
|
3
4
|
import { describe, expect, it } from 'vitest';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
5
|
+
import type { Runtime } from '../src/exports';
|
|
6
|
+
import { createRuntime, createSqlExecutionStack } from '../src/exports';
|
|
7
|
+
import {
|
|
8
|
+
createStubAdapter,
|
|
9
|
+
createTestAdapterDescriptor,
|
|
10
|
+
createTestContext,
|
|
11
|
+
createTestContract,
|
|
12
|
+
createTestTargetDescriptor,
|
|
13
|
+
} from './utils';
|
|
6
14
|
|
|
7
|
-
// Mock driver that implements SqlDriver interface
|
|
8
15
|
class MockDriver {
|
|
9
16
|
private rows: ReadonlyArray<Record<string, unknown>> = [];
|
|
10
17
|
|
|
@@ -12,11 +19,10 @@ class MockDriver {
|
|
|
12
19
|
this.rows = rows;
|
|
13
20
|
}
|
|
14
21
|
|
|
15
|
-
async query(
|
|
22
|
+
async query<Row = Record<string, unknown>>(
|
|
16
23
|
_sql: string,
|
|
17
|
-
_params
|
|
18
|
-
): Promise<{ rows: ReadonlyArray<
|
|
19
|
-
// Return empty marker result for contract verification
|
|
24
|
+
_params?: readonly unknown[],
|
|
25
|
+
): Promise<{ rows: ReadonlyArray<Row> }> {
|
|
20
26
|
return { rows: [] };
|
|
21
27
|
}
|
|
22
28
|
|
|
@@ -29,20 +35,19 @@ class MockDriver {
|
|
|
29
35
|
}
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
async
|
|
33
|
-
|
|
38
|
+
async acquireConnection(): Promise<never> {
|
|
39
|
+
throw new Error('Not implemented in mock');
|
|
34
40
|
}
|
|
35
41
|
|
|
36
|
-
async
|
|
37
|
-
|
|
38
|
-
}
|
|
42
|
+
async connect(): Promise<void> {}
|
|
43
|
+
|
|
44
|
+
async close(): Promise<void> {}
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
const fixtureContract = createTestContract({
|
|
42
|
-
schemaVersion: '1',
|
|
43
48
|
targetFamily: 'sql',
|
|
44
49
|
target: 'postgres',
|
|
45
|
-
|
|
50
|
+
storageHash: 'test-hash',
|
|
46
51
|
profileHash: 'test-profile-hash',
|
|
47
52
|
storage: {
|
|
48
53
|
tables: {
|
|
@@ -58,24 +63,33 @@ const fixtureContract = createTestContract({
|
|
|
58
63
|
},
|
|
59
64
|
},
|
|
60
65
|
models: {},
|
|
61
|
-
relations: {},
|
|
62
|
-
mappings: { codecTypes: {}, operationTypes: {} },
|
|
63
66
|
});
|
|
64
67
|
|
|
68
|
+
function createTestRuntime(mockDriver: MockDriver): Runtime {
|
|
69
|
+
const adapter = createStubAdapter();
|
|
70
|
+
const stack = createSqlExecutionStack({
|
|
71
|
+
target: createTestTargetDescriptor(),
|
|
72
|
+
adapter: createTestAdapterDescriptor(adapter),
|
|
73
|
+
extensionPacks: [],
|
|
74
|
+
});
|
|
75
|
+
const stackInstance = instantiateExecutionStack(stack);
|
|
76
|
+
const context = createTestContext(fixtureContract, adapter);
|
|
77
|
+
return createRuntime({
|
|
78
|
+
stackInstance,
|
|
79
|
+
context,
|
|
80
|
+
driver: mockDriver,
|
|
81
|
+
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
65
85
|
describe('SqlRuntime AsyncIterableResult integration', () => {
|
|
66
86
|
it('returns AsyncIterableResult from execute', async () => {
|
|
67
|
-
const adapter = createStubAdapter();
|
|
68
87
|
const driver = new MockDriver();
|
|
69
88
|
driver.setRows([
|
|
70
89
|
{ id: 1, email: 'test1@example.com' },
|
|
71
90
|
{ id: 2, email: 'test2@example.com' },
|
|
72
91
|
]);
|
|
73
|
-
const
|
|
74
|
-
const runtime = createRuntime({
|
|
75
|
-
driver: driver as unknown as Parameters<typeof createRuntime>[0]['driver'],
|
|
76
|
-
context,
|
|
77
|
-
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
78
|
-
});
|
|
92
|
+
const runtime = createTestRuntime(driver);
|
|
79
93
|
|
|
80
94
|
const plan: ExecutionPlan<{ id: number; email: string }> = {
|
|
81
95
|
sql: 'SELECT id, email FROM "user" ORDER BY id',
|
|
@@ -83,7 +97,7 @@ describe('SqlRuntime AsyncIterableResult integration', () => {
|
|
|
83
97
|
meta: {
|
|
84
98
|
target: 'postgres',
|
|
85
99
|
targetFamily: 'sql',
|
|
86
|
-
|
|
100
|
+
storageHash: 'test-hash',
|
|
87
101
|
lane: 'sql',
|
|
88
102
|
paramDescriptors: [],
|
|
89
103
|
},
|
|
@@ -91,7 +105,6 @@ describe('SqlRuntime AsyncIterableResult integration', () => {
|
|
|
91
105
|
|
|
92
106
|
const result = runtime.execute(plan);
|
|
93
107
|
|
|
94
|
-
// Verify it's an AsyncIterableResult
|
|
95
108
|
expect(result).toBeInstanceOf(Object);
|
|
96
109
|
expect(typeof result.toArray).toBe('function');
|
|
97
110
|
expect(typeof result[Symbol.asyncIterator]).toBe('function');
|
|
@@ -100,15 +113,9 @@ describe('SqlRuntime AsyncIterableResult integration', () => {
|
|
|
100
113
|
});
|
|
101
114
|
|
|
102
115
|
it('preserves type information', async () => {
|
|
103
|
-
const adapter = createStubAdapter();
|
|
104
116
|
const driver = new MockDriver();
|
|
105
117
|
driver.setRows([{ id: 1, email: 'test@example.com' }]);
|
|
106
|
-
const
|
|
107
|
-
const runtime = createRuntime({
|
|
108
|
-
driver: driver as unknown as Parameters<typeof createRuntime>[0]['driver'],
|
|
109
|
-
context,
|
|
110
|
-
verify: { mode: 'onFirstUse', requireMarker: false },
|
|
111
|
-
});
|
|
118
|
+
const runtime = createTestRuntime(driver);
|
|
112
119
|
|
|
113
120
|
const plan: ExecutionPlan<{ id: number; email: string }> = {
|
|
114
121
|
sql: 'SELECT id, email FROM "user" LIMIT 1',
|
|
@@ -116,7 +123,7 @@ describe('SqlRuntime AsyncIterableResult integration', () => {
|
|
|
116
123
|
meta: {
|
|
117
124
|
target: 'postgres',
|
|
118
125
|
targetFamily: 'sql',
|
|
119
|
-
|
|
126
|
+
storageHash: 'test-hash',
|
|
120
127
|
lane: 'sql',
|
|
121
128
|
paramDescriptors: [],
|
|
122
129
|
},
|
|
@@ -126,10 +133,8 @@ describe('SqlRuntime AsyncIterableResult integration', () => {
|
|
|
126
133
|
const rows = await result.toArray();
|
|
127
134
|
|
|
128
135
|
expect(rows.length).toBe(1);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
expect(typeof rows[0].email).toBe('string');
|
|
132
|
-
}
|
|
136
|
+
expect(typeof rows[0]!.id).toBe('number');
|
|
137
|
+
expect(typeof rows[0]!.email).toBe('string');
|
|
133
138
|
|
|
134
139
|
await runtime.close();
|
|
135
140
|
});
|