@prisma/client-engine-runtime 6.15.0-dev.2 → 6.15.0-dev.21
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/dist/index.d.mts +31 -58
- package/dist/index.d.ts +31 -58
- package/dist/index.js +215 -210
- package/dist/index.mjs +215 -208
- package/dist/interpreter/generators.d.ts +1 -2
- package/dist/interpreter/render-query.d.ts +2 -2
- package/dist/query-plan.d.ts +26 -48
- package/dist/transaction-manager/transaction-manager-error.d.ts +0 -3
- package/dist/transaction-manager/transaction-manager.d.ts +1 -5
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -39,8 +39,6 @@ __export(index_exports, {
|
|
|
39
39
|
deserializeJsonResponse: () => deserializeJsonResponse,
|
|
40
40
|
doKeysMatch: () => doKeysMatch,
|
|
41
41
|
isDeepStrictEqual: () => isDeepStrictEqual,
|
|
42
|
-
isPrismaValueBigInt: () => isPrismaValueBigInt,
|
|
43
|
-
isPrismaValueBytes: () => isPrismaValueBytes,
|
|
44
42
|
isPrismaValueGenerator: () => isPrismaValueGenerator,
|
|
45
43
|
isPrismaValuePlaceholder: () => isPrismaValuePlaceholder,
|
|
46
44
|
noopTracingHelper: () => noopTracingHelper,
|
|
@@ -172,7 +170,7 @@ function normalizeTaggedValue({ $type, value }) {
|
|
|
172
170
|
case "BigInt":
|
|
173
171
|
return { $type, value: String(value) };
|
|
174
172
|
case "Bytes":
|
|
175
|
-
return { $type, value };
|
|
173
|
+
return { $type, value: Buffer.from(value, "base64").toString("base64") };
|
|
176
174
|
case "DateTime":
|
|
177
175
|
return { $type, value: new Date(value).toISOString() };
|
|
178
176
|
case "Decimal":
|
|
@@ -447,15 +445,15 @@ var DataMapperError = class extends Error {
|
|
|
447
445
|
};
|
|
448
446
|
function applyDataMap(data, structure, enums) {
|
|
449
447
|
switch (structure.type) {
|
|
450
|
-
case "
|
|
448
|
+
case "affectedRows":
|
|
451
449
|
if (typeof data !== "number") {
|
|
452
450
|
throw new DataMapperError(`Expected an affected rows count, got: ${typeof data} (${data})`);
|
|
453
451
|
}
|
|
454
452
|
return { count: data };
|
|
455
|
-
case "
|
|
453
|
+
case "object":
|
|
456
454
|
return mapArrayOrObject(data, structure.fields, enums, structure.skipNulls);
|
|
457
|
-
case "
|
|
458
|
-
return mapValue(data, "<result>", structure.
|
|
455
|
+
case "field":
|
|
456
|
+
return mapValue(data, "<result>", structure.fieldType, enums);
|
|
459
457
|
default:
|
|
460
458
|
assertNever(structure, `Invalid data mapping type: '${structure.type}'`);
|
|
461
459
|
}
|
|
@@ -493,10 +491,10 @@ function mapObject(data, fields, enums) {
|
|
|
493
491
|
const result = {};
|
|
494
492
|
for (const [name, node] of Object.entries(fields)) {
|
|
495
493
|
switch (node.type) {
|
|
496
|
-
case "
|
|
494
|
+
case "affectedRows": {
|
|
497
495
|
throw new DataMapperError(`Unexpected 'AffectedRows' node in data mapping for field '${name}'`);
|
|
498
496
|
}
|
|
499
|
-
case "
|
|
497
|
+
case "object": {
|
|
500
498
|
if (node.serializedName !== null && !Object.hasOwn(data, node.serializedName)) {
|
|
501
499
|
throw new DataMapperError(
|
|
502
500
|
`Missing data field (Object): '${name}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
|
|
@@ -506,11 +504,11 @@ function mapObject(data, fields, enums) {
|
|
|
506
504
|
result[name] = mapArrayOrObject(target, node.fields, enums, node.skipNulls);
|
|
507
505
|
break;
|
|
508
506
|
}
|
|
509
|
-
case "
|
|
507
|
+
case "field":
|
|
510
508
|
{
|
|
511
509
|
const dbName = node.dbName;
|
|
512
510
|
if (Object.hasOwn(data, dbName)) {
|
|
513
|
-
result[name] =
|
|
511
|
+
result[name] = mapField(data[dbName], dbName, node.fieldType, enums);
|
|
514
512
|
} else {
|
|
515
513
|
throw new DataMapperError(
|
|
516
514
|
`Missing data field (Value): '${dbName}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
|
|
@@ -524,20 +522,27 @@ function mapObject(data, fields, enums) {
|
|
|
524
522
|
}
|
|
525
523
|
return result;
|
|
526
524
|
}
|
|
527
|
-
function
|
|
525
|
+
function mapField(value, columnName, fieldType, enums) {
|
|
528
526
|
if (value === null) {
|
|
529
|
-
return
|
|
527
|
+
return fieldType.arity === "list" ? [] : null;
|
|
530
528
|
}
|
|
531
|
-
|
|
532
|
-
|
|
529
|
+
if (fieldType.arity === "list") {
|
|
530
|
+
const values = value;
|
|
531
|
+
return values.map((v, i) => mapValue(v, `${columnName}[${i}]`, fieldType, enums));
|
|
532
|
+
}
|
|
533
|
+
return mapValue(value, columnName, fieldType, enums);
|
|
534
|
+
}
|
|
535
|
+
function mapValue(value, columnName, scalarType, enums) {
|
|
536
|
+
switch (scalarType.type) {
|
|
537
|
+
case "unsupported":
|
|
533
538
|
return value;
|
|
534
|
-
case "
|
|
539
|
+
case "string": {
|
|
535
540
|
if (typeof value !== "string") {
|
|
536
541
|
throw new DataMapperError(`Expected a string in column '${columnName}', got ${typeof value}: ${value}`);
|
|
537
542
|
}
|
|
538
543
|
return value;
|
|
539
544
|
}
|
|
540
|
-
case "
|
|
545
|
+
case "int": {
|
|
541
546
|
switch (typeof value) {
|
|
542
547
|
case "number": {
|
|
543
548
|
return Math.trunc(value);
|
|
@@ -558,13 +563,13 @@ function mapValue(value, columnName, resultType, enums) {
|
|
|
558
563
|
throw new DataMapperError(`Expected an integer in column '${columnName}', got ${typeof value}: ${value}`);
|
|
559
564
|
}
|
|
560
565
|
}
|
|
561
|
-
case "
|
|
566
|
+
case "bigint": {
|
|
562
567
|
if (typeof value !== "number" && typeof value !== "string") {
|
|
563
568
|
throw new DataMapperError(`Expected a bigint in column '${columnName}', got ${typeof value}: ${value}`);
|
|
564
569
|
}
|
|
565
570
|
return { $type: "BigInt", value };
|
|
566
571
|
}
|
|
567
|
-
case "
|
|
572
|
+
case "float": {
|
|
568
573
|
if (typeof value === "number") return value;
|
|
569
574
|
if (typeof value === "string") {
|
|
570
575
|
const parsedValue = Number(value);
|
|
@@ -575,7 +580,7 @@ function mapValue(value, columnName, resultType, enums) {
|
|
|
575
580
|
}
|
|
576
581
|
throw new DataMapperError(`Expected a float in column '${columnName}', got ${typeof value}: ${value}`);
|
|
577
582
|
}
|
|
578
|
-
case "
|
|
583
|
+
case "boolean": {
|
|
579
584
|
if (typeof value === "boolean") return value;
|
|
580
585
|
if (typeof value === "number") return value === 1;
|
|
581
586
|
if (typeof value === "string") {
|
|
@@ -587,7 +592,7 @@ function mapValue(value, columnName, resultType, enums) {
|
|
|
587
592
|
throw new DataMapperError(`Expected a boolean in column '${columnName}', got ${typeof value}: ${value}`);
|
|
588
593
|
}
|
|
589
594
|
}
|
|
590
|
-
if (value
|
|
595
|
+
if (Array.isArray(value)) {
|
|
591
596
|
for (const byte of value) {
|
|
592
597
|
if (byte !== 0) return true;
|
|
593
598
|
}
|
|
@@ -595,73 +600,87 @@ function mapValue(value, columnName, resultType, enums) {
|
|
|
595
600
|
}
|
|
596
601
|
throw new DataMapperError(`Expected a boolean in column '${columnName}', got ${typeof value}: ${value}`);
|
|
597
602
|
}
|
|
598
|
-
case "
|
|
603
|
+
case "decimal":
|
|
599
604
|
if (typeof value !== "number" && typeof value !== "string" && !import_decimal3.default.isDecimal(value)) {
|
|
600
605
|
throw new DataMapperError(`Expected a decimal in column '${columnName}', got ${typeof value}: ${value}`);
|
|
601
606
|
}
|
|
602
607
|
return { $type: "Decimal", value };
|
|
603
|
-
case "
|
|
608
|
+
case "datetime": {
|
|
604
609
|
if (typeof value === "string") {
|
|
605
|
-
return { $type: "DateTime", value:
|
|
610
|
+
return { $type: "DateTime", value: normalizeDateTime(value) };
|
|
606
611
|
}
|
|
607
612
|
if (typeof value === "number" || value instanceof Date) {
|
|
608
613
|
return { $type: "DateTime", value };
|
|
609
614
|
}
|
|
610
615
|
throw new DataMapperError(`Expected a date in column '${columnName}', got ${typeof value}: ${value}`);
|
|
611
616
|
}
|
|
612
|
-
case "
|
|
613
|
-
if (typeof value === "string") {
|
|
614
|
-
return { $type: "DateTime", value: `1970-01-01T${ensureTimezoneInIsoString(value)}` };
|
|
615
|
-
}
|
|
616
|
-
throw new DataMapperError(`Expected a time in column '${columnName}', got ${typeof value}: ${value}`);
|
|
617
|
-
}
|
|
618
|
-
case "Array": {
|
|
619
|
-
const values = value;
|
|
620
|
-
return values.map((v, i) => mapValue(v, `${columnName}[${i}]`, resultType.inner, enums));
|
|
621
|
-
}
|
|
622
|
-
case "Object": {
|
|
617
|
+
case "object": {
|
|
623
618
|
return { $type: "Json", value: safeJsonStringify(value) };
|
|
624
619
|
}
|
|
625
|
-
case "
|
|
620
|
+
case "json": {
|
|
626
621
|
return { $type: "Json", value: `${value}` };
|
|
627
622
|
}
|
|
628
|
-
case "
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
623
|
+
case "bytes": {
|
|
624
|
+
switch (scalarType.encoding) {
|
|
625
|
+
case "base64":
|
|
626
|
+
if (typeof value !== "string") {
|
|
627
|
+
throw new DataMapperError(
|
|
628
|
+
`Expected a base64-encoded byte array in column '${columnName}', got ${typeof value}: ${value}`
|
|
629
|
+
);
|
|
630
|
+
}
|
|
631
|
+
return { $type: "Bytes", value };
|
|
632
|
+
case "hex":
|
|
633
|
+
if (typeof value !== "string" || !value.startsWith("\\x")) {
|
|
634
|
+
throw new DataMapperError(
|
|
635
|
+
`Expected a hex-encoded byte array in column '${columnName}', got ${typeof value}: ${value}`
|
|
636
|
+
);
|
|
637
|
+
}
|
|
638
|
+
return { $type: "Bytes", value: Buffer.from(value.slice(2), "hex").toString("base64") };
|
|
639
|
+
case "array":
|
|
640
|
+
if (Array.isArray(value)) {
|
|
641
|
+
return { $type: "Bytes", value: Buffer.from(value).toString("base64") };
|
|
642
|
+
}
|
|
643
|
+
if (value instanceof Uint8Array) {
|
|
644
|
+
return { $type: "Bytes", value: Buffer.from(value).toString("base64") };
|
|
645
|
+
}
|
|
646
|
+
throw new DataMapperError(`Expected a byte array in column '${columnName}', got ${typeof value}: ${value}`);
|
|
647
|
+
default:
|
|
648
|
+
assertNever(scalarType.encoding, `DataMapper: Unknown bytes encoding: ${scalarType.encoding}`);
|
|
637
649
|
}
|
|
638
|
-
|
|
650
|
+
break;
|
|
639
651
|
}
|
|
640
|
-
case "
|
|
641
|
-
const enumDef = enums[
|
|
652
|
+
case "enum": {
|
|
653
|
+
const enumDef = enums[scalarType.name];
|
|
642
654
|
if (enumDef === void 0) {
|
|
643
|
-
throw new DataMapperError(`Unknown enum '${
|
|
655
|
+
throw new DataMapperError(`Unknown enum '${scalarType.name}'`);
|
|
644
656
|
}
|
|
645
657
|
const enumValue = enumDef[`${value}`];
|
|
646
658
|
if (enumValue === void 0) {
|
|
647
|
-
throw new DataMapperError(`Value '${value}' not found in enum '${
|
|
659
|
+
throw new DataMapperError(`Value '${value}' not found in enum '${scalarType.name}'`);
|
|
648
660
|
}
|
|
649
661
|
return enumValue;
|
|
650
662
|
}
|
|
651
663
|
default:
|
|
652
|
-
assertNever(
|
|
664
|
+
assertNever(scalarType, `DataMapper: Unknown result type: ${scalarType["type"]}`);
|
|
653
665
|
}
|
|
654
666
|
}
|
|
655
|
-
var
|
|
656
|
-
function
|
|
657
|
-
const
|
|
658
|
-
if (
|
|
667
|
+
var TIME_TZ_PATTERN = /\d{2}:\d{2}:\d{2}(?:\.\d+)?(Z|[+-]\d{2}(:?\d{2})?)?$/;
|
|
668
|
+
function normalizeDateTime(dt) {
|
|
669
|
+
const matches = TIME_TZ_PATTERN.exec(dt);
|
|
670
|
+
if (matches === null) {
|
|
659
671
|
return `${dt}Z`;
|
|
660
|
-
} else if (results[0] !== "Z" && results[1] === void 0) {
|
|
661
|
-
return `${dt}:00`;
|
|
662
|
-
} else {
|
|
663
|
-
return dt;
|
|
664
672
|
}
|
|
673
|
+
let dtWithTz = dt;
|
|
674
|
+
const [timeTz, tz, tzMinuteOffset] = matches;
|
|
675
|
+
if (tz !== void 0 && tz !== "Z" && tzMinuteOffset === void 0) {
|
|
676
|
+
dtWithTz = `${dt}:00`;
|
|
677
|
+
} else if (tz === void 0) {
|
|
678
|
+
dtWithTz = `${dt}Z`;
|
|
679
|
+
}
|
|
680
|
+
if (timeTz.length === dt.length) {
|
|
681
|
+
return `1970-01-01T${dtWithTz}`;
|
|
682
|
+
}
|
|
683
|
+
return dtWithTz;
|
|
665
684
|
}
|
|
666
685
|
|
|
667
686
|
// src/tracing.ts
|
|
@@ -740,10 +759,10 @@ var GeneratorRegistry = class {
|
|
|
740
759
|
* method being called, meaning that the built-in time-based generators will always return
|
|
741
760
|
* the same value on repeated calls as long as the same snapshot is used.
|
|
742
761
|
*/
|
|
743
|
-
snapshot(
|
|
762
|
+
snapshot() {
|
|
744
763
|
return Object.create(this.#generators, {
|
|
745
764
|
now: {
|
|
746
|
-
value:
|
|
765
|
+
value: new NowGenerator()
|
|
747
766
|
}
|
|
748
767
|
});
|
|
749
768
|
}
|
|
@@ -760,12 +779,6 @@ var NowGenerator = class {
|
|
|
760
779
|
return this.#now.toISOString();
|
|
761
780
|
}
|
|
762
781
|
};
|
|
763
|
-
var MysqlNowGenerator = class {
|
|
764
|
-
#now = /* @__PURE__ */ new Date();
|
|
765
|
-
generate() {
|
|
766
|
-
return this.#now.toISOString().replace("T", " ").replace("Z", "");
|
|
767
|
-
}
|
|
768
|
-
};
|
|
769
782
|
var UuidGenerator = class {
|
|
770
783
|
generate(arg) {
|
|
771
784
|
if (arg === 4) {
|
|
@@ -919,74 +932,82 @@ function isPrismaValuePlaceholder(value) {
|
|
|
919
932
|
function isPrismaValueGenerator(value) {
|
|
920
933
|
return typeof value === "object" && value !== null && value["prisma__type"] === "generatorCall";
|
|
921
934
|
}
|
|
922
|
-
function isPrismaValueBytes(value) {
|
|
923
|
-
return typeof value === "object" && value !== null && value["prisma__type"] === "bytes";
|
|
924
|
-
}
|
|
925
|
-
function isPrismaValueBigInt(value) {
|
|
926
|
-
return typeof value === "object" && value !== null && value["prisma__type"] === "bigint";
|
|
927
|
-
}
|
|
928
935
|
|
|
929
936
|
// src/interpreter/render-query.ts
|
|
930
937
|
function renderQuery(dbQuery, scope, generators, maxChunkSize) {
|
|
931
|
-
const
|
|
932
|
-
|
|
933
|
-
switch (queryType) {
|
|
938
|
+
const args = dbQuery.args.map((arg) => evaluateArg(arg, scope, generators));
|
|
939
|
+
switch (dbQuery.type) {
|
|
934
940
|
case "rawSql":
|
|
935
|
-
return [renderRawSql(dbQuery.sql,
|
|
941
|
+
return [renderRawSql(dbQuery.sql, args, dbQuery.argTypes)];
|
|
936
942
|
case "templateSql": {
|
|
937
|
-
const chunks = dbQuery.chunkable ? chunkParams(dbQuery.fragments,
|
|
938
|
-
return chunks.map((
|
|
939
|
-
if (maxChunkSize !== void 0 &&
|
|
943
|
+
const chunks = dbQuery.chunkable ? chunkParams(dbQuery.fragments, args, maxChunkSize) : [args];
|
|
944
|
+
return chunks.map((params) => {
|
|
945
|
+
if (maxChunkSize !== void 0 && params.length > maxChunkSize) {
|
|
940
946
|
throw new UserFacingError("The query parameter limit supported by your database is exceeded.", "P2029");
|
|
941
947
|
}
|
|
942
|
-
return renderTemplateSql(dbQuery.fragments, dbQuery.placeholderFormat,
|
|
948
|
+
return renderTemplateSql(dbQuery.fragments, dbQuery.placeholderFormat, params, dbQuery.argTypes);
|
|
943
949
|
});
|
|
944
950
|
}
|
|
945
951
|
default:
|
|
946
|
-
assertNever(
|
|
952
|
+
assertNever(dbQuery["type"], `Invalid query type`);
|
|
947
953
|
}
|
|
948
954
|
}
|
|
949
|
-
function
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
let value = param;
|
|
954
|
-
while (doesRequireEvaluation(value)) {
|
|
955
|
-
if (isPrismaValuePlaceholder(value)) {
|
|
956
|
-
const found = scope[value.prisma__value.name];
|
|
955
|
+
function evaluateArg(arg, scope, generators) {
|
|
956
|
+
while (doesRequireEvaluation(arg)) {
|
|
957
|
+
if (isPrismaValuePlaceholder(arg)) {
|
|
958
|
+
const found = scope[arg.prisma__value.name];
|
|
957
959
|
if (found === void 0) {
|
|
958
|
-
throw new Error(`Missing value for query variable ${
|
|
960
|
+
throw new Error(`Missing value for query variable ${arg.prisma__value.name}`);
|
|
959
961
|
}
|
|
960
|
-
|
|
961
|
-
} else if (isPrismaValueGenerator(
|
|
962
|
-
const { name, args } =
|
|
962
|
+
arg = found;
|
|
963
|
+
} else if (isPrismaValueGenerator(arg)) {
|
|
964
|
+
const { name, args } = arg.prisma__value;
|
|
963
965
|
const generator = generators[name];
|
|
964
966
|
if (!generator) {
|
|
965
967
|
throw new Error(`Encountered an unknown generator '${name}'`);
|
|
966
968
|
}
|
|
967
|
-
|
|
969
|
+
arg = generator.generate(...args.map((arg2) => evaluateArg(arg2, scope, generators)));
|
|
968
970
|
} else {
|
|
969
|
-
assertNever(
|
|
971
|
+
assertNever(arg, `Unexpected unevaluated value type: ${arg}`);
|
|
970
972
|
}
|
|
971
973
|
}
|
|
972
|
-
if (Array.isArray(
|
|
973
|
-
|
|
974
|
-
} else if (isPrismaValueBytes(value)) {
|
|
975
|
-
value = Buffer.from(value.prisma__value, "base64");
|
|
976
|
-
} else if (isPrismaValueBigInt(value)) {
|
|
977
|
-
value = BigInt(value.prisma__value);
|
|
974
|
+
if (Array.isArray(arg)) {
|
|
975
|
+
arg = arg.map((el) => evaluateArg(el, scope, generators));
|
|
978
976
|
}
|
|
979
|
-
return
|
|
977
|
+
return arg;
|
|
980
978
|
}
|
|
981
|
-
function renderTemplateSql(fragments, placeholderFormat, params) {
|
|
979
|
+
function renderTemplateSql(fragments, placeholderFormat, params, argTypes) {
|
|
982
980
|
let sql = "";
|
|
983
981
|
const ctx = { placeholderNumber: 1 };
|
|
984
982
|
const flattenedParams = [];
|
|
985
|
-
|
|
986
|
-
|
|
983
|
+
const flattenedArgTypes = [];
|
|
984
|
+
for (const fragment of pairFragmentsWithParams(fragments, params, argTypes)) {
|
|
987
985
|
sql += renderFragment(fragment, placeholderFormat, ctx);
|
|
986
|
+
if (fragment.type === "stringChunk") {
|
|
987
|
+
continue;
|
|
988
|
+
}
|
|
989
|
+
const length = flattenedParams.length;
|
|
990
|
+
const added = flattenedParams.push(...flattenedFragmentParams(fragment)) - length;
|
|
991
|
+
if (fragment.argType.arity === "tuple") {
|
|
992
|
+
if (added % fragment.argType.elements.length !== 0) {
|
|
993
|
+
throw new Error(
|
|
994
|
+
`Malformed query template. Expected the number of parameters to match the tuple arity, but got ${added} parameters for a tuple of arity ${fragment.argType.elements.length}.`
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
for (let i = 0; i < added / fragment.argType.elements.length; i++) {
|
|
998
|
+
flattenedArgTypes.push(...fragment.argType.elements);
|
|
999
|
+
}
|
|
1000
|
+
} else {
|
|
1001
|
+
for (let i = 0; i < added; i++) {
|
|
1002
|
+
flattenedArgTypes.push(fragment.argType);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
988
1005
|
}
|
|
989
|
-
return
|
|
1006
|
+
return {
|
|
1007
|
+
sql,
|
|
1008
|
+
args: flattenedParams,
|
|
1009
|
+
argTypes: flattenedArgTypes
|
|
1010
|
+
};
|
|
990
1011
|
}
|
|
991
1012
|
function renderFragment(fragment, placeholderFormat, ctx) {
|
|
992
1013
|
const fragmentType = fragment.type;
|
|
@@ -1012,36 +1033,17 @@ function renderFragment(fragment, placeholderFormat, ctx) {
|
|
|
1012
1033
|
function formatPlaceholder(placeholderFormat, placeholderNumber) {
|
|
1013
1034
|
return placeholderFormat.hasNumbering ? `${placeholderFormat.prefix}${placeholderNumber}` : placeholderFormat.prefix;
|
|
1014
1035
|
}
|
|
1015
|
-
function renderRawSql(sql,
|
|
1016
|
-
const argTypes = params.map((param) => toArgType(param));
|
|
1036
|
+
function renderRawSql(sql, args, argTypes) {
|
|
1017
1037
|
return {
|
|
1018
1038
|
sql,
|
|
1019
|
-
args
|
|
1039
|
+
args,
|
|
1020
1040
|
argTypes
|
|
1021
1041
|
};
|
|
1022
1042
|
}
|
|
1023
|
-
function toArgType(value) {
|
|
1024
|
-
if (typeof value === "string") {
|
|
1025
|
-
return "Text";
|
|
1026
|
-
}
|
|
1027
|
-
if (typeof value === "number") {
|
|
1028
|
-
return "Numeric";
|
|
1029
|
-
}
|
|
1030
|
-
if (typeof value === "boolean") {
|
|
1031
|
-
return "Boolean";
|
|
1032
|
-
}
|
|
1033
|
-
if (Array.isArray(value)) {
|
|
1034
|
-
return "Array";
|
|
1035
|
-
}
|
|
1036
|
-
if (Buffer.isBuffer(value)) {
|
|
1037
|
-
return "Bytes";
|
|
1038
|
-
}
|
|
1039
|
-
return "Unknown";
|
|
1040
|
-
}
|
|
1041
1043
|
function doesRequireEvaluation(param) {
|
|
1042
1044
|
return isPrismaValuePlaceholder(param) || isPrismaValueGenerator(param);
|
|
1043
1045
|
}
|
|
1044
|
-
function* pairFragmentsWithParams(fragments, params) {
|
|
1046
|
+
function* pairFragmentsWithParams(fragments, params, argTypes) {
|
|
1045
1047
|
let index = 0;
|
|
1046
1048
|
for (const fragment of fragments) {
|
|
1047
1049
|
switch (fragment.type) {
|
|
@@ -1049,7 +1051,8 @@ function* pairFragmentsWithParams(fragments, params) {
|
|
|
1049
1051
|
if (index >= params.length) {
|
|
1050
1052
|
throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
|
|
1051
1053
|
}
|
|
1052
|
-
yield { ...fragment, value: params[index
|
|
1054
|
+
yield { ...fragment, value: params[index], argType: argTypes?.[index] };
|
|
1055
|
+
index++;
|
|
1053
1056
|
break;
|
|
1054
1057
|
}
|
|
1055
1058
|
case "stringChunk": {
|
|
@@ -1060,15 +1063,16 @@ function* pairFragmentsWithParams(fragments, params) {
|
|
|
1060
1063
|
if (index >= params.length) {
|
|
1061
1064
|
throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
|
|
1062
1065
|
}
|
|
1063
|
-
const value = params[index
|
|
1064
|
-
yield { ...fragment, value: Array.isArray(value) ? value : [value] };
|
|
1066
|
+
const value = params[index];
|
|
1067
|
+
yield { ...fragment, value: Array.isArray(value) ? value : [value], argType: argTypes?.[index] };
|
|
1068
|
+
index++;
|
|
1065
1069
|
break;
|
|
1066
1070
|
}
|
|
1067
1071
|
case "parameterTupleList": {
|
|
1068
1072
|
if (index >= params.length) {
|
|
1069
1073
|
throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
|
|
1070
1074
|
}
|
|
1071
|
-
const value = params[index
|
|
1075
|
+
const value = params[index];
|
|
1072
1076
|
if (!Array.isArray(value)) {
|
|
1073
1077
|
throw new Error(`Malformed query template. Tuple list expected.`);
|
|
1074
1078
|
}
|
|
@@ -1080,7 +1084,8 @@ function* pairFragmentsWithParams(fragments, params) {
|
|
|
1080
1084
|
throw new Error(`Malformed query template. Tuple expected.`);
|
|
1081
1085
|
}
|
|
1082
1086
|
}
|
|
1083
|
-
yield { ...fragment, value };
|
|
1087
|
+
yield { ...fragment, value, argType: argTypes?.[index] };
|
|
1088
|
+
index++;
|
|
1084
1089
|
break;
|
|
1085
1090
|
}
|
|
1086
1091
|
}
|
|
@@ -1106,7 +1111,7 @@ function* flattenedFragmentParams(fragment) {
|
|
|
1106
1111
|
function chunkParams(fragments, params, maxChunkSize) {
|
|
1107
1112
|
let totalParamCount = 0;
|
|
1108
1113
|
let maxParamsPerFragment = 0;
|
|
1109
|
-
for (const fragment of pairFragmentsWithParams(fragments, params)) {
|
|
1114
|
+
for (const fragment of pairFragmentsWithParams(fragments, params, void 0)) {
|
|
1110
1115
|
let paramSize = 0;
|
|
1111
1116
|
for (const _ of flattenedFragmentParams(fragment)) {
|
|
1112
1117
|
void _;
|
|
@@ -1116,7 +1121,7 @@ function chunkParams(fragments, params, maxChunkSize) {
|
|
|
1116
1121
|
totalParamCount += paramSize;
|
|
1117
1122
|
}
|
|
1118
1123
|
let chunkedParams = [[]];
|
|
1119
|
-
for (const fragment of pairFragmentsWithParams(fragments, params)) {
|
|
1124
|
+
for (const fragment of pairFragmentsWithParams(fragments, params, void 0)) {
|
|
1120
1125
|
switch (fragment.type) {
|
|
1121
1126
|
case "parameter": {
|
|
1122
1127
|
for (const params2 of chunkedParams) {
|
|
@@ -1182,16 +1187,8 @@ function chunkArray(array, chunkSize) {
|
|
|
1182
1187
|
// src/interpreter/serialize-sql.ts
|
|
1183
1188
|
var import_driver_adapter_utils2 = require("@prisma/driver-adapter-utils");
|
|
1184
1189
|
function serializeSql(resultSet) {
|
|
1185
|
-
const mappers = resultSet.columnTypes.map((type) => {
|
|
1186
|
-
switch (type) {
|
|
1187
|
-
case import_driver_adapter_utils2.ColumnTypeEnum.Bytes:
|
|
1188
|
-
return (value) => Array.isArray(value) ? new Uint8Array(value) : value;
|
|
1189
|
-
default:
|
|
1190
|
-
return (value) => value;
|
|
1191
|
-
}
|
|
1192
|
-
});
|
|
1193
1190
|
return resultSet.rows.map(
|
|
1194
|
-
(row) => row.
|
|
1191
|
+
(row) => row.reduce((acc, value, index) => {
|
|
1195
1192
|
const splitByDot = resultSet.columnNames[index].split(".");
|
|
1196
1193
|
let nested = acc;
|
|
1197
1194
|
for (let i = 0; i < splitByDot.length; i++) {
|
|
@@ -1485,14 +1482,14 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
1485
1482
|
queryPlan,
|
|
1486
1483
|
queryable,
|
|
1487
1484
|
this.#placeholderValues,
|
|
1488
|
-
this.#generators.snapshot(
|
|
1485
|
+
this.#generators.snapshot()
|
|
1489
1486
|
).catch((e) => rethrowAsUserFacing(e));
|
|
1490
1487
|
return value;
|
|
1491
1488
|
}
|
|
1492
1489
|
async interpretNode(node, queryable, scope, generators) {
|
|
1493
1490
|
switch (node.type) {
|
|
1494
1491
|
case "value": {
|
|
1495
|
-
return { value:
|
|
1492
|
+
return { value: evaluateArg(node.args, scope, generators) };
|
|
1496
1493
|
}
|
|
1497
1494
|
case "seq": {
|
|
1498
1495
|
let result;
|
|
@@ -1597,7 +1594,7 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
1597
1594
|
}
|
|
1598
1595
|
case "mapField": {
|
|
1599
1596
|
const { value, lastInsertId } = await this.interpretNode(node.args.records, queryable, scope, generators);
|
|
1600
|
-
return { value:
|
|
1597
|
+
return { value: mapField2(value, node.args.field), lastInsertId };
|
|
1601
1598
|
}
|
|
1602
1599
|
case "join": {
|
|
1603
1600
|
const { value: parent, lastInsertId } = await this.interpretNode(node.args.parent, queryable, scope, generators);
|
|
@@ -1618,7 +1615,7 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
1618
1615
|
}
|
|
1619
1616
|
const transactionManager = this.#transactionManager.manager;
|
|
1620
1617
|
const transactionInfo = await transactionManager.startTransaction();
|
|
1621
|
-
const transaction = transactionManager.getTransaction(transactionInfo, "query");
|
|
1618
|
+
const transaction = await transactionManager.getTransaction(transactionInfo, "query");
|
|
1622
1619
|
try {
|
|
1623
1620
|
const value = await this.interpretNode(node.args, transaction, scope, generators);
|
|
1624
1621
|
await transactionManager.commitTransaction(transactionInfo.id);
|
|
@@ -1740,9 +1737,9 @@ function asRecord(value) {
|
|
|
1740
1737
|
}
|
|
1741
1738
|
throw new Error(`Expected object, got ${typeof value}`);
|
|
1742
1739
|
}
|
|
1743
|
-
function
|
|
1740
|
+
function mapField2(value, field) {
|
|
1744
1741
|
if (Array.isArray(value)) {
|
|
1745
|
-
return value.map((element) =>
|
|
1742
|
+
return value.map((element) => mapField2(element, field));
|
|
1746
1743
|
}
|
|
1747
1744
|
if (typeof value === "object" && value !== null) {
|
|
1748
1745
|
return value[field] ?? null;
|
|
@@ -1786,7 +1783,7 @@ function attachChildrenToParents(parentRecords, children) {
|
|
|
1786
1783
|
function evalFieldInitializer(initializer, lastInsertId, scope, generators) {
|
|
1787
1784
|
switch (initializer.type) {
|
|
1788
1785
|
case "value":
|
|
1789
|
-
return
|
|
1786
|
+
return evaluateArg(initializer.value, scope, generators);
|
|
1790
1787
|
case "lastInsertId":
|
|
1791
1788
|
return lastInsertId;
|
|
1792
1789
|
default:
|
|
@@ -1796,16 +1793,16 @@ function evalFieldInitializer(initializer, lastInsertId, scope, generators) {
|
|
|
1796
1793
|
function evalFieldOperation(op, value, scope, generators) {
|
|
1797
1794
|
switch (op.type) {
|
|
1798
1795
|
case "set":
|
|
1799
|
-
return
|
|
1796
|
+
return evaluateArg(op.value, scope, generators);
|
|
1800
1797
|
case "add":
|
|
1801
|
-
return asNumber2(value) + asNumber2(
|
|
1798
|
+
return asNumber2(value) + asNumber2(evaluateArg(op.value, scope, generators));
|
|
1802
1799
|
case "subtract":
|
|
1803
|
-
return asNumber2(value) - asNumber2(
|
|
1800
|
+
return asNumber2(value) - asNumber2(evaluateArg(op.value, scope, generators));
|
|
1804
1801
|
case "multiply":
|
|
1805
|
-
return asNumber2(value) * asNumber2(
|
|
1802
|
+
return asNumber2(value) * asNumber2(evaluateArg(op.value, scope, generators));
|
|
1806
1803
|
case "divide": {
|
|
1807
1804
|
const lhs = asNumber2(value);
|
|
1808
|
-
const rhs = asNumber2(
|
|
1805
|
+
const rhs = asNumber2(evaluateArg(op.value, scope, generators));
|
|
1809
1806
|
if (rhs === 0) {
|
|
1810
1807
|
return null;
|
|
1811
1808
|
}
|
|
@@ -1876,11 +1873,6 @@ var TransactionClosedError = class extends TransactionManagerError {
|
|
|
1876
1873
|
super(`Transaction already closed: A ${operation} cannot be executed on a committed transaction.`);
|
|
1877
1874
|
}
|
|
1878
1875
|
};
|
|
1879
|
-
var TransactionClosingError = class extends TransactionManagerError {
|
|
1880
|
-
constructor(operation) {
|
|
1881
|
-
super(`Transaction is being closed: A ${operation} cannot be executed on a closing transaction.`);
|
|
1882
|
-
}
|
|
1883
|
-
};
|
|
1884
1876
|
var TransactionRolledBackError = class extends TransactionManagerError {
|
|
1885
1877
|
constructor(operation) {
|
|
1886
1878
|
super(`Transaction already closed: A ${operation} cannot be executed on a transaction that was rolled back.`);
|
|
@@ -1953,7 +1945,7 @@ var TransactionManager = class {
|
|
|
1953
1945
|
return await this.tracingHelper.runInChildSpan("start_transaction", () => this.#startTransactionImpl(options));
|
|
1954
1946
|
}
|
|
1955
1947
|
async #startTransactionImpl(options) {
|
|
1956
|
-
const validatedOptions = options !== void 0 ? this
|
|
1948
|
+
const validatedOptions = options !== void 0 ? this.#validateOptions(options) : this.transactionOptions;
|
|
1957
1949
|
const transaction = {
|
|
1958
1950
|
id: await randomUUID(),
|
|
1959
1951
|
status: "waiting",
|
|
@@ -1970,13 +1962,12 @@ var TransactionManager = class {
|
|
|
1970
1962
|
switch (transaction.status) {
|
|
1971
1963
|
case "waiting":
|
|
1972
1964
|
if (hasTimedOut) {
|
|
1973
|
-
await this
|
|
1965
|
+
await this.#closeTransaction(transaction, "timed_out");
|
|
1974
1966
|
throw new TransactionStartTimeoutError();
|
|
1975
1967
|
}
|
|
1976
1968
|
transaction.status = "running";
|
|
1977
|
-
transaction.timer = this
|
|
1969
|
+
transaction.timer = this.#startTransactionTimeout(transaction.id, validatedOptions.timeout);
|
|
1978
1970
|
return { id: transaction.id };
|
|
1979
|
-
case "closing":
|
|
1980
1971
|
case "timed_out":
|
|
1981
1972
|
case "running":
|
|
1982
1973
|
case "committed":
|
|
@@ -1985,27 +1976,31 @@ var TransactionManager = class {
|
|
|
1985
1976
|
`Transaction in invalid state ${transaction.status} although it just finished startup.`
|
|
1986
1977
|
);
|
|
1987
1978
|
default:
|
|
1988
|
-
assertNever(transaction
|
|
1979
|
+
assertNever(transaction["status"], "Unknown transaction status.");
|
|
1989
1980
|
}
|
|
1990
1981
|
}
|
|
1991
1982
|
async commitTransaction(transactionId) {
|
|
1992
1983
|
return await this.tracingHelper.runInChildSpan("commit_transaction", async () => {
|
|
1993
|
-
const txw = this
|
|
1994
|
-
await this
|
|
1984
|
+
const txw = this.#getActiveOrClosingTransaction(transactionId, "commit");
|
|
1985
|
+
await this.#closeTransaction(txw, "committed");
|
|
1995
1986
|
});
|
|
1996
1987
|
}
|
|
1997
1988
|
async rollbackTransaction(transactionId) {
|
|
1998
1989
|
return await this.tracingHelper.runInChildSpan("rollback_transaction", async () => {
|
|
1999
|
-
const txw = this
|
|
2000
|
-
await this
|
|
1990
|
+
const txw = this.#getActiveOrClosingTransaction(transactionId, "rollback");
|
|
1991
|
+
await this.#closeTransaction(txw, "rolled_back");
|
|
2001
1992
|
});
|
|
2002
1993
|
}
|
|
2003
|
-
getTransaction(txInfo, operation) {
|
|
2004
|
-
|
|
1994
|
+
async getTransaction(txInfo, operation) {
|
|
1995
|
+
let tx = this.#getActiveOrClosingTransaction(txInfo.id, operation);
|
|
1996
|
+
if (tx.status === "closing") {
|
|
1997
|
+
await tx.closing;
|
|
1998
|
+
tx = this.#getActiveOrClosingTransaction(txInfo.id, operation);
|
|
1999
|
+
}
|
|
2005
2000
|
if (!tx.transaction) throw new TransactionNotFoundError();
|
|
2006
2001
|
return tx.transaction;
|
|
2007
2002
|
}
|
|
2008
|
-
|
|
2003
|
+
#getActiveOrClosingTransaction(transactionId, operation) {
|
|
2009
2004
|
const transaction = this.transactions.get(transactionId);
|
|
2010
2005
|
if (!transaction) {
|
|
2011
2006
|
const closedTransaction = this.closedTransactions.find((tx) => tx.id === transactionId);
|
|
@@ -2031,62 +2026,74 @@ var TransactionManager = class {
|
|
|
2031
2026
|
throw new TransactionNotFoundError();
|
|
2032
2027
|
}
|
|
2033
2028
|
}
|
|
2034
|
-
if (transaction.status === "closing") {
|
|
2035
|
-
throw new TransactionClosingError(operation);
|
|
2036
|
-
}
|
|
2037
2029
|
if (["committed", "rolled_back", "timed_out"].includes(transaction.status)) {
|
|
2038
2030
|
throw new TransactionInternalConsistencyError("Closed transaction found in active transactions map.");
|
|
2039
2031
|
}
|
|
2040
2032
|
return transaction;
|
|
2041
2033
|
}
|
|
2042
2034
|
async cancelAllTransactions() {
|
|
2043
|
-
await Promise.allSettled([...this.transactions.values()].map((tx) => this
|
|
2035
|
+
await Promise.allSettled([...this.transactions.values()].map((tx) => this.#closeTransaction(tx, "rolled_back")));
|
|
2044
2036
|
}
|
|
2045
|
-
startTransactionTimeout(transactionId, timeout) {
|
|
2037
|
+
#startTransactionTimeout(transactionId, timeout) {
|
|
2046
2038
|
const timeoutStartedAt = Date.now();
|
|
2047
2039
|
return setTimeout(async () => {
|
|
2048
2040
|
debug("Transaction timed out.", { transactionId, timeoutStartedAt, timeout });
|
|
2049
2041
|
const tx = this.transactions.get(transactionId);
|
|
2050
2042
|
if (tx && ["running", "waiting"].includes(tx.status)) {
|
|
2051
|
-
await this
|
|
2043
|
+
await this.#closeTransaction(tx, "timed_out");
|
|
2052
2044
|
} else {
|
|
2053
2045
|
debug("Transaction already committed or rolled back when timeout happened.", transactionId);
|
|
2054
2046
|
}
|
|
2055
2047
|
}, timeout);
|
|
2056
2048
|
}
|
|
2057
|
-
async closeTransaction(tx, status) {
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2049
|
+
async #closeTransaction(tx, status) {
|
|
2050
|
+
const createClosingPromise = async () => {
|
|
2051
|
+
debug("Closing transaction.", { transactionId: tx.id, status });
|
|
2052
|
+
try {
|
|
2053
|
+
if (tx.transaction && status === "committed") {
|
|
2054
|
+
if (tx.transaction.options.usePhantomQuery) {
|
|
2055
|
+
await this.#withQuerySpanAndEvent(PHANTOM_COMMIT_QUERY(), tx.transaction, () => tx.transaction.commit());
|
|
2056
|
+
} else {
|
|
2057
|
+
const query = COMMIT_QUERY();
|
|
2058
|
+
await this.#withQuerySpanAndEvent(query, tx.transaction, () => tx.transaction.executeRaw(query));
|
|
2059
|
+
await tx.transaction.commit();
|
|
2060
|
+
}
|
|
2061
|
+
} else if (tx.transaction) {
|
|
2062
|
+
if (tx.transaction.options.usePhantomQuery) {
|
|
2063
|
+
await this.#withQuerySpanAndEvent(
|
|
2064
|
+
PHANTOM_ROLLBACK_QUERY(),
|
|
2065
|
+
tx.transaction,
|
|
2066
|
+
() => tx.transaction.rollback()
|
|
2067
|
+
);
|
|
2068
|
+
} else {
|
|
2069
|
+
const query = ROLLBACK_QUERY();
|
|
2070
|
+
await this.#withQuerySpanAndEvent(query, tx.transaction, () => tx.transaction.executeRaw(query));
|
|
2071
|
+
await tx.transaction.rollback();
|
|
2072
|
+
}
|
|
2068
2073
|
}
|
|
2069
|
-
}
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2074
|
+
} finally {
|
|
2075
|
+
tx.status = status;
|
|
2076
|
+
clearTimeout(tx.timer);
|
|
2077
|
+
tx.timer = void 0;
|
|
2078
|
+
this.transactions.delete(tx.id);
|
|
2079
|
+
this.closedTransactions.push(tx);
|
|
2080
|
+
if (this.closedTransactions.length > MAX_CLOSED_TRANSACTIONS) {
|
|
2081
|
+
this.closedTransactions.shift();
|
|
2076
2082
|
}
|
|
2077
2083
|
}
|
|
2078
|
-
}
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
tx.
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2084
|
+
};
|
|
2085
|
+
if (tx.status === "closing") {
|
|
2086
|
+
await tx.closing;
|
|
2087
|
+
this.#getActiveOrClosingTransaction(tx.id, status === "committed" ? "commit" : "rollback");
|
|
2088
|
+
} else {
|
|
2089
|
+
await Object.assign(tx, {
|
|
2090
|
+
status: "closing",
|
|
2091
|
+
reason: status,
|
|
2092
|
+
closing: createClosingPromise()
|
|
2093
|
+
}).closing;
|
|
2087
2094
|
}
|
|
2088
2095
|
}
|
|
2089
|
-
validateOptions(options) {
|
|
2096
|
+
#validateOptions(options) {
|
|
2090
2097
|
if (!options.timeout) throw new TransactionManagerError("timeout is required");
|
|
2091
2098
|
if (!options.maxWait) throw new TransactionManagerError("maxWait is required");
|
|
2092
2099
|
if (options.isolationLevel === "SNAPSHOT") throw new InvalidTransactionIsolationLevelError(options.isolationLevel);
|
|
@@ -2117,8 +2124,6 @@ var TransactionManager = class {
|
|
|
2117
2124
|
deserializeJsonResponse,
|
|
2118
2125
|
doKeysMatch,
|
|
2119
2126
|
isDeepStrictEqual,
|
|
2120
|
-
isPrismaValueBigInt,
|
|
2121
|
-
isPrismaValueBytes,
|
|
2122
2127
|
isPrismaValueGenerator,
|
|
2123
2128
|
isPrismaValuePlaceholder,
|
|
2124
2129
|
noopTracingHelper,
|