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