@prisma/client-engine-runtime 6.7.0-dev.3 → 6.7.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 +40 -0
- package/dist/UserFacingError.d.ts +16 -0
- package/dist/index.d.mts +79 -2
- package/dist/index.d.ts +79 -2
- package/dist/index.js +394 -47
- package/dist/index.mjs +391 -46
- package/dist/interpreter/DataMapper.d.ts +3 -0
- package/dist/interpreter/QueryInterpreter.d.ts +3 -1
- package/dist/tracing.d.ts +11 -0
- package/dist/transactionManager/TransactionManager.d.ts +5 -1
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -33,11 +33,277 @@ __export(index_exports, {
|
|
|
33
33
|
QueryInterpreter: () => QueryInterpreter,
|
|
34
34
|
TransactionManager: () => TransactionManager,
|
|
35
35
|
TransactionManagerError: () => TransactionManagerError,
|
|
36
|
+
UserFacingError: () => UserFacingError,
|
|
36
37
|
isPrismaValueGenerator: () => isPrismaValueGenerator,
|
|
37
|
-
isPrismaValuePlaceholder: () => isPrismaValuePlaceholder
|
|
38
|
+
isPrismaValuePlaceholder: () => isPrismaValuePlaceholder,
|
|
39
|
+
noopTracingHelper: () => noopTracingHelper
|
|
38
40
|
});
|
|
39
41
|
module.exports = __toCommonJS(index_exports);
|
|
40
42
|
|
|
43
|
+
// src/interpreter/QueryInterpreter.ts
|
|
44
|
+
var import_api = require("@opentelemetry/api");
|
|
45
|
+
|
|
46
|
+
// src/utils.ts
|
|
47
|
+
function assertNever(_, message) {
|
|
48
|
+
throw new Error(message);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/tracing.ts
|
|
52
|
+
var noopTracingHelper = {
|
|
53
|
+
runInChildSpan(_, callback) {
|
|
54
|
+
return callback();
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
function providerToOtelSystem(provider) {
|
|
58
|
+
switch (provider) {
|
|
59
|
+
case "postgres":
|
|
60
|
+
return "postgresql";
|
|
61
|
+
case "mysql":
|
|
62
|
+
return "mysql";
|
|
63
|
+
case "sqlite":
|
|
64
|
+
return "sqlite";
|
|
65
|
+
default:
|
|
66
|
+
assertNever(provider, `Unknown provider: ${provider}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/UserFacingError.ts
|
|
71
|
+
var import_driver_adapter_utils = require("@prisma/driver-adapter-utils");
|
|
72
|
+
var UserFacingError = class extends Error {
|
|
73
|
+
name = "UserFacingError";
|
|
74
|
+
code;
|
|
75
|
+
meta;
|
|
76
|
+
constructor(message, code, meta) {
|
|
77
|
+
super(message);
|
|
78
|
+
this.code = code;
|
|
79
|
+
this.meta = meta;
|
|
80
|
+
}
|
|
81
|
+
toQueryResponseErrorObject() {
|
|
82
|
+
return {
|
|
83
|
+
error: this.message,
|
|
84
|
+
user_facing_error: {
|
|
85
|
+
is_panic: false,
|
|
86
|
+
message: this.message,
|
|
87
|
+
meta: this.meta,
|
|
88
|
+
error_code: this.code
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
function rethrowAsUserFacing(error) {
|
|
94
|
+
if (!(0, import_driver_adapter_utils.isDriverAdapterError)(error)) {
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
const code = getErrorCode(error);
|
|
98
|
+
const message = renderErrorMessage(error);
|
|
99
|
+
if (!code || !message) {
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
throw new UserFacingError(message, code, error);
|
|
103
|
+
}
|
|
104
|
+
function getErrorCode(err) {
|
|
105
|
+
switch (err.cause.kind) {
|
|
106
|
+
case "AuthenticationFailed":
|
|
107
|
+
return "P1000";
|
|
108
|
+
case "DatabaseDoesNotExist":
|
|
109
|
+
return "P1003";
|
|
110
|
+
case "SocketTimeout":
|
|
111
|
+
return "P1008";
|
|
112
|
+
case "DatabaseAlreadyExists":
|
|
113
|
+
return "P1009";
|
|
114
|
+
case "DatabaseAccessDenied":
|
|
115
|
+
return "P1010";
|
|
116
|
+
case "LengthMismatch":
|
|
117
|
+
return "P2000";
|
|
118
|
+
case "UniqueConstraintViolation":
|
|
119
|
+
return "P2002";
|
|
120
|
+
case "ForeignKeyConstraintViolation":
|
|
121
|
+
return "P2003";
|
|
122
|
+
case "UnsupportedNativeDataType":
|
|
123
|
+
return "P2010";
|
|
124
|
+
case "NullConstraintViolation":
|
|
125
|
+
return "P2011";
|
|
126
|
+
case "TableDoesNotExist":
|
|
127
|
+
return "P2021";
|
|
128
|
+
case "ColumnNotFound":
|
|
129
|
+
return "P2022";
|
|
130
|
+
case "InvalidIsolationLevel":
|
|
131
|
+
return "P2023";
|
|
132
|
+
case "TransactionWriteConflict":
|
|
133
|
+
return "P2034";
|
|
134
|
+
case "GenericJs":
|
|
135
|
+
return "P2036";
|
|
136
|
+
case "TooManyConnections":
|
|
137
|
+
return "P2037";
|
|
138
|
+
case "postgres":
|
|
139
|
+
case "sqlite":
|
|
140
|
+
case "mysql":
|
|
141
|
+
return;
|
|
142
|
+
default:
|
|
143
|
+
assertNever(err.cause, `Unknown error: ${err.cause}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function renderErrorMessage(err) {
|
|
147
|
+
switch (err.cause.kind) {
|
|
148
|
+
case "AuthenticationFailed": {
|
|
149
|
+
const user = err.cause.user ?? "(not available)";
|
|
150
|
+
return `Authentication failed against the database server, the provided database credentials for \`${user}\` are not valid`;
|
|
151
|
+
}
|
|
152
|
+
case "DatabaseDoesNotExist": {
|
|
153
|
+
const db = err.cause.db ?? "(not available)";
|
|
154
|
+
return `Database \`${db}\` does not exist on the database server`;
|
|
155
|
+
}
|
|
156
|
+
case "SocketTimeout":
|
|
157
|
+
return `Operation has timed out`;
|
|
158
|
+
case "DatabaseAlreadyExists": {
|
|
159
|
+
const db = err.cause.db ?? "(not available)";
|
|
160
|
+
return `Database \`${db}\` already exists on the database server`;
|
|
161
|
+
}
|
|
162
|
+
case "DatabaseAccessDenied": {
|
|
163
|
+
const db = err.cause.db ?? "(not available)";
|
|
164
|
+
return `User was denied access on the database \`${db}\``;
|
|
165
|
+
}
|
|
166
|
+
case "LengthMismatch": {
|
|
167
|
+
const column = err.cause.column ?? "(not available)";
|
|
168
|
+
return `The provided value for the column is too long for the column's type. Column: ${column}`;
|
|
169
|
+
}
|
|
170
|
+
case "UniqueConstraintViolation":
|
|
171
|
+
return `Unique constraint failed on the ${renderConstraint({ fields: err.cause.fields })}`;
|
|
172
|
+
case "ForeignKeyConstraintViolation":
|
|
173
|
+
return `Foreign key constraint violated on the ${renderConstraint(err.cause.constraint)}`;
|
|
174
|
+
case "UnsupportedNativeDataType":
|
|
175
|
+
return `Failed to deserialize column of type '${err.cause.type}'. If you're using $queryRaw and this column is explicitly marked as \`Unsupported\` in your Prisma schema, try casting this column to any supported Prisma type such as \`String\`.`;
|
|
176
|
+
case "NullConstraintViolation":
|
|
177
|
+
return `Null constraint violation on the ${renderConstraint({ fields: err.cause.fields })}`;
|
|
178
|
+
case "TableDoesNotExist": {
|
|
179
|
+
const table = err.cause.table ?? "(not available)";
|
|
180
|
+
return `The table \`${table}\` does not exist in the current database.`;
|
|
181
|
+
}
|
|
182
|
+
case "ColumnNotFound": {
|
|
183
|
+
const column = err.cause.column ?? "(not available)";
|
|
184
|
+
return `The column \`${column}\` does not exist in the current database.`;
|
|
185
|
+
}
|
|
186
|
+
case "InvalidIsolationLevel":
|
|
187
|
+
return `Invalid isolation level \`${err.cause.level}\``;
|
|
188
|
+
case "TransactionWriteConflict":
|
|
189
|
+
return `Transaction failed due to a write conflict or a deadlock. Please retry your transaction`;
|
|
190
|
+
case "GenericJs":
|
|
191
|
+
return `Error in external connector (id ${err.cause.id})`;
|
|
192
|
+
case "TooManyConnections":
|
|
193
|
+
return `Too many database connections opened: ${err.cause.cause}`;
|
|
194
|
+
case "sqlite":
|
|
195
|
+
case "postgres":
|
|
196
|
+
case "mysql":
|
|
197
|
+
return;
|
|
198
|
+
default:
|
|
199
|
+
assertNever(err.cause, `Unknown error: ${err.cause}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function renderConstraint(constraint) {
|
|
203
|
+
if (constraint && "fields" in constraint) {
|
|
204
|
+
return `fields: (${constraint.fields.map((field) => `\`${field}\``).join(", ")})`;
|
|
205
|
+
} else if (constraint && "index" in constraint) {
|
|
206
|
+
return `constraint: \`${constraint.index}\``;
|
|
207
|
+
} else if (constraint && "foreignKey" in constraint) {
|
|
208
|
+
return `foreign key`;
|
|
209
|
+
}
|
|
210
|
+
return "(not available)";
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// src/interpreter/DataMapper.ts
|
|
214
|
+
function applyDataMap(data, structure) {
|
|
215
|
+
switch (structure.type) {
|
|
216
|
+
case "Object":
|
|
217
|
+
return mapArrayOrObject(data, structure.fields);
|
|
218
|
+
case "Value":
|
|
219
|
+
return mapValue(data, structure.resultType);
|
|
220
|
+
default:
|
|
221
|
+
assertNever(structure, `Invalid data mapping type: '${structure.type}'`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function mapArrayOrObject(data, fields) {
|
|
225
|
+
if (data === null) return null;
|
|
226
|
+
if (Array.isArray(data)) {
|
|
227
|
+
const rows = data;
|
|
228
|
+
return rows.map((row) => mapObject(row, fields));
|
|
229
|
+
}
|
|
230
|
+
if (typeof data === "object") {
|
|
231
|
+
const row = data;
|
|
232
|
+
return mapObject(row, fields);
|
|
233
|
+
}
|
|
234
|
+
throw new Error(`DataMapper: Expected an array or an object, got: ${typeof data}`);
|
|
235
|
+
}
|
|
236
|
+
function mapObject(data, fields) {
|
|
237
|
+
if (typeof data !== "object") {
|
|
238
|
+
throw new Error(`DataMapper: Expected an object, but got '${typeof data}'`);
|
|
239
|
+
}
|
|
240
|
+
const result = {};
|
|
241
|
+
for (const [name, node] of Object.entries(fields)) {
|
|
242
|
+
switch (node.type) {
|
|
243
|
+
case "Object":
|
|
244
|
+
if (Object.hasOwn(data, name)) {
|
|
245
|
+
result[name] = mapArrayOrObject(data[name], node.fields);
|
|
246
|
+
} else {
|
|
247
|
+
throw new Error(
|
|
248
|
+
`DataMapper: Missing data field (Object): '${name}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
break;
|
|
252
|
+
case "Value":
|
|
253
|
+
{
|
|
254
|
+
const dbName = node.dbName;
|
|
255
|
+
if (Object.hasOwn(data, dbName)) {
|
|
256
|
+
result[name] = mapValue(data[dbName], node.resultType);
|
|
257
|
+
} else {
|
|
258
|
+
throw new Error(
|
|
259
|
+
`DataMapper: Missing data field (Value): '${dbName}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
break;
|
|
264
|
+
default:
|
|
265
|
+
assertNever(node, `DataMapper: Invalid data mapping node type: '${node.type}'`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return result;
|
|
269
|
+
}
|
|
270
|
+
function mapValue(value, resultType) {
|
|
271
|
+
if (value === null) return null;
|
|
272
|
+
switch (resultType.type) {
|
|
273
|
+
case "Any":
|
|
274
|
+
return value;
|
|
275
|
+
case "String":
|
|
276
|
+
return typeof value === "string" ? value : `${value}`;
|
|
277
|
+
case "Int":
|
|
278
|
+
return typeof value === "number" ? value : parseInt(`${value}`, 10);
|
|
279
|
+
case "BigInt":
|
|
280
|
+
return typeof value === "bigint" ? value : BigInt(`${value}`);
|
|
281
|
+
case "Float":
|
|
282
|
+
return typeof value === "number" ? value : parseFloat(`${value}`);
|
|
283
|
+
case "Boolean":
|
|
284
|
+
return typeof value === "boolean" ? value : value !== "0";
|
|
285
|
+
case "Decimal":
|
|
286
|
+
return typeof value === "number" ? value : parseFloat(`${value}`);
|
|
287
|
+
case "Date":
|
|
288
|
+
return value instanceof Date ? value : /* @__PURE__ */ new Date(`${value}`);
|
|
289
|
+
case "Array": {
|
|
290
|
+
const values = value;
|
|
291
|
+
return values.map((v) => {
|
|
292
|
+
mapValue(v, resultType.inner);
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
case "Object":
|
|
296
|
+
return typeof value === "object" ? value : { value };
|
|
297
|
+
case "Bytes":
|
|
298
|
+
if (typeof value !== "string") {
|
|
299
|
+
throw new Error(`DataMapper: Bytes data is not a string, got: ${typeof value}`);
|
|
300
|
+
}
|
|
301
|
+
return value;
|
|
302
|
+
default:
|
|
303
|
+
assertNever(resultType, `DataMapper: Unknown result type: ${resultType.type}`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
41
307
|
// src/interpreter/generators.ts
|
|
42
308
|
var import_cuid = __toESM(require("@bugsnag/cuid"));
|
|
43
309
|
var import_cuid2 = require("@paralleldrive/cuid2");
|
|
@@ -52,6 +318,7 @@ var GeneratorRegistry = class {
|
|
|
52
318
|
this.register("cuid", new CuidGenerator());
|
|
53
319
|
this.register("ulid", new UlidGenerator());
|
|
54
320
|
this.register("nanoid", new NanoIdGenerator());
|
|
321
|
+
this.register("product", new ProductGenerator());
|
|
55
322
|
}
|
|
56
323
|
/**
|
|
57
324
|
* Returns a snapshot of the generator registry. It's 'frozen' in time at the moment of this
|
|
@@ -114,6 +381,22 @@ var NanoIdGenerator = class {
|
|
|
114
381
|
}
|
|
115
382
|
}
|
|
116
383
|
};
|
|
384
|
+
var ProductGenerator = class {
|
|
385
|
+
generate(lhs, rhs) {
|
|
386
|
+
if (lhs === void 0 || rhs === void 0) {
|
|
387
|
+
throw new Error("Invalid Product generator arguments");
|
|
388
|
+
}
|
|
389
|
+
if (Array.isArray(lhs) && Array.isArray(rhs)) {
|
|
390
|
+
return lhs.flatMap((l) => rhs.map((r) => [l, r]));
|
|
391
|
+
} else if (Array.isArray(lhs)) {
|
|
392
|
+
return lhs.map((l) => [l, rhs]);
|
|
393
|
+
} else if (Array.isArray(rhs)) {
|
|
394
|
+
return rhs.map((r) => [lhs, r]);
|
|
395
|
+
} else {
|
|
396
|
+
return [[lhs, rhs]];
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
};
|
|
117
400
|
|
|
118
401
|
// src/QueryPlan.ts
|
|
119
402
|
function isPrismaValuePlaceholder(value) {
|
|
@@ -123,46 +406,49 @@ function isPrismaValueGenerator(value) {
|
|
|
123
406
|
return typeof value === "object" && value !== null && value["prisma__type"] === "generatorCall";
|
|
124
407
|
}
|
|
125
408
|
|
|
126
|
-
// src/utils.ts
|
|
127
|
-
function assertNever(_, message) {
|
|
128
|
-
throw new Error(message);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
409
|
// src/interpreter/renderQuery.ts
|
|
132
410
|
function renderQuery(dbQuery, scope, generators) {
|
|
133
411
|
const queryType = dbQuery.type;
|
|
134
412
|
switch (queryType) {
|
|
135
413
|
case "rawSql":
|
|
136
|
-
return renderRawSql(dbQuery.sql,
|
|
414
|
+
return renderRawSql(dbQuery.sql, evaluateParams(dbQuery.params, scope, generators));
|
|
137
415
|
case "templateSql":
|
|
138
416
|
return renderTemplateSql(
|
|
139
417
|
dbQuery.fragments,
|
|
140
418
|
dbQuery.placeholderFormat,
|
|
141
|
-
|
|
419
|
+
evaluateParams(dbQuery.params, scope, generators)
|
|
142
420
|
);
|
|
143
421
|
default:
|
|
144
422
|
assertNever(queryType, `Invalid query type`);
|
|
145
423
|
}
|
|
146
424
|
}
|
|
147
|
-
function
|
|
148
|
-
return params.map((param) =>
|
|
149
|
-
|
|
150
|
-
|
|
425
|
+
function evaluateParams(params, scope, generators) {
|
|
426
|
+
return params.map((param) => evaluateParam(param, scope, generators));
|
|
427
|
+
}
|
|
428
|
+
function evaluateParam(param, scope, generators) {
|
|
429
|
+
let value = param;
|
|
430
|
+
while (doesRequireEvaluation(value)) {
|
|
431
|
+
if (isPrismaValuePlaceholder(value)) {
|
|
432
|
+
const found = scope[value.prisma__value.name];
|
|
433
|
+
if (found === void 0) {
|
|
434
|
+
throw new Error(`Missing value for query variable ${value.prisma__value.name}`);
|
|
435
|
+
}
|
|
436
|
+
value = found;
|
|
437
|
+
} else if (isPrismaValueGenerator(value)) {
|
|
438
|
+
const { name, args } = value.prisma__value;
|
|
151
439
|
const generator = generators[name];
|
|
152
440
|
if (!generator) {
|
|
153
441
|
throw new Error(`Encountered an unknown generator '${name}'`);
|
|
154
442
|
}
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return param;
|
|
159
|
-
}
|
|
160
|
-
const value = scope[param.prisma__value.name];
|
|
161
|
-
if (value === void 0) {
|
|
162
|
-
throw new Error(`Missing value for query variable ${param.prisma__value.name}`);
|
|
443
|
+
value = generator.generate(...args.map((arg) => evaluateParam(arg, scope, generators)));
|
|
444
|
+
} else {
|
|
445
|
+
assertNever(value, `Unexpected unevaluated value type: ${value}`);
|
|
163
446
|
}
|
|
164
|
-
|
|
165
|
-
|
|
447
|
+
}
|
|
448
|
+
if (Array.isArray(value)) {
|
|
449
|
+
value = value.map((el) => evaluateParam(el, scope, generators));
|
|
450
|
+
}
|
|
451
|
+
return value;
|
|
166
452
|
}
|
|
167
453
|
function renderTemplateSql(fragments, placeholderFormat, params) {
|
|
168
454
|
let paramIndex = 0;
|
|
@@ -191,6 +477,29 @@ function renderTemplateSql(fragments, placeholderFormat, params) {
|
|
|
191
477
|
}).join(",");
|
|
192
478
|
return `(${placeholders})`;
|
|
193
479
|
}
|
|
480
|
+
case "parameterTupleList": {
|
|
481
|
+
if (paramIndex >= params.length) {
|
|
482
|
+
throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
|
|
483
|
+
}
|
|
484
|
+
const paramValue = params[paramIndex++];
|
|
485
|
+
if (!Array.isArray(paramValue)) {
|
|
486
|
+
throw new Error(`Malformed query template. Tuple list expected.`);
|
|
487
|
+
}
|
|
488
|
+
if (paramValue.length === 0) {
|
|
489
|
+
throw new Error(`Malformed query template. Tuple list cannot be empty.`);
|
|
490
|
+
}
|
|
491
|
+
const tupleList = paramValue.map((tuple) => {
|
|
492
|
+
if (!Array.isArray(tuple)) {
|
|
493
|
+
throw new Error(`Malformed query template. Tuple expected.`);
|
|
494
|
+
}
|
|
495
|
+
const elements = tuple.map((value) => {
|
|
496
|
+
flattenedParams.push(value);
|
|
497
|
+
return formatPlaceholder(placeholderFormat, placeholderNumber++);
|
|
498
|
+
}).join(",");
|
|
499
|
+
return `(${elements})`;
|
|
500
|
+
}).join(",");
|
|
501
|
+
return tupleList;
|
|
502
|
+
}
|
|
194
503
|
default:
|
|
195
504
|
assertNever(fragmentType, "Invalid fragment type");
|
|
196
505
|
}
|
|
@@ -249,6 +558,9 @@ function placeholderTypeToArgType(type) {
|
|
|
249
558
|
}
|
|
250
559
|
return mappedType;
|
|
251
560
|
}
|
|
561
|
+
function doesRequireEvaluation(param) {
|
|
562
|
+
return isPrismaValuePlaceholder(param) || isPrismaValueGenerator(param);
|
|
563
|
+
}
|
|
252
564
|
|
|
253
565
|
// src/interpreter/serialize.ts
|
|
254
566
|
function serialize(resultSet) {
|
|
@@ -278,13 +590,17 @@ var QueryInterpreter = class {
|
|
|
278
590
|
#placeholderValues;
|
|
279
591
|
#onQuery;
|
|
280
592
|
#generators = new GeneratorRegistry();
|
|
281
|
-
|
|
593
|
+
#tracingHelper;
|
|
594
|
+
constructor({ transactionManager, placeholderValues, onQuery, tracingHelper }) {
|
|
282
595
|
this.#transactionManager = transactionManager;
|
|
283
596
|
this.#placeholderValues = placeholderValues;
|
|
284
597
|
this.#onQuery = onQuery;
|
|
598
|
+
this.#tracingHelper = tracingHelper;
|
|
285
599
|
}
|
|
286
600
|
async run(queryPlan, queryable) {
|
|
287
|
-
return this.interpretNode(queryPlan, queryable, this.#placeholderValues, this.#generators.snapshot())
|
|
601
|
+
return this.interpretNode(queryPlan, queryable, this.#placeholderValues, this.#generators.snapshot()).catch(
|
|
602
|
+
(e) => rethrowAsUserFacing(e)
|
|
603
|
+
);
|
|
288
604
|
}
|
|
289
605
|
async interpretNode(node, queryable, scope, generators) {
|
|
290
606
|
switch (node.type) {
|
|
@@ -323,13 +639,13 @@ var QueryInterpreter = class {
|
|
|
323
639
|
}
|
|
324
640
|
case "execute": {
|
|
325
641
|
const query = renderQuery(node.args, scope, generators);
|
|
326
|
-
return this.#withQueryEvent(query, async () => {
|
|
642
|
+
return this.#withQueryEvent(query, queryable, async () => {
|
|
327
643
|
return await queryable.executeRaw(query);
|
|
328
644
|
});
|
|
329
645
|
}
|
|
330
646
|
case "query": {
|
|
331
647
|
const query = renderQuery(node.args, scope, generators);
|
|
332
|
-
return this.#withQueryEvent(query, async () => {
|
|
648
|
+
return this.#withQueryEvent(query, queryable, async () => {
|
|
333
649
|
return serialize(await queryable.queryRaw(query));
|
|
334
650
|
});
|
|
335
651
|
}
|
|
@@ -390,24 +706,38 @@ var QueryInterpreter = class {
|
|
|
390
706
|
throw e;
|
|
391
707
|
}
|
|
392
708
|
}
|
|
393
|
-
|
|
394
|
-
node;
|
|
395
|
-
|
|
709
|
+
case "dataMap": {
|
|
710
|
+
const data = await this.interpretNode(node.args.expr, queryable, scope, generators);
|
|
711
|
+
return applyDataMap(data, node.args.structure);
|
|
396
712
|
}
|
|
713
|
+
default:
|
|
714
|
+
assertNever(node, `Unexpected node type: ${node.type}`);
|
|
397
715
|
}
|
|
398
716
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
717
|
+
#withQueryEvent(query, queryable, execute) {
|
|
718
|
+
return this.#tracingHelper.runInChildSpan(
|
|
719
|
+
{
|
|
720
|
+
name: "db_query",
|
|
721
|
+
kind: import_api.SpanKind.CLIENT,
|
|
722
|
+
attributes: {
|
|
723
|
+
"db.query.text": query.sql,
|
|
724
|
+
"db.system.name": providerToOtelSystem(queryable.provider)
|
|
725
|
+
}
|
|
726
|
+
},
|
|
727
|
+
async () => {
|
|
728
|
+
const timestamp = /* @__PURE__ */ new Date();
|
|
729
|
+
const startInstant = performance.now();
|
|
730
|
+
const result = await execute();
|
|
731
|
+
const endInstant = performance.now();
|
|
732
|
+
this.#onQuery?.({
|
|
733
|
+
timestamp,
|
|
734
|
+
duration: endInstant - startInstant,
|
|
735
|
+
query: query.sql,
|
|
736
|
+
params: query.args
|
|
737
|
+
});
|
|
738
|
+
return result;
|
|
739
|
+
}
|
|
740
|
+
);
|
|
411
741
|
}
|
|
412
742
|
};
|
|
413
743
|
function isEmpty(value) {
|
|
@@ -452,6 +782,8 @@ function attachChildrenToParent(parentRecord, children) {
|
|
|
452
782
|
function filterChildRecords(records, parentRecord, joinExpr) {
|
|
453
783
|
if (Array.isArray(records)) {
|
|
454
784
|
return records.filter((record) => childRecordMatchesParent(asRecord(record), parentRecord, joinExpr));
|
|
785
|
+
} else if (records === null) {
|
|
786
|
+
return null;
|
|
455
787
|
} else {
|
|
456
788
|
const record = asRecord(records);
|
|
457
789
|
return childRecordMatchesParent(record, parentRecord, joinExpr) ? record : null;
|
|
@@ -540,11 +872,20 @@ var TransactionManager = class {
|
|
|
540
872
|
closedTransactions = [];
|
|
541
873
|
driverAdapter;
|
|
542
874
|
transactionOptions;
|
|
543
|
-
|
|
875
|
+
tracingHelper;
|
|
876
|
+
constructor({
|
|
877
|
+
driverAdapter,
|
|
878
|
+
transactionOptions,
|
|
879
|
+
tracingHelper
|
|
880
|
+
}) {
|
|
544
881
|
this.driverAdapter = driverAdapter;
|
|
545
882
|
this.transactionOptions = transactionOptions;
|
|
883
|
+
this.tracingHelper = tracingHelper;
|
|
546
884
|
}
|
|
547
885
|
async startTransaction(options) {
|
|
886
|
+
return await this.tracingHelper.runInChildSpan("start_transaction", () => this.#startTransactionImpl(options));
|
|
887
|
+
}
|
|
888
|
+
async #startTransactionImpl(options) {
|
|
548
889
|
const validatedOptions = options !== void 0 ? this.validateOptions(options) : this.transactionOptions;
|
|
549
890
|
const transaction = {
|
|
550
891
|
id: await randomUUID(),
|
|
@@ -578,12 +919,16 @@ var TransactionManager = class {
|
|
|
578
919
|
}
|
|
579
920
|
}
|
|
580
921
|
async commitTransaction(transactionId) {
|
|
581
|
-
|
|
582
|
-
|
|
922
|
+
return await this.tracingHelper.runInChildSpan("commit_transaction", async () => {
|
|
923
|
+
const txw = this.getActiveTransaction(transactionId, "commit");
|
|
924
|
+
await this.closeTransaction(txw, "committed");
|
|
925
|
+
});
|
|
583
926
|
}
|
|
584
927
|
async rollbackTransaction(transactionId) {
|
|
585
|
-
|
|
586
|
-
|
|
928
|
+
return await this.tracingHelper.runInChildSpan("rollback_transaction", async () => {
|
|
929
|
+
const txw = this.getActiveTransaction(transactionId, "rollback");
|
|
930
|
+
await this.closeTransaction(txw, "rolled_back");
|
|
931
|
+
});
|
|
587
932
|
}
|
|
588
933
|
getTransaction(txInfo, operation) {
|
|
589
934
|
const tx = this.getActiveTransaction(txInfo.id, operation);
|
|
@@ -673,6 +1018,8 @@ var TransactionManager = class {
|
|
|
673
1018
|
QueryInterpreter,
|
|
674
1019
|
TransactionManager,
|
|
675
1020
|
TransactionManagerError,
|
|
1021
|
+
UserFacingError,
|
|
676
1022
|
isPrismaValueGenerator,
|
|
677
|
-
isPrismaValuePlaceholder
|
|
1023
|
+
isPrismaValuePlaceholder,
|
|
1024
|
+
noopTracingHelper
|
|
678
1025
|
});
|