@prisma/client-engine-runtime 6.9.0-dev.3 → 6.9.0-dev.30
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/QueryPlan.d.ts +37 -1
- package/dist/UserFacingError.d.ts +3 -3
- package/dist/index.d.mts +75 -13
- package/dist/index.d.ts +75 -13
- package/dist/index.js +500 -151
- package/dist/index.mjs +494 -150
- package/dist/interpreter/DataMapper.d.ts +3 -0
- package/dist/interpreter/QueryInterpreter.d.ts +2 -1
- package/dist/interpreter/serializeSql.d.ts +2 -1
- package/dist/tracing.d.ts +10 -2
- package/dist/transactionManager/TransactionManager.d.ts +3 -1
- package/dist/transactionManager/TransactionManagerErrors.d.ts +4 -4
- package/dist/utils.d.ts +15 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -30,26 +30,253 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
DataMapperError: () => DataMapperError,
|
|
33
34
|
QueryInterpreter: () => QueryInterpreter,
|
|
34
35
|
TransactionManager: () => TransactionManager,
|
|
35
36
|
TransactionManagerError: () => TransactionManagerError,
|
|
36
37
|
UserFacingError: () => UserFacingError,
|
|
38
|
+
doKeysMatch: () => doKeysMatch,
|
|
39
|
+
isDeepStrictEqual: () => isDeepStrictEqual,
|
|
40
|
+
isPrismaValueBigInt: () => isPrismaValueBigInt,
|
|
37
41
|
isPrismaValueBytes: () => isPrismaValueBytes,
|
|
38
42
|
isPrismaValueGenerator: () => isPrismaValueGenerator,
|
|
39
43
|
isPrismaValuePlaceholder: () => isPrismaValuePlaceholder,
|
|
40
|
-
noopTracingHelper: () => noopTracingHelper
|
|
44
|
+
noopTracingHelper: () => noopTracingHelper,
|
|
45
|
+
safeJsonStringify: () => safeJsonStringify
|
|
41
46
|
});
|
|
42
47
|
module.exports = __toCommonJS(index_exports);
|
|
43
48
|
|
|
44
|
-
// src/interpreter/
|
|
45
|
-
var
|
|
49
|
+
// src/interpreter/DataMapper.ts
|
|
50
|
+
var import_decimal2 = __toESM(require("decimal.js"));
|
|
46
51
|
|
|
47
52
|
// src/utils.ts
|
|
53
|
+
var import_decimal = __toESM(require("decimal.js"));
|
|
48
54
|
function assertNever(_, message) {
|
|
49
55
|
throw new Error(message);
|
|
50
56
|
}
|
|
57
|
+
function isDeepStrictEqual(a, b) {
|
|
58
|
+
return a === b || a !== null && b !== null && typeof a === "object" && typeof b === "object" && Object.keys(a).length === Object.keys(b).length && Object.keys(a).every((key) => isDeepStrictEqual(a[key], b[key]));
|
|
59
|
+
}
|
|
60
|
+
function doKeysMatch(lhs, rhs) {
|
|
61
|
+
const lhsKeys = Object.keys(lhs);
|
|
62
|
+
const rhsKeys = Object.keys(rhs);
|
|
63
|
+
const smallerKeyList = lhsKeys.length < rhsKeys.length ? lhsKeys : rhsKeys;
|
|
64
|
+
return smallerKeyList.every((key) => {
|
|
65
|
+
if (typeof lhs[key] !== typeof rhs[key]) {
|
|
66
|
+
if (typeof lhs[key] === "number" || typeof rhs[key] === "number") {
|
|
67
|
+
return `${lhs[key]}` === `${rhs[key]}`;
|
|
68
|
+
} else if (typeof lhs[key] === "bigint" || typeof rhs[key] === "bigint") {
|
|
69
|
+
return BigInt(`${lhs[key]}`.replace(/n$/, "")) === BigInt(`${rhs[key]}`.replace(/n$/, ""));
|
|
70
|
+
} else if (lhs[key] instanceof Date || rhs[key] instanceof Date) {
|
|
71
|
+
return (/* @__PURE__ */ new Date(`${lhs[key]}`)).getTime() === (/* @__PURE__ */ new Date(`${rhs[key]}`)).getTime();
|
|
72
|
+
} else if (import_decimal.default.isDecimal(lhs[key]) || import_decimal.default.isDecimal(rhs[key])) {
|
|
73
|
+
return new import_decimal.default(`${lhs[key]}`).equals(new import_decimal.default(`${rhs[key]}`));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return isDeepStrictEqual(lhs[key], rhs[key]);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
function safeJsonStringify(obj) {
|
|
80
|
+
return JSON.stringify(obj, (_key, val) => {
|
|
81
|
+
if (typeof val === "bigint") {
|
|
82
|
+
return val.toString();
|
|
83
|
+
} else if (val instanceof Uint8Array) {
|
|
84
|
+
return Buffer.from(val).toString("base64");
|
|
85
|
+
}
|
|
86
|
+
return val;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// src/interpreter/DataMapper.ts
|
|
91
|
+
var DataMapperError = class extends Error {
|
|
92
|
+
name = "DataMapperError";
|
|
93
|
+
};
|
|
94
|
+
function applyDataMap(data, structure) {
|
|
95
|
+
switch (structure.type) {
|
|
96
|
+
case "Object":
|
|
97
|
+
return mapArrayOrObject(data, structure.fields);
|
|
98
|
+
case "Value":
|
|
99
|
+
return mapValue(data, "<result>", structure.resultType);
|
|
100
|
+
default:
|
|
101
|
+
assertNever(structure, `Invalid data mapping type: '${structure.type}'`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function mapArrayOrObject(data, fields) {
|
|
105
|
+
if (data === null) return null;
|
|
106
|
+
if (Array.isArray(data)) {
|
|
107
|
+
const rows = data;
|
|
108
|
+
return rows.map((row) => mapObject(row, fields));
|
|
109
|
+
}
|
|
110
|
+
if (typeof data === "object") {
|
|
111
|
+
const row = data;
|
|
112
|
+
return mapObject(row, fields);
|
|
113
|
+
}
|
|
114
|
+
if (typeof data === "string") {
|
|
115
|
+
let decodedData;
|
|
116
|
+
try {
|
|
117
|
+
decodedData = JSON.parse(data);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
throw new DataMapperError(`Expected an array or object, got a string that is not valid JSON`, {
|
|
120
|
+
cause: error
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return mapArrayOrObject(decodedData, fields);
|
|
124
|
+
}
|
|
125
|
+
throw new DataMapperError(`Expected an array or an object, got: ${typeof data}`);
|
|
126
|
+
}
|
|
127
|
+
function mapObject(data, fields) {
|
|
128
|
+
if (typeof data !== "object") {
|
|
129
|
+
throw new DataMapperError(`Expected an object, but got '${typeof data}'`);
|
|
130
|
+
}
|
|
131
|
+
const result = {};
|
|
132
|
+
for (const [name, node] of Object.entries(fields)) {
|
|
133
|
+
switch (node.type) {
|
|
134
|
+
case "Object": {
|
|
135
|
+
if (!node.flattened && !Object.hasOwn(data, name)) {
|
|
136
|
+
throw new DataMapperError(
|
|
137
|
+
`Missing data field (Object): '${name}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
const target = node.flattened ? data : data[name];
|
|
141
|
+
result[name] = mapArrayOrObject(target, node.fields);
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
case "Value":
|
|
145
|
+
{
|
|
146
|
+
const dbName = node.dbName;
|
|
147
|
+
if (Object.hasOwn(data, dbName)) {
|
|
148
|
+
result[name] = mapValue(data[dbName], dbName, node.resultType);
|
|
149
|
+
} else {
|
|
150
|
+
throw new DataMapperError(
|
|
151
|
+
`Missing data field (Value): '${dbName}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
break;
|
|
156
|
+
default:
|
|
157
|
+
assertNever(node, `DataMapper: Invalid data mapping node type: '${node.type}'`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
function mapValue(value, columnName, resultType) {
|
|
163
|
+
if (value === null) return null;
|
|
164
|
+
switch (resultType.type) {
|
|
165
|
+
case "Any":
|
|
166
|
+
return value;
|
|
167
|
+
case "String": {
|
|
168
|
+
if (typeof value !== "string") {
|
|
169
|
+
throw new DataMapperError(`Expected a string in column '${columnName}', got ${typeof value}: ${value}`);
|
|
170
|
+
}
|
|
171
|
+
return value;
|
|
172
|
+
}
|
|
173
|
+
case "Int": {
|
|
174
|
+
switch (typeof value) {
|
|
175
|
+
case "number": {
|
|
176
|
+
return Math.trunc(value);
|
|
177
|
+
}
|
|
178
|
+
case "string": {
|
|
179
|
+
const numberValue = Math.trunc(Number(value));
|
|
180
|
+
if (Number.isNaN(numberValue) || !Number.isFinite(numberValue)) {
|
|
181
|
+
throw new DataMapperError(`Expected an integer in column '${columnName}', got string: ${value}`);
|
|
182
|
+
}
|
|
183
|
+
if (!Number.isSafeInteger(numberValue)) {
|
|
184
|
+
throw new DataMapperError(
|
|
185
|
+
`Integer value in column '${columnName}' is too large to represent as a JavaScript number without loss of precision, got: ${value}. Consider using BigInt type.`
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
return numberValue;
|
|
189
|
+
}
|
|
190
|
+
default:
|
|
191
|
+
throw new DataMapperError(`Expected an integer in column '${columnName}', got ${typeof value}: ${value}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
case "BigInt": {
|
|
195
|
+
if (typeof value !== "number" && typeof value !== "string") {
|
|
196
|
+
throw new DataMapperError(`Expected a bigint in column '${columnName}', got ${typeof value}: ${value}`);
|
|
197
|
+
}
|
|
198
|
+
return { $type: "BigInt", value };
|
|
199
|
+
}
|
|
200
|
+
case "Float": {
|
|
201
|
+
if (typeof value === "number") return value;
|
|
202
|
+
if (typeof value === "string") {
|
|
203
|
+
const parsedValue = Number(value);
|
|
204
|
+
if (Number.isNaN(parsedValue) && !/^[-+]?nan$/.test(value.toLowerCase())) {
|
|
205
|
+
throw new DataMapperError(`Expected a float in column '${columnName}', got string: ${value}`);
|
|
206
|
+
}
|
|
207
|
+
return parsedValue;
|
|
208
|
+
}
|
|
209
|
+
throw new DataMapperError(`Expected a float in column '${columnName}', got ${typeof value}: ${value}`);
|
|
210
|
+
}
|
|
211
|
+
case "Boolean": {
|
|
212
|
+
if (typeof value === "boolean") return value;
|
|
213
|
+
if (typeof value === "number") return value === 1;
|
|
214
|
+
if (typeof value === "string") {
|
|
215
|
+
if (value === "true" || value === "TRUE" || value === "1") {
|
|
216
|
+
return true;
|
|
217
|
+
} else if (value === "false" || value === "FALSE" || value === "0") {
|
|
218
|
+
return false;
|
|
219
|
+
} else {
|
|
220
|
+
throw new DataMapperError(`Expected a boolean in column '${columnName}', got ${typeof value}: ${value}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
throw new DataMapperError(`Expected a boolean in column '${columnName}', got ${typeof value}: ${value}`);
|
|
224
|
+
}
|
|
225
|
+
case "Decimal":
|
|
226
|
+
if (typeof value !== "number" && typeof value !== "string" && !import_decimal2.default.isDecimal(value)) {
|
|
227
|
+
throw new DataMapperError(`Expected a decimal in column '${columnName}', got ${typeof value}: ${value}`);
|
|
228
|
+
}
|
|
229
|
+
return { $type: "Decimal", value };
|
|
230
|
+
case "Date": {
|
|
231
|
+
if (typeof value === "string") {
|
|
232
|
+
return { $type: "DateTime", value: ensureTimezoneInIsoString(value) };
|
|
233
|
+
}
|
|
234
|
+
if (typeof value === "number" || value instanceof Date) {
|
|
235
|
+
return { $type: "DateTime", value };
|
|
236
|
+
}
|
|
237
|
+
throw new DataMapperError(`Expected a date in column '${columnName}', got ${typeof value}: ${value}`);
|
|
238
|
+
}
|
|
239
|
+
case "Time": {
|
|
240
|
+
if (typeof value === "string") {
|
|
241
|
+
return { $type: "DateTime", value: `1970-01-01T${ensureTimezoneInIsoString(value)}` };
|
|
242
|
+
}
|
|
243
|
+
throw new DataMapperError(`Expected a time in column '${columnName}', got ${typeof value}: ${value}`);
|
|
244
|
+
}
|
|
245
|
+
case "Array": {
|
|
246
|
+
const values = value;
|
|
247
|
+
return values.map((v, i) => mapValue(v, `${columnName}[${i}]`, resultType.inner));
|
|
248
|
+
}
|
|
249
|
+
case "Object": {
|
|
250
|
+
const jsonValue = typeof value === "string" ? value : safeJsonStringify(value);
|
|
251
|
+
return { $type: "Json", value: jsonValue };
|
|
252
|
+
}
|
|
253
|
+
case "Bytes": {
|
|
254
|
+
if (typeof value === "string" && value.startsWith("\\x")) {
|
|
255
|
+
return { $type: "Bytes", value: Buffer.from(value.slice(2), "hex").toString("base64") };
|
|
256
|
+
}
|
|
257
|
+
if (Array.isArray(value)) {
|
|
258
|
+
return { $type: "Bytes", value: Buffer.from(value).toString("base64") };
|
|
259
|
+
}
|
|
260
|
+
throw new DataMapperError(`Expected a byte array in column '${columnName}', got ${typeof value}: ${value}`);
|
|
261
|
+
}
|
|
262
|
+
default:
|
|
263
|
+
assertNever(resultType, `DataMapper: Unknown result type: ${resultType.type}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
var TIMEZONE_PATTERN = /Z$|(?<!\d{4}-\d{2})[+-]\d{2}(:?\d{2})?$/;
|
|
267
|
+
function ensureTimezoneInIsoString(dt) {
|
|
268
|
+
const results = TIMEZONE_PATTERN.exec(dt);
|
|
269
|
+
if (results === null) {
|
|
270
|
+
return `${dt}Z`;
|
|
271
|
+
} else if (results[0] !== "Z" && results[1] === void 0) {
|
|
272
|
+
return `${dt}:00`;
|
|
273
|
+
} else {
|
|
274
|
+
return dt;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
51
277
|
|
|
52
278
|
// src/tracing.ts
|
|
279
|
+
var import_api = require("@opentelemetry/api");
|
|
53
280
|
var noopTracingHelper = {
|
|
54
281
|
runInChildSpan(_, callback) {
|
|
55
282
|
return callback();
|
|
@@ -67,6 +294,37 @@ function providerToOtelSystem(provider) {
|
|
|
67
294
|
assertNever(provider, `Unknown provider: ${provider}`);
|
|
68
295
|
}
|
|
69
296
|
}
|
|
297
|
+
async function withQuerySpanAndEvent({
|
|
298
|
+
query,
|
|
299
|
+
queryable,
|
|
300
|
+
tracingHelper,
|
|
301
|
+
onQuery,
|
|
302
|
+
execute
|
|
303
|
+
}) {
|
|
304
|
+
return await tracingHelper.runInChildSpan(
|
|
305
|
+
{
|
|
306
|
+
name: "db_query",
|
|
307
|
+
kind: import_api.SpanKind.CLIENT,
|
|
308
|
+
attributes: {
|
|
309
|
+
"db.query.text": query.sql,
|
|
310
|
+
"db.system.name": providerToOtelSystem(queryable.provider)
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
async () => {
|
|
314
|
+
const timestamp = /* @__PURE__ */ new Date();
|
|
315
|
+
const startInstant = performance.now();
|
|
316
|
+
const result = await execute();
|
|
317
|
+
const endInstant = performance.now();
|
|
318
|
+
onQuery?.({
|
|
319
|
+
timestamp,
|
|
320
|
+
duration: endInstant - startInstant,
|
|
321
|
+
query: query.sql,
|
|
322
|
+
params: query.args
|
|
323
|
+
});
|
|
324
|
+
return result;
|
|
325
|
+
}
|
|
326
|
+
);
|
|
327
|
+
}
|
|
70
328
|
|
|
71
329
|
// src/UserFacingError.ts
|
|
72
330
|
var import_driver_adapter_utils = require("@prisma/driver-adapter-utils");
|
|
@@ -77,7 +335,7 @@ var UserFacingError = class extends Error {
|
|
|
77
335
|
constructor(message, code, meta) {
|
|
78
336
|
super(message);
|
|
79
337
|
this.code = code;
|
|
80
|
-
this.meta = meta;
|
|
338
|
+
this.meta = meta ?? {};
|
|
81
339
|
}
|
|
82
340
|
toQueryResponseErrorObject() {
|
|
83
341
|
return {
|
|
@@ -100,7 +358,7 @@ function rethrowAsUserFacing(error) {
|
|
|
100
358
|
if (!code || !message) {
|
|
101
359
|
throw error;
|
|
102
360
|
}
|
|
103
|
-
throw new UserFacingError(message, code, error);
|
|
361
|
+
throw new UserFacingError(message, code, { driverAdapterError: error });
|
|
104
362
|
}
|
|
105
363
|
function getErrorCode(err) {
|
|
106
364
|
switch (err.cause.kind) {
|
|
@@ -211,101 +469,6 @@ function renderConstraint(constraint) {
|
|
|
211
469
|
return "(not available)";
|
|
212
470
|
}
|
|
213
471
|
|
|
214
|
-
// src/interpreter/DataMapper.ts
|
|
215
|
-
var import_decimal = __toESM(require("decimal.js"));
|
|
216
|
-
function applyDataMap(data, structure) {
|
|
217
|
-
switch (structure.type) {
|
|
218
|
-
case "Object":
|
|
219
|
-
return mapArrayOrObject(data, structure.fields);
|
|
220
|
-
case "Value":
|
|
221
|
-
return mapValue(data, structure.resultType);
|
|
222
|
-
default:
|
|
223
|
-
assertNever(structure, `Invalid data mapping type: '${structure.type}'`);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
function mapArrayOrObject(data, fields) {
|
|
227
|
-
if (data === null) return null;
|
|
228
|
-
if (Array.isArray(data)) {
|
|
229
|
-
const rows = data;
|
|
230
|
-
return rows.map((row) => mapObject(row, fields));
|
|
231
|
-
}
|
|
232
|
-
if (typeof data === "object") {
|
|
233
|
-
const row = data;
|
|
234
|
-
return mapObject(row, fields);
|
|
235
|
-
}
|
|
236
|
-
throw new Error(`DataMapper: Expected an array or an object, got: ${typeof data}`);
|
|
237
|
-
}
|
|
238
|
-
function mapObject(data, fields) {
|
|
239
|
-
if (typeof data !== "object") {
|
|
240
|
-
throw new Error(`DataMapper: Expected an object, but got '${typeof data}'`);
|
|
241
|
-
}
|
|
242
|
-
const result = {};
|
|
243
|
-
for (const [name, node] of Object.entries(fields)) {
|
|
244
|
-
switch (node.type) {
|
|
245
|
-
case "Object": {
|
|
246
|
-
if (!node.flattened && !Object.hasOwn(data, name)) {
|
|
247
|
-
throw new Error(
|
|
248
|
-
`DataMapper: Missing data field (Object): '${name}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
const target = node.flattened ? data : data[name];
|
|
252
|
-
result[name] = mapArrayOrObject(target, node.fields);
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
255
|
-
case "Value":
|
|
256
|
-
{
|
|
257
|
-
const dbName = node.dbName;
|
|
258
|
-
if (Object.hasOwn(data, dbName)) {
|
|
259
|
-
result[name] = mapValue(data[dbName], node.resultType);
|
|
260
|
-
} else {
|
|
261
|
-
throw new Error(
|
|
262
|
-
`DataMapper: Missing data field (Value): '${dbName}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
break;
|
|
267
|
-
default:
|
|
268
|
-
assertNever(node, `DataMapper: Invalid data mapping node type: '${node.type}'`);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
return result;
|
|
272
|
-
}
|
|
273
|
-
function mapValue(value, resultType) {
|
|
274
|
-
if (value === null) return null;
|
|
275
|
-
switch (resultType.type) {
|
|
276
|
-
case "Any":
|
|
277
|
-
return value;
|
|
278
|
-
case "String":
|
|
279
|
-
return typeof value === "string" ? value : `${value}`;
|
|
280
|
-
case "Int":
|
|
281
|
-
return typeof value === "number" ? value : parseInt(`${value}`, 10);
|
|
282
|
-
case "BigInt":
|
|
283
|
-
return typeof value === "bigint" ? value : BigInt(`${value}`);
|
|
284
|
-
case "Float":
|
|
285
|
-
return typeof value === "number" ? value : parseFloat(`${value}`);
|
|
286
|
-
case "Boolean":
|
|
287
|
-
return typeof value === "boolean" ? value : value !== "0";
|
|
288
|
-
case "Decimal":
|
|
289
|
-
return typeof value === "number" ? new import_decimal.default(value) : new import_decimal.default(`${value}`);
|
|
290
|
-
case "Date":
|
|
291
|
-
return value instanceof Date ? value : /* @__PURE__ */ new Date(`${value}`);
|
|
292
|
-
case "Array": {
|
|
293
|
-
const values = value;
|
|
294
|
-
return values.map((v) => mapValue(v, resultType.inner));
|
|
295
|
-
}
|
|
296
|
-
case "Object":
|
|
297
|
-
return typeof value === "string" ? value : JSON.stringify(value);
|
|
298
|
-
case "Bytes": {
|
|
299
|
-
if (!Array.isArray(value)) {
|
|
300
|
-
throw new Error(`DataMapper: Bytes data is invalid, got: ${typeof value}`);
|
|
301
|
-
}
|
|
302
|
-
return new Uint8Array(value);
|
|
303
|
-
}
|
|
304
|
-
default:
|
|
305
|
-
assertNever(resultType, `DataMapper: Unknown result type: ${resultType.type}`);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
472
|
// src/interpreter/generators.ts
|
|
310
473
|
var import_cuid = __toESM(require("@bugsnag/cuid"));
|
|
311
474
|
var import_cuid2 = require("@paralleldrive/cuid2");
|
|
@@ -410,6 +573,9 @@ function isPrismaValueGenerator(value) {
|
|
|
410
573
|
function isPrismaValueBytes(value) {
|
|
411
574
|
return typeof value === "object" && value !== null && value["prisma__type"] === "bytes";
|
|
412
575
|
}
|
|
576
|
+
function isPrismaValueBigInt(value) {
|
|
577
|
+
return typeof value === "object" && value !== null && value["prisma__type"] === "bigint";
|
|
578
|
+
}
|
|
413
579
|
|
|
414
580
|
// src/interpreter/renderQuery.ts
|
|
415
581
|
function renderQuery(dbQuery, scope, generators) {
|
|
@@ -452,9 +618,10 @@ function evaluateParam(param, scope, generators) {
|
|
|
452
618
|
}
|
|
453
619
|
if (Array.isArray(value)) {
|
|
454
620
|
value = value.map((el) => evaluateParam(el, scope, generators));
|
|
455
|
-
}
|
|
456
|
-
if (isPrismaValueBytes(value)) {
|
|
621
|
+
} else if (isPrismaValueBytes(value)) {
|
|
457
622
|
value = Buffer.from(value.prisma__value, "base64");
|
|
623
|
+
} else if (isPrismaValueBigInt(value)) {
|
|
624
|
+
value = BigInt(value.prisma__value);
|
|
458
625
|
}
|
|
459
626
|
return value;
|
|
460
627
|
}
|
|
@@ -548,6 +715,7 @@ function doesRequireEvaluation(param) {
|
|
|
548
715
|
}
|
|
549
716
|
|
|
550
717
|
// src/interpreter/serializeSql.ts
|
|
718
|
+
var import_driver_adapter_utils2 = require("@prisma/driver-adapter-utils");
|
|
551
719
|
function serializeSql(resultSet) {
|
|
552
720
|
return resultSet.rows.map(
|
|
553
721
|
(row) => row.reduce((acc, value, index) => {
|
|
@@ -568,6 +736,96 @@ function serializeSql(resultSet) {
|
|
|
568
736
|
}, {})
|
|
569
737
|
);
|
|
570
738
|
}
|
|
739
|
+
function serializeRawSql(resultSet) {
|
|
740
|
+
const types = resultSet.columnTypes.map((type) => serializeColumnType(type));
|
|
741
|
+
const mappers = types.map((type) => {
|
|
742
|
+
switch (type) {
|
|
743
|
+
case "int":
|
|
744
|
+
return (value) => value === null ? null : typeof value === "number" ? value : parseInt(`${value}`, 10);
|
|
745
|
+
case "bigint":
|
|
746
|
+
return (value) => value === null ? null : typeof value === "bigint" ? value : BigInt(`${value}`);
|
|
747
|
+
default:
|
|
748
|
+
return (value) => value;
|
|
749
|
+
}
|
|
750
|
+
});
|
|
751
|
+
return {
|
|
752
|
+
columns: resultSet.columnNames,
|
|
753
|
+
types: resultSet.columnTypes.map((type) => serializeColumnType(type)),
|
|
754
|
+
rows: resultSet.rows.map((row) => row.map((value, index) => mappers[index](value)))
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
function serializeColumnType(columnType) {
|
|
758
|
+
switch (columnType) {
|
|
759
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Int32:
|
|
760
|
+
return "int";
|
|
761
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Int64:
|
|
762
|
+
return "bigint";
|
|
763
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Float:
|
|
764
|
+
return "float";
|
|
765
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Double:
|
|
766
|
+
return "double";
|
|
767
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Text:
|
|
768
|
+
return "string";
|
|
769
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Enum:
|
|
770
|
+
return "enum";
|
|
771
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Bytes:
|
|
772
|
+
return "bytes";
|
|
773
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Boolean:
|
|
774
|
+
return "bool";
|
|
775
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Character:
|
|
776
|
+
return "char";
|
|
777
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Numeric:
|
|
778
|
+
return "decimal";
|
|
779
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Json:
|
|
780
|
+
return "json";
|
|
781
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Uuid:
|
|
782
|
+
return "uuid";
|
|
783
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.DateTime:
|
|
784
|
+
return "datetime";
|
|
785
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Date:
|
|
786
|
+
return "date";
|
|
787
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Time:
|
|
788
|
+
return "time";
|
|
789
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Int32Array:
|
|
790
|
+
return "int-array";
|
|
791
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Int64Array:
|
|
792
|
+
return "bigint-array";
|
|
793
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.FloatArray:
|
|
794
|
+
return "float-array";
|
|
795
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.DoubleArray:
|
|
796
|
+
return "double-array";
|
|
797
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.TextArray:
|
|
798
|
+
return "string-array";
|
|
799
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.EnumArray:
|
|
800
|
+
return "string-array";
|
|
801
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.BytesArray:
|
|
802
|
+
return "bytes-array";
|
|
803
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.BooleanArray:
|
|
804
|
+
return "bool-array";
|
|
805
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.CharacterArray:
|
|
806
|
+
return "char-array";
|
|
807
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.NumericArray:
|
|
808
|
+
return "decimal-array";
|
|
809
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.JsonArray:
|
|
810
|
+
return "json-array";
|
|
811
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.UuidArray:
|
|
812
|
+
return "uuid-array";
|
|
813
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.DateTimeArray:
|
|
814
|
+
return "datetime-array";
|
|
815
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.DateArray:
|
|
816
|
+
return "date-array";
|
|
817
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.TimeArray:
|
|
818
|
+
return "time-array";
|
|
819
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.UnknownNumber:
|
|
820
|
+
return "unknown";
|
|
821
|
+
/// The following PlanetScale type IDs are mapped into Set:
|
|
822
|
+
/// - SET (SET) -> e.g. `"foo,bar"` (String-encoded, comma-separated)
|
|
823
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Set:
|
|
824
|
+
return "string";
|
|
825
|
+
default:
|
|
826
|
+
assertNever(columnType, `Unexpected column type: ${columnType}`);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
571
829
|
|
|
572
830
|
// src/interpreter/validation.ts
|
|
573
831
|
function performValidation(data, rules, error) {
|
|
@@ -595,6 +853,8 @@ function doesSatisfyRule(data, rule) {
|
|
|
595
853
|
return rule.args !== 0;
|
|
596
854
|
}
|
|
597
855
|
return rule.args !== 1;
|
|
856
|
+
case "affectedRowCountEq":
|
|
857
|
+
return data === rule.args;
|
|
598
858
|
case "never":
|
|
599
859
|
return false;
|
|
600
860
|
default:
|
|
@@ -612,7 +872,9 @@ function renderMessage(data, error) {
|
|
|
612
872
|
return `An operation failed because it depends on one or more records that were required but not found. No '${error.context.model}' record${hint} was found for ${error.context.operation} on ${error.context.relationType} relation '${error.context.relation}'.`;
|
|
613
873
|
}
|
|
614
874
|
case "INCOMPLETE_CONNECT_INPUT":
|
|
615
|
-
return `An operation failed because it depends on one or more records that were required but not found. Expected ${error.context.expectedRows} records to be connected, found only ${Array.isArray(data) ? data.length :
|
|
875
|
+
return `An operation failed because it depends on one or more records that were required but not found. Expected ${error.context.expectedRows} records to be connected, found only ${Array.isArray(data) ? data.length : data}.`;
|
|
876
|
+
case "INCOMPLETE_CONNECT_OUTPUT":
|
|
877
|
+
return `The required connected records were not found. Expected ${error.context.expectedRows} records to be connected after connect operation on ${error.context.relationType} relation '${error.context.relation}', found ${Array.isArray(data) ? data.length : data}.`;
|
|
616
878
|
case "RECORDS_NOT_CONNECTED":
|
|
617
879
|
return `The records for relation \`${error.context.relation}\` between the \`${error.context.parent}\` and \`${error.context.child}\` models are not connected.`;
|
|
618
880
|
default:
|
|
@@ -625,6 +887,8 @@ function getErrorCode2(error) {
|
|
|
625
887
|
return "P2014";
|
|
626
888
|
case "RECORDS_NOT_CONNECTED":
|
|
627
889
|
return "P2017";
|
|
890
|
+
case "INCOMPLETE_CONNECT_OUTPUT":
|
|
891
|
+
return "P2018";
|
|
628
892
|
case "MISSING_RECORD":
|
|
629
893
|
case "MISSING_RELATED_RECORD":
|
|
630
894
|
case "INCOMPLETE_CONNECT_INPUT":
|
|
@@ -642,12 +906,21 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
642
906
|
#generators = new GeneratorRegistry();
|
|
643
907
|
#tracingHelper;
|
|
644
908
|
#serializer;
|
|
645
|
-
|
|
909
|
+
#rawSerializer;
|
|
910
|
+
constructor({
|
|
911
|
+
transactionManager,
|
|
912
|
+
placeholderValues,
|
|
913
|
+
onQuery,
|
|
914
|
+
tracingHelper,
|
|
915
|
+
serializer,
|
|
916
|
+
rawSerializer
|
|
917
|
+
}) {
|
|
646
918
|
this.#transactionManager = transactionManager;
|
|
647
919
|
this.#placeholderValues = placeholderValues;
|
|
648
920
|
this.#onQuery = onQuery;
|
|
649
921
|
this.#tracingHelper = tracingHelper;
|
|
650
922
|
this.#serializer = serializer;
|
|
923
|
+
this.#rawSerializer = rawSerializer ?? serializer;
|
|
651
924
|
}
|
|
652
925
|
static forSql(options) {
|
|
653
926
|
return new _QueryInterpreter({
|
|
@@ -655,7 +928,8 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
655
928
|
placeholderValues: options.placeholderValues,
|
|
656
929
|
onQuery: options.onQuery,
|
|
657
930
|
tracingHelper: options.tracingHelper,
|
|
658
|
-
serializer: serializeSql
|
|
931
|
+
serializer: serializeSql,
|
|
932
|
+
rawSerializer: serializeRawSql
|
|
659
933
|
});
|
|
660
934
|
}
|
|
661
935
|
async run(queryPlan, queryable) {
|
|
@@ -666,8 +940,11 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
666
940
|
async interpretNode(node, queryable, scope, generators) {
|
|
667
941
|
switch (node.type) {
|
|
668
942
|
case "seq": {
|
|
669
|
-
|
|
670
|
-
|
|
943
|
+
let result;
|
|
944
|
+
for (const arg of node.args) {
|
|
945
|
+
result = await this.interpretNode(arg, queryable, scope, generators);
|
|
946
|
+
}
|
|
947
|
+
return result;
|
|
671
948
|
}
|
|
672
949
|
case "get": {
|
|
673
950
|
return scope[node.args.name];
|
|
@@ -690,22 +967,26 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
690
967
|
}
|
|
691
968
|
case "concat": {
|
|
692
969
|
const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
|
|
693
|
-
return parts.reduce((acc, part) => acc.concat(asList(part)), []);
|
|
970
|
+
return parts.length > 0 ? parts.reduce((acc, part) => acc.concat(asList(part)), []) : [];
|
|
694
971
|
}
|
|
695
972
|
case "sum": {
|
|
696
973
|
const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
|
|
697
|
-
return parts.reduce((acc, part) => asNumber(acc) + asNumber(part));
|
|
974
|
+
return parts.length > 0 ? parts.reduce((acc, part) => asNumber(acc) + asNumber(part)) : 0;
|
|
698
975
|
}
|
|
699
976
|
case "execute": {
|
|
700
977
|
const query = renderQuery(node.args, scope, generators);
|
|
701
|
-
return this.#
|
|
978
|
+
return this.#withQuerySpanAndEvent(query, queryable, async () => {
|
|
702
979
|
return await queryable.executeRaw(query);
|
|
703
980
|
});
|
|
704
981
|
}
|
|
705
982
|
case "query": {
|
|
706
983
|
const query = renderQuery(node.args, scope, generators);
|
|
707
|
-
return this.#
|
|
708
|
-
|
|
984
|
+
return this.#withQuerySpanAndEvent(query, queryable, async () => {
|
|
985
|
+
if (node.args.type === "rawSql") {
|
|
986
|
+
return this.#rawSerializer(await queryable.queryRaw(query));
|
|
987
|
+
} else {
|
|
988
|
+
return this.#serializer(await queryable.queryRaw(query));
|
|
989
|
+
}
|
|
709
990
|
});
|
|
710
991
|
}
|
|
711
992
|
case "reverse": {
|
|
@@ -735,6 +1016,9 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
735
1016
|
}
|
|
736
1017
|
case "join": {
|
|
737
1018
|
const parent = await this.interpretNode(node.args.parent, queryable, scope, generators);
|
|
1019
|
+
if (parent === null) {
|
|
1020
|
+
return null;
|
|
1021
|
+
}
|
|
738
1022
|
const children = await Promise.all(
|
|
739
1023
|
node.args.children.map(async (joinExpr) => ({
|
|
740
1024
|
joinExpr,
|
|
@@ -791,34 +1075,50 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
791
1075
|
const toSet = new Set(asList(to));
|
|
792
1076
|
return asList(from).filter((item) => !toSet.has(item));
|
|
793
1077
|
}
|
|
1078
|
+
case "distinctBy": {
|
|
1079
|
+
const value = await this.interpretNode(node.args.expr, queryable, scope, generators);
|
|
1080
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1081
|
+
const result = [];
|
|
1082
|
+
for (const item of asList(value)) {
|
|
1083
|
+
const key = getRecordKey(item, node.args.fields);
|
|
1084
|
+
if (!seen.has(key)) {
|
|
1085
|
+
seen.add(key);
|
|
1086
|
+
result.push(item);
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
return result;
|
|
1090
|
+
}
|
|
1091
|
+
case "paginate": {
|
|
1092
|
+
const value = await this.interpretNode(node.args.expr, queryable, scope, generators);
|
|
1093
|
+
const list = asList(value);
|
|
1094
|
+
const linkingFields = node.args.pagination.linkingFields;
|
|
1095
|
+
if (linkingFields !== null) {
|
|
1096
|
+
const groupedByParent = /* @__PURE__ */ new Map();
|
|
1097
|
+
for (const item of list) {
|
|
1098
|
+
const parentKey = getRecordKey(item, linkingFields);
|
|
1099
|
+
if (!groupedByParent.has(parentKey)) {
|
|
1100
|
+
groupedByParent.set(parentKey, []);
|
|
1101
|
+
}
|
|
1102
|
+
groupedByParent.get(parentKey).push(item);
|
|
1103
|
+
}
|
|
1104
|
+
const groupList = Array.from(groupedByParent.entries());
|
|
1105
|
+
groupList.sort(([aId], [bId]) => aId < bId ? -1 : aId > bId ? 1 : 0);
|
|
1106
|
+
return groupList.flatMap(([, elems]) => paginate(elems, node.args.pagination));
|
|
1107
|
+
}
|
|
1108
|
+
return paginate(list, node.args.pagination);
|
|
1109
|
+
}
|
|
794
1110
|
default:
|
|
795
1111
|
assertNever(node, `Unexpected node type: ${node.type}`);
|
|
796
1112
|
}
|
|
797
1113
|
}
|
|
798
|
-
#
|
|
799
|
-
return
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
}
|
|
807
|
-
},
|
|
808
|
-
async () => {
|
|
809
|
-
const timestamp = /* @__PURE__ */ new Date();
|
|
810
|
-
const startInstant = performance.now();
|
|
811
|
-
const result = await execute();
|
|
812
|
-
const endInstant = performance.now();
|
|
813
|
-
this.#onQuery?.({
|
|
814
|
-
timestamp,
|
|
815
|
-
duration: endInstant - startInstant,
|
|
816
|
-
query: query.sql,
|
|
817
|
-
params: query.args
|
|
818
|
-
});
|
|
819
|
-
return result;
|
|
820
|
-
}
|
|
821
|
-
);
|
|
1114
|
+
#withQuerySpanAndEvent(query, queryable, execute) {
|
|
1115
|
+
return withQuerySpanAndEvent({
|
|
1116
|
+
query,
|
|
1117
|
+
queryable,
|
|
1118
|
+
execute,
|
|
1119
|
+
tracingHelper: this.#tracingHelper,
|
|
1120
|
+
onQuery: this.#onQuery
|
|
1121
|
+
});
|
|
822
1122
|
}
|
|
823
1123
|
};
|
|
824
1124
|
function isEmpty(value) {
|
|
@@ -862,7 +1162,12 @@ function attachChildrenToParent(parentRecord, children) {
|
|
|
862
1162
|
}
|
|
863
1163
|
function filterChildRecords(records, parentRecord, joinExpr) {
|
|
864
1164
|
if (Array.isArray(records)) {
|
|
865
|
-
|
|
1165
|
+
const filtered = records.filter((record) => childRecordMatchesParent(asRecord(record), parentRecord, joinExpr));
|
|
1166
|
+
if (joinExpr.isRelationUnique) {
|
|
1167
|
+
return filtered.length > 0 ? filtered[0] : null;
|
|
1168
|
+
} else {
|
|
1169
|
+
return filtered;
|
|
1170
|
+
}
|
|
866
1171
|
} else if (records === null) {
|
|
867
1172
|
return null;
|
|
868
1173
|
} else {
|
|
@@ -878,6 +1183,18 @@ function childRecordMatchesParent(childRecord, parentRecord, joinExpr) {
|
|
|
878
1183
|
}
|
|
879
1184
|
return true;
|
|
880
1185
|
}
|
|
1186
|
+
function paginate(list, { cursor, skip, take }) {
|
|
1187
|
+
const cursorIndex = cursor !== null ? list.findIndex((item) => doKeysMatch(item, cursor)) : 0;
|
|
1188
|
+
if (cursorIndex === -1) {
|
|
1189
|
+
return [];
|
|
1190
|
+
}
|
|
1191
|
+
const start = cursorIndex + (skip ?? 0);
|
|
1192
|
+
const end = take !== null ? start + take : list.length;
|
|
1193
|
+
return list.slice(start, end);
|
|
1194
|
+
}
|
|
1195
|
+
function getRecordKey(record, fields) {
|
|
1196
|
+
return JSON.stringify(fields.map((field) => record[field]));
|
|
1197
|
+
}
|
|
881
1198
|
|
|
882
1199
|
// src/transactionManager/TransactionManager.ts
|
|
883
1200
|
var import_debug = require("@prisma/debug");
|
|
@@ -892,12 +1209,11 @@ async function randomUUID() {
|
|
|
892
1209
|
}
|
|
893
1210
|
|
|
894
1211
|
// src/transactionManager/TransactionManagerErrors.ts
|
|
895
|
-
var TransactionManagerError = class extends
|
|
1212
|
+
var TransactionManagerError = class extends UserFacingError {
|
|
1213
|
+
name = "TransactionManagerError";
|
|
896
1214
|
constructor(message, meta) {
|
|
897
|
-
super("Transaction API error: " + message);
|
|
898
|
-
this.meta = meta;
|
|
1215
|
+
super("Transaction API error: " + message, "P2028", meta);
|
|
899
1216
|
}
|
|
900
|
-
code = "P2028";
|
|
901
1217
|
};
|
|
902
1218
|
var TransactionNotFoundError = class extends TransactionManagerError {
|
|
903
1219
|
constructor() {
|
|
@@ -908,12 +1224,12 @@ var TransactionNotFoundError = class extends TransactionManagerError {
|
|
|
908
1224
|
};
|
|
909
1225
|
var TransactionClosedError = class extends TransactionManagerError {
|
|
910
1226
|
constructor(operation) {
|
|
911
|
-
super(`Transaction already closed: A ${operation} cannot be executed on a committed transaction
|
|
1227
|
+
super(`Transaction already closed: A ${operation} cannot be executed on a committed transaction.`);
|
|
912
1228
|
}
|
|
913
1229
|
};
|
|
914
1230
|
var TransactionRolledBackError = class extends TransactionManagerError {
|
|
915
1231
|
constructor(operation) {
|
|
916
|
-
super(`Transaction already closed: A ${operation} cannot be executed on a transaction that was rolled back
|
|
1232
|
+
super(`Transaction already closed: A ${operation} cannot be executed on a transaction that was rolled back.`);
|
|
917
1233
|
}
|
|
918
1234
|
};
|
|
919
1235
|
var TransactionStartTimeoutError = class extends TransactionManagerError {
|
|
@@ -945,6 +1261,16 @@ var MAX_CLOSED_TRANSACTIONS = 100;
|
|
|
945
1261
|
var debug = (0, import_debug.Debug)("prisma:client:transactionManager");
|
|
946
1262
|
var COMMIT_QUERY = () => ({ sql: "COMMIT", args: [], argTypes: [] });
|
|
947
1263
|
var ROLLBACK_QUERY = () => ({ sql: "ROLLBACK", args: [], argTypes: [] });
|
|
1264
|
+
var PHANTOM_COMMIT_QUERY = () => ({
|
|
1265
|
+
sql: '-- Implicit "COMMIT" query via underlying driver',
|
|
1266
|
+
args: [],
|
|
1267
|
+
argTypes: []
|
|
1268
|
+
});
|
|
1269
|
+
var PHANTOM_ROLLBACK_QUERY = () => ({
|
|
1270
|
+
sql: '-- Implicit "ROLLBACK" query via underlying driver',
|
|
1271
|
+
args: [],
|
|
1272
|
+
argTypes: []
|
|
1273
|
+
});
|
|
948
1274
|
var TransactionManager = class {
|
|
949
1275
|
// The map of active transactions.
|
|
950
1276
|
transactions = /* @__PURE__ */ new Map();
|
|
@@ -954,14 +1280,17 @@ var TransactionManager = class {
|
|
|
954
1280
|
driverAdapter;
|
|
955
1281
|
transactionOptions;
|
|
956
1282
|
tracingHelper;
|
|
1283
|
+
#onQuery;
|
|
957
1284
|
constructor({
|
|
958
1285
|
driverAdapter,
|
|
959
1286
|
transactionOptions,
|
|
960
|
-
tracingHelper
|
|
1287
|
+
tracingHelper,
|
|
1288
|
+
onQuery
|
|
961
1289
|
}) {
|
|
962
1290
|
this.driverAdapter = driverAdapter;
|
|
963
1291
|
this.transactionOptions = transactionOptions;
|
|
964
1292
|
this.tracingHelper = tracingHelper;
|
|
1293
|
+
this.#onQuery = onQuery;
|
|
965
1294
|
}
|
|
966
1295
|
async startTransaction(options) {
|
|
967
1296
|
return await this.tracingHelper.runInChildSpan("start_transaction", () => this.#startTransactionImpl(options));
|
|
@@ -1065,14 +1394,20 @@ var TransactionManager = class {
|
|
|
1065
1394
|
debug("Closing transaction.", { transactionId: tx.id, status });
|
|
1066
1395
|
tx.status = status;
|
|
1067
1396
|
if (tx.transaction && status === "committed") {
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1397
|
+
if (tx.transaction.options.usePhantomQuery) {
|
|
1398
|
+
await this.#withQuerySpanAndEvent(PHANTOM_COMMIT_QUERY(), tx.transaction, () => tx.transaction.commit());
|
|
1399
|
+
} else {
|
|
1400
|
+
await tx.transaction.commit();
|
|
1401
|
+
const query = COMMIT_QUERY();
|
|
1402
|
+
await this.#withQuerySpanAndEvent(query, tx.transaction, () => tx.transaction.executeRaw(query));
|
|
1071
1403
|
}
|
|
1072
1404
|
} else if (tx.transaction) {
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1405
|
+
if (tx.transaction.options.usePhantomQuery) {
|
|
1406
|
+
await this.#withQuerySpanAndEvent(PHANTOM_ROLLBACK_QUERY(), tx.transaction, () => tx.transaction.rollback());
|
|
1407
|
+
} else {
|
|
1408
|
+
await tx.transaction.rollback();
|
|
1409
|
+
const query = ROLLBACK_QUERY();
|
|
1410
|
+
await this.#withQuerySpanAndEvent(query, tx.transaction, () => tx.transaction.executeRaw(query));
|
|
1076
1411
|
}
|
|
1077
1412
|
}
|
|
1078
1413
|
clearTimeout(tx.timer);
|
|
@@ -1093,15 +1428,29 @@ var TransactionManager = class {
|
|
|
1093
1428
|
maxWait: options.maxWait
|
|
1094
1429
|
};
|
|
1095
1430
|
}
|
|
1431
|
+
#withQuerySpanAndEvent(query, queryable, execute) {
|
|
1432
|
+
return withQuerySpanAndEvent({
|
|
1433
|
+
query,
|
|
1434
|
+
queryable,
|
|
1435
|
+
execute,
|
|
1436
|
+
tracingHelper: this.tracingHelper,
|
|
1437
|
+
onQuery: this.#onQuery
|
|
1438
|
+
});
|
|
1439
|
+
}
|
|
1096
1440
|
};
|
|
1097
1441
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1098
1442
|
0 && (module.exports = {
|
|
1443
|
+
DataMapperError,
|
|
1099
1444
|
QueryInterpreter,
|
|
1100
1445
|
TransactionManager,
|
|
1101
1446
|
TransactionManagerError,
|
|
1102
1447
|
UserFacingError,
|
|
1448
|
+
doKeysMatch,
|
|
1449
|
+
isDeepStrictEqual,
|
|
1450
|
+
isPrismaValueBigInt,
|
|
1103
1451
|
isPrismaValueBytes,
|
|
1104
1452
|
isPrismaValueGenerator,
|
|
1105
1453
|
isPrismaValuePlaceholder,
|
|
1106
|
-
noopTracingHelper
|
|
1454
|
+
noopTracingHelper,
|
|
1455
|
+
safeJsonStringify
|
|
1107
1456
|
});
|