@prisma/client-engine-runtime 6.14.0-dev.4 → 6.14.0-dev.41
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/batch.d.ts +19 -0
- package/dist/index.d.mts +59 -14
- package/dist/index.d.ts +59 -14
- package/dist/index.js +784 -394
- package/dist/index.mjs +781 -394
- package/dist/interpreter/{DataMapper.d.ts → data-mapper.d.ts} +1 -1
- package/dist/interpreter/in-memory-processing.d.ts +3 -0
- package/dist/interpreter/{QueryInterpreter.d.ts → query-interpreter.d.ts} +6 -4
- package/dist/interpreter/{renderQuery.d.ts → render-query.d.ts} +2 -2
- package/dist/interpreter/validation.d.ts +1 -1
- package/dist/json-protocol.d.ts +5 -0
- package/dist/{QueryPlan.d.ts → query-plan.d.ts} +16 -12
- package/dist/raw-json-protocol.d.ts +6 -0
- package/dist/{transactionManager/TransactionManagerErrors.d.ts → transaction-manager/transaction-manager-error.d.ts} +1 -1
- package/dist/{transactionManager/TransactionManager.d.ts → transaction-manager/transaction-manager.d.ts} +1 -1
- package/dist/transaction-manager/transaction-manager.test.d.ts +1 -0
- package/dist/{UserFacingError.d.ts → user-facing-error.d.ts} +1 -0
- package/package.json +3 -3
- /package/dist/interpreter/{renderQuery.test.d.ts → render-query.test.d.ts} +0 -0
- /package/dist/interpreter/{serializeSql.d.ts → serialize-sql.d.ts} +0 -0
- /package/dist/interpreter/{serializeSql.test.d.ts → serialize-sql.test.d.ts} +0 -0
- /package/dist/{transactionManager/TransactionManager.test.d.ts → json-protocol.test.d.ts} +0 -0
- /package/dist/{transactionManager/Transaction.d.ts → transaction-manager/transaction.d.ts} +0 -0
package/dist/index.js
CHANGED
|
@@ -35,6 +35,8 @@ __export(index_exports, {
|
|
|
35
35
|
TransactionManager: () => TransactionManager,
|
|
36
36
|
TransactionManagerError: () => TransactionManagerError,
|
|
37
37
|
UserFacingError: () => UserFacingError,
|
|
38
|
+
convertCompactedRows: () => convertCompactedRows,
|
|
39
|
+
deserializeJsonResponse: () => deserializeJsonResponse,
|
|
38
40
|
doKeysMatch: () => doKeysMatch,
|
|
39
41
|
isDeepStrictEqual: () => isDeepStrictEqual,
|
|
40
42
|
isPrismaValueBigInt: () => isPrismaValueBigInt,
|
|
@@ -43,12 +45,13 @@ __export(index_exports, {
|
|
|
43
45
|
isPrismaValuePlaceholder: () => isPrismaValuePlaceholder,
|
|
44
46
|
noopTracingHelper: () => noopTracingHelper,
|
|
45
47
|
normalizeJsonProtocolValues: () => normalizeJsonProtocolValues,
|
|
48
|
+
normalizeRawJsonProtocolResponse: () => normalizeRawJsonProtocolResponse,
|
|
46
49
|
safeJsonStringify: () => safeJsonStringify
|
|
47
50
|
});
|
|
48
51
|
module.exports = __toCommonJS(index_exports);
|
|
49
52
|
|
|
50
|
-
// src/
|
|
51
|
-
var import_decimal2 =
|
|
53
|
+
// src/json-protocol.ts
|
|
54
|
+
var import_decimal2 = require("decimal.js");
|
|
52
55
|
|
|
53
56
|
// src/utils.ts
|
|
54
57
|
var import_decimal = __toESM(require("decimal.js"));
|
|
@@ -142,7 +145,303 @@ function safeJsonStringify(obj) {
|
|
|
142
145
|
});
|
|
143
146
|
}
|
|
144
147
|
|
|
145
|
-
// src/
|
|
148
|
+
// src/json-protocol.ts
|
|
149
|
+
function normalizeJsonProtocolValues(result) {
|
|
150
|
+
if (result === null) {
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
if (Array.isArray(result)) {
|
|
154
|
+
return result.map(normalizeJsonProtocolValues);
|
|
155
|
+
}
|
|
156
|
+
if (typeof result === "object") {
|
|
157
|
+
if (isTaggedValue(result)) {
|
|
158
|
+
return normalizeTaggedValue(result);
|
|
159
|
+
}
|
|
160
|
+
if (result.constructor !== null && result.constructor.name !== "Object") {
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
return mapObjectValues(result, normalizeJsonProtocolValues);
|
|
164
|
+
}
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
function isTaggedValue(value) {
|
|
168
|
+
return value !== null && typeof value == "object" && typeof value["$type"] === "string";
|
|
169
|
+
}
|
|
170
|
+
function normalizeTaggedValue({ $type, value }) {
|
|
171
|
+
switch ($type) {
|
|
172
|
+
case "BigInt":
|
|
173
|
+
return { $type, value: String(value) };
|
|
174
|
+
case "Bytes":
|
|
175
|
+
return { $type, value };
|
|
176
|
+
case "DateTime":
|
|
177
|
+
return { $type, value: new Date(value).toISOString() };
|
|
178
|
+
case "Decimal":
|
|
179
|
+
return { $type, value: String(new import_decimal2.Decimal(value)) };
|
|
180
|
+
case "Json":
|
|
181
|
+
return { $type, value: JSON.stringify(JSON.parse(value)) };
|
|
182
|
+
default:
|
|
183
|
+
assertNever(value, "Unknown tagged value");
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function mapObjectValues(object, mapper) {
|
|
187
|
+
const result = {};
|
|
188
|
+
for (const key of Object.keys(object)) {
|
|
189
|
+
result[key] = mapper(object[key], key);
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
function deserializeJsonResponse(result) {
|
|
194
|
+
if (result === null) {
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
if (Array.isArray(result)) {
|
|
198
|
+
return result.map(deserializeJsonResponse);
|
|
199
|
+
}
|
|
200
|
+
if (typeof result === "object") {
|
|
201
|
+
if (isTaggedValue(result)) {
|
|
202
|
+
return deserializeTaggedValue(result);
|
|
203
|
+
}
|
|
204
|
+
if (result.constructor !== null && result.constructor.name !== "Object") {
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
207
|
+
return mapObjectValues(result, deserializeJsonResponse);
|
|
208
|
+
}
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
function deserializeTaggedValue({ $type, value }) {
|
|
212
|
+
switch ($type) {
|
|
213
|
+
case "BigInt":
|
|
214
|
+
return BigInt(value);
|
|
215
|
+
case "Bytes": {
|
|
216
|
+
const { buffer, byteOffset, byteLength } = Buffer.from(value, "base64");
|
|
217
|
+
return new Uint8Array(buffer, byteOffset, byteLength);
|
|
218
|
+
}
|
|
219
|
+
case "DateTime":
|
|
220
|
+
return new Date(value);
|
|
221
|
+
case "Decimal":
|
|
222
|
+
return new import_decimal2.Decimal(value);
|
|
223
|
+
case "Json":
|
|
224
|
+
return JSON.parse(value);
|
|
225
|
+
default:
|
|
226
|
+
assertNever(value, "Unknown tagged value");
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// src/user-facing-error.ts
|
|
231
|
+
var import_driver_adapter_utils = require("@prisma/driver-adapter-utils");
|
|
232
|
+
var UserFacingError = class extends Error {
|
|
233
|
+
name = "UserFacingError";
|
|
234
|
+
code;
|
|
235
|
+
meta;
|
|
236
|
+
constructor(message, code, meta) {
|
|
237
|
+
super(message);
|
|
238
|
+
this.code = code;
|
|
239
|
+
this.meta = meta ?? {};
|
|
240
|
+
}
|
|
241
|
+
toQueryResponseErrorObject() {
|
|
242
|
+
return {
|
|
243
|
+
error: this.message,
|
|
244
|
+
user_facing_error: {
|
|
245
|
+
is_panic: false,
|
|
246
|
+
message: this.message,
|
|
247
|
+
meta: this.meta,
|
|
248
|
+
error_code: this.code
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
function rethrowAsUserFacing(error) {
|
|
254
|
+
if (!(0, import_driver_adapter_utils.isDriverAdapterError)(error)) {
|
|
255
|
+
throw error;
|
|
256
|
+
}
|
|
257
|
+
const code = getErrorCode(error);
|
|
258
|
+
const message = renderErrorMessage(error);
|
|
259
|
+
if (!code || !message) {
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
throw new UserFacingError(message, code, { driverAdapterError: error });
|
|
263
|
+
}
|
|
264
|
+
function rethrowAsUserFacingRawError(error) {
|
|
265
|
+
if (!(0, import_driver_adapter_utils.isDriverAdapterError)(error)) {
|
|
266
|
+
throw error;
|
|
267
|
+
}
|
|
268
|
+
throw new UserFacingError(
|
|
269
|
+
`Raw query failed. Code: \`${error.cause.originalCode ?? "N/A"}\`. Message: \`${error.cause.originalMessage ?? renderErrorMessage(error)}\``,
|
|
270
|
+
"P2010",
|
|
271
|
+
{ driverAdapterError: error }
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
function getErrorCode(err) {
|
|
275
|
+
switch (err.cause.kind) {
|
|
276
|
+
case "AuthenticationFailed":
|
|
277
|
+
return "P1000";
|
|
278
|
+
case "DatabaseNotReachable":
|
|
279
|
+
return "P1001";
|
|
280
|
+
case "DatabaseDoesNotExist":
|
|
281
|
+
return "P1003";
|
|
282
|
+
case "SocketTimeout":
|
|
283
|
+
return "P1008";
|
|
284
|
+
case "DatabaseAlreadyExists":
|
|
285
|
+
return "P1009";
|
|
286
|
+
case "DatabaseAccessDenied":
|
|
287
|
+
return "P1010";
|
|
288
|
+
case "TlsConnectionError":
|
|
289
|
+
return "P1011";
|
|
290
|
+
case "ConnectionClosed":
|
|
291
|
+
return "P1017";
|
|
292
|
+
case "TransactionAlreadyClosed":
|
|
293
|
+
return "P1018";
|
|
294
|
+
case "LengthMismatch":
|
|
295
|
+
return "P2000";
|
|
296
|
+
case "UniqueConstraintViolation":
|
|
297
|
+
return "P2002";
|
|
298
|
+
case "ForeignKeyConstraintViolation":
|
|
299
|
+
return "P2003";
|
|
300
|
+
case "UnsupportedNativeDataType":
|
|
301
|
+
return "P2010";
|
|
302
|
+
case "NullConstraintViolation":
|
|
303
|
+
return "P2011";
|
|
304
|
+
case "ValueOutOfRange":
|
|
305
|
+
return "P2020";
|
|
306
|
+
case "TableDoesNotExist":
|
|
307
|
+
return "P2021";
|
|
308
|
+
case "ColumnNotFound":
|
|
309
|
+
return "P2022";
|
|
310
|
+
case "InvalidIsolationLevel":
|
|
311
|
+
case "InconsistentColumnData":
|
|
312
|
+
return "P2023";
|
|
313
|
+
case "MissingFullTextSearchIndex":
|
|
314
|
+
return "P2030";
|
|
315
|
+
case "TransactionWriteConflict":
|
|
316
|
+
return "P2034";
|
|
317
|
+
case "GenericJs":
|
|
318
|
+
return "P2036";
|
|
319
|
+
case "TooManyConnections":
|
|
320
|
+
return "P2037";
|
|
321
|
+
case "postgres":
|
|
322
|
+
case "sqlite":
|
|
323
|
+
case "mysql":
|
|
324
|
+
case "mssql":
|
|
325
|
+
return;
|
|
326
|
+
default:
|
|
327
|
+
assertNever(err.cause, `Unknown error: ${err.cause}`);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
function renderErrorMessage(err) {
|
|
331
|
+
switch (err.cause.kind) {
|
|
332
|
+
case "AuthenticationFailed": {
|
|
333
|
+
const user = err.cause.user ?? "(not available)";
|
|
334
|
+
return `Authentication failed against the database server, the provided database credentials for \`${user}\` are not valid`;
|
|
335
|
+
}
|
|
336
|
+
case "DatabaseNotReachable": {
|
|
337
|
+
const address = err.cause.host && err.cause.port ? `${err.cause.host}:${err.cause.port}` : err.cause.host;
|
|
338
|
+
return `Can't reach database server${address ? ` at ${address}` : ""}`;
|
|
339
|
+
}
|
|
340
|
+
case "DatabaseDoesNotExist": {
|
|
341
|
+
const db = err.cause.db ?? "(not available)";
|
|
342
|
+
return `Database \`${db}\` does not exist on the database server`;
|
|
343
|
+
}
|
|
344
|
+
case "SocketTimeout":
|
|
345
|
+
return `Operation has timed out`;
|
|
346
|
+
case "DatabaseAlreadyExists": {
|
|
347
|
+
const db = err.cause.db ?? "(not available)";
|
|
348
|
+
return `Database \`${db}\` already exists on the database server`;
|
|
349
|
+
}
|
|
350
|
+
case "DatabaseAccessDenied": {
|
|
351
|
+
const db = err.cause.db ?? "(not available)";
|
|
352
|
+
return `User was denied access on the database \`${db}\``;
|
|
353
|
+
}
|
|
354
|
+
case "TlsConnectionError": {
|
|
355
|
+
return `Error opening a TLS connection: ${err.cause.reason}`;
|
|
356
|
+
}
|
|
357
|
+
case "ConnectionClosed": {
|
|
358
|
+
return "Server has closed the connection.";
|
|
359
|
+
}
|
|
360
|
+
case "TransactionAlreadyClosed":
|
|
361
|
+
return err.cause.cause;
|
|
362
|
+
case "LengthMismatch": {
|
|
363
|
+
const column = err.cause.column ?? "(not available)";
|
|
364
|
+
return `The provided value for the column is too long for the column's type. Column: ${column}`;
|
|
365
|
+
}
|
|
366
|
+
case "UniqueConstraintViolation":
|
|
367
|
+
return `Unique constraint failed on the ${renderConstraint(err.cause.constraint)}`;
|
|
368
|
+
case "ForeignKeyConstraintViolation":
|
|
369
|
+
return `Foreign key constraint violated on the ${renderConstraint(err.cause.constraint)}`;
|
|
370
|
+
case "UnsupportedNativeDataType":
|
|
371
|
+
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\`.`;
|
|
372
|
+
case "NullConstraintViolation":
|
|
373
|
+
return `Null constraint violation on the ${renderConstraint(err.cause.constraint)}`;
|
|
374
|
+
case "ValueOutOfRange":
|
|
375
|
+
return `Value out of range for the type: ${err.cause.cause}`;
|
|
376
|
+
case "TableDoesNotExist": {
|
|
377
|
+
const table = err.cause.table ?? "(not available)";
|
|
378
|
+
return `The table \`${table}\` does not exist in the current database.`;
|
|
379
|
+
}
|
|
380
|
+
case "ColumnNotFound": {
|
|
381
|
+
const column = err.cause.column ?? "(not available)";
|
|
382
|
+
return `The column \`${column}\` does not exist in the current database.`;
|
|
383
|
+
}
|
|
384
|
+
case "InvalidIsolationLevel":
|
|
385
|
+
return `Error in connector: Conversion error: ${err.cause.level}`;
|
|
386
|
+
case "InconsistentColumnData":
|
|
387
|
+
return `Inconsistent column data: ${err.cause.cause}`;
|
|
388
|
+
case "MissingFullTextSearchIndex":
|
|
389
|
+
return "Cannot find a fulltext index to use for the native search, try adding a @@fulltext([Fields...]) to your schema";
|
|
390
|
+
case "TransactionWriteConflict":
|
|
391
|
+
return `Transaction failed due to a write conflict or a deadlock. Please retry your transaction`;
|
|
392
|
+
case "GenericJs":
|
|
393
|
+
return `Error in external connector (id ${err.cause.id})`;
|
|
394
|
+
case "TooManyConnections":
|
|
395
|
+
return `Too many database connections opened: ${err.cause.cause}`;
|
|
396
|
+
case "sqlite":
|
|
397
|
+
case "postgres":
|
|
398
|
+
case "mysql":
|
|
399
|
+
case "mssql":
|
|
400
|
+
return;
|
|
401
|
+
default:
|
|
402
|
+
assertNever(err.cause, `Unknown error: ${err.cause}`);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
function renderConstraint(constraint) {
|
|
406
|
+
if (constraint && "fields" in constraint) {
|
|
407
|
+
return `fields: (${constraint.fields.map((field) => `\`${field}\``).join(", ")})`;
|
|
408
|
+
} else if (constraint && "index" in constraint) {
|
|
409
|
+
return `constraint: \`${constraint.index}\``;
|
|
410
|
+
} else if (constraint && "foreignKey" in constraint) {
|
|
411
|
+
return `foreign key`;
|
|
412
|
+
}
|
|
413
|
+
return "(not available)";
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// src/batch.ts
|
|
417
|
+
function convertCompactedRows(rows, compiledBatch) {
|
|
418
|
+
const keysPerRow = rows.map(
|
|
419
|
+
(item) => compiledBatch.keys.reduce((acc, key) => {
|
|
420
|
+
acc[key] = deserializeJsonResponse(item[key]);
|
|
421
|
+
return acc;
|
|
422
|
+
}, {})
|
|
423
|
+
);
|
|
424
|
+
const selection = new Set(compiledBatch.nestedSelection);
|
|
425
|
+
return compiledBatch.arguments.map((args) => {
|
|
426
|
+
const rowIndex = keysPerRow.findIndex((rowKeys) => doKeysMatch(rowKeys, args));
|
|
427
|
+
if (rowIndex === -1) {
|
|
428
|
+
if (compiledBatch.expectNonEmpty) {
|
|
429
|
+
return new UserFacingError(
|
|
430
|
+
"An operation failed because it depends on one or more records that were required but not found",
|
|
431
|
+
"P2025"
|
|
432
|
+
);
|
|
433
|
+
} else {
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
} else {
|
|
437
|
+
const selected = Object.entries(rows[rowIndex]).filter(([k]) => selection.has(k));
|
|
438
|
+
return Object.fromEntries(selected);
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// src/interpreter/data-mapper.ts
|
|
444
|
+
var import_decimal3 = __toESM(require("decimal.js"));
|
|
146
445
|
var DataMapperError = class extends Error {
|
|
147
446
|
name = "DataMapperError";
|
|
148
447
|
};
|
|
@@ -154,17 +453,20 @@ function applyDataMap(data, structure, enums) {
|
|
|
154
453
|
}
|
|
155
454
|
return { count: data };
|
|
156
455
|
case "Object":
|
|
157
|
-
return mapArrayOrObject(data, structure.fields, enums);
|
|
456
|
+
return mapArrayOrObject(data, structure.fields, enums, structure.skipNulls);
|
|
158
457
|
case "Value":
|
|
159
458
|
return mapValue(data, "<result>", structure.resultType, enums);
|
|
160
459
|
default:
|
|
161
460
|
assertNever(structure, `Invalid data mapping type: '${structure.type}'`);
|
|
162
461
|
}
|
|
163
462
|
}
|
|
164
|
-
function mapArrayOrObject(data, fields, enums) {
|
|
463
|
+
function mapArrayOrObject(data, fields, enums, skipNulls) {
|
|
165
464
|
if (data === null) return null;
|
|
166
465
|
if (Array.isArray(data)) {
|
|
167
|
-
|
|
466
|
+
let rows = data;
|
|
467
|
+
if (skipNulls) {
|
|
468
|
+
rows = rows.filter((row) => row !== null);
|
|
469
|
+
}
|
|
168
470
|
return rows.map((row) => mapObject(row, fields, enums));
|
|
169
471
|
}
|
|
170
472
|
if (typeof data === "object") {
|
|
@@ -180,7 +482,7 @@ function mapArrayOrObject(data, fields, enums) {
|
|
|
180
482
|
cause: error
|
|
181
483
|
});
|
|
182
484
|
}
|
|
183
|
-
return mapArrayOrObject(decodedData, fields, enums);
|
|
485
|
+
return mapArrayOrObject(decodedData, fields, enums, skipNulls);
|
|
184
486
|
}
|
|
185
487
|
throw new DataMapperError(`Expected an array or an object, got: ${typeof data}`);
|
|
186
488
|
}
|
|
@@ -201,7 +503,7 @@ function mapObject(data, fields, enums) {
|
|
|
201
503
|
);
|
|
202
504
|
}
|
|
203
505
|
const target = node.serializedName !== null ? data[node.serializedName] : data;
|
|
204
|
-
result[name] = mapArrayOrObject(target, node.fields, enums);
|
|
506
|
+
result[name] = mapArrayOrObject(target, node.fields, enums, node.skipNulls);
|
|
205
507
|
break;
|
|
206
508
|
}
|
|
207
509
|
case "Value":
|
|
@@ -294,7 +596,7 @@ function mapValue(value, columnName, resultType, enums) {
|
|
|
294
596
|
throw new DataMapperError(`Expected a boolean in column '${columnName}', got ${typeof value}: ${value}`);
|
|
295
597
|
}
|
|
296
598
|
case "Decimal":
|
|
297
|
-
if (typeof value !== "number" && typeof value !== "string" && !
|
|
599
|
+
if (typeof value !== "number" && typeof value !== "string" && !import_decimal3.default.isDecimal(value)) {
|
|
298
600
|
throw new DataMapperError(`Expected a decimal in column '${columnName}', got ${typeof value}: ${value}`);
|
|
299
601
|
}
|
|
300
602
|
return { $type: "Decimal", value };
|
|
@@ -318,8 +620,10 @@ function mapValue(value, columnName, resultType, enums) {
|
|
|
318
620
|
return values.map((v, i) => mapValue(v, `${columnName}[${i}]`, resultType.inner, enums));
|
|
319
621
|
}
|
|
320
622
|
case "Object": {
|
|
321
|
-
|
|
322
|
-
|
|
623
|
+
return { $type: "Json", value: safeJsonStringify(value) };
|
|
624
|
+
}
|
|
625
|
+
case "Json": {
|
|
626
|
+
return { $type: "Json", value: `${value}` };
|
|
323
627
|
}
|
|
324
628
|
case "Bytes": {
|
|
325
629
|
if (typeof value === "string" && value.startsWith("\\x")) {
|
|
@@ -340,7 +644,7 @@ function mapValue(value, columnName, resultType, enums) {
|
|
|
340
644
|
}
|
|
341
645
|
const enumValue = enumDef[`${value}`];
|
|
342
646
|
if (enumValue === void 0) {
|
|
343
|
-
throw new DataMapperError(`
|
|
647
|
+
throw new DataMapperError(`Value '${value}' not found in enum '${resultType.inner}'`);
|
|
344
648
|
}
|
|
345
649
|
return enumValue;
|
|
346
650
|
}
|
|
@@ -395,201 +699,25 @@ async function withQuerySpanAndEvent({
|
|
|
395
699
|
{
|
|
396
700
|
name: "db_query",
|
|
397
701
|
kind: import_api.SpanKind.CLIENT,
|
|
398
|
-
attributes: {
|
|
399
|
-
"db.query.text": query.sql,
|
|
400
|
-
"db.system.name": providerToOtelSystem(provider)
|
|
401
|
-
}
|
|
402
|
-
},
|
|
403
|
-
async () => {
|
|
404
|
-
const timestamp = /* @__PURE__ */ new Date();
|
|
405
|
-
const startInstant = performance.now();
|
|
406
|
-
const result = await execute();
|
|
407
|
-
const endInstant = performance.now();
|
|
408
|
-
onQuery?.({
|
|
409
|
-
timestamp,
|
|
410
|
-
duration: endInstant - startInstant,
|
|
411
|
-
query: query.sql,
|
|
412
|
-
params: query.args
|
|
413
|
-
});
|
|
414
|
-
return result;
|
|
415
|
-
}
|
|
416
|
-
);
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
// src/UserFacingError.ts
|
|
420
|
-
var import_driver_adapter_utils = require("@prisma/driver-adapter-utils");
|
|
421
|
-
var UserFacingError = class extends Error {
|
|
422
|
-
name = "UserFacingError";
|
|
423
|
-
code;
|
|
424
|
-
meta;
|
|
425
|
-
constructor(message, code, meta) {
|
|
426
|
-
super(message);
|
|
427
|
-
this.code = code;
|
|
428
|
-
this.meta = meta ?? {};
|
|
429
|
-
}
|
|
430
|
-
toQueryResponseErrorObject() {
|
|
431
|
-
return {
|
|
432
|
-
error: this.message,
|
|
433
|
-
user_facing_error: {
|
|
434
|
-
is_panic: false,
|
|
435
|
-
message: this.message,
|
|
436
|
-
meta: this.meta,
|
|
437
|
-
error_code: this.code
|
|
438
|
-
}
|
|
439
|
-
};
|
|
440
|
-
}
|
|
441
|
-
};
|
|
442
|
-
function rethrowAsUserFacing(error) {
|
|
443
|
-
if (!(0, import_driver_adapter_utils.isDriverAdapterError)(error)) {
|
|
444
|
-
throw error;
|
|
445
|
-
}
|
|
446
|
-
const code = getErrorCode(error);
|
|
447
|
-
const message = renderErrorMessage(error);
|
|
448
|
-
if (!code || !message) {
|
|
449
|
-
throw error;
|
|
450
|
-
}
|
|
451
|
-
throw new UserFacingError(message, code, { driverAdapterError: error });
|
|
452
|
-
}
|
|
453
|
-
function getErrorCode(err) {
|
|
454
|
-
switch (err.cause.kind) {
|
|
455
|
-
case "AuthenticationFailed":
|
|
456
|
-
return "P1000";
|
|
457
|
-
case "DatabaseNotReachable":
|
|
458
|
-
return "P1001";
|
|
459
|
-
case "DatabaseDoesNotExist":
|
|
460
|
-
return "P1003";
|
|
461
|
-
case "SocketTimeout":
|
|
462
|
-
return "P1008";
|
|
463
|
-
case "DatabaseAlreadyExists":
|
|
464
|
-
return "P1009";
|
|
465
|
-
case "DatabaseAccessDenied":
|
|
466
|
-
return "P1010";
|
|
467
|
-
case "TlsConnectionError":
|
|
468
|
-
return "P1011";
|
|
469
|
-
case "ConnectionClosed":
|
|
470
|
-
return "P1017";
|
|
471
|
-
case "TransactionAlreadyClosed":
|
|
472
|
-
return "P1018";
|
|
473
|
-
case "LengthMismatch":
|
|
474
|
-
return "P2000";
|
|
475
|
-
case "UniqueConstraintViolation":
|
|
476
|
-
return "P2002";
|
|
477
|
-
case "ForeignKeyConstraintViolation":
|
|
478
|
-
return "P2003";
|
|
479
|
-
case "UnsupportedNativeDataType":
|
|
480
|
-
return "P2010";
|
|
481
|
-
case "NullConstraintViolation":
|
|
482
|
-
return "P2011";
|
|
483
|
-
case "ValueOutOfRange":
|
|
484
|
-
return "P2020";
|
|
485
|
-
case "TableDoesNotExist":
|
|
486
|
-
return "P2021";
|
|
487
|
-
case "ColumnNotFound":
|
|
488
|
-
return "P2022";
|
|
489
|
-
case "InvalidIsolationLevel":
|
|
490
|
-
case "InconsistentColumnData":
|
|
491
|
-
return "P2023";
|
|
492
|
-
case "MissingFullTextSearchIndex":
|
|
493
|
-
return "P2030";
|
|
494
|
-
case "TransactionWriteConflict":
|
|
495
|
-
return "P2034";
|
|
496
|
-
case "GenericJs":
|
|
497
|
-
return "P2036";
|
|
498
|
-
case "TooManyConnections":
|
|
499
|
-
return "P2037";
|
|
500
|
-
case "postgres":
|
|
501
|
-
case "sqlite":
|
|
502
|
-
case "mysql":
|
|
503
|
-
case "mssql":
|
|
504
|
-
return;
|
|
505
|
-
default:
|
|
506
|
-
assertNever(err.cause, `Unknown error: ${err.cause}`);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
function renderErrorMessage(err) {
|
|
510
|
-
switch (err.cause.kind) {
|
|
511
|
-
case "AuthenticationFailed": {
|
|
512
|
-
const user = err.cause.user ?? "(not available)";
|
|
513
|
-
return `Authentication failed against the database server, the provided database credentials for \`${user}\` are not valid`;
|
|
514
|
-
}
|
|
515
|
-
case "DatabaseNotReachable": {
|
|
516
|
-
const address = err.cause.host && err.cause.port ? `${err.cause.host}:${err.cause.port}` : err.cause.host;
|
|
517
|
-
return `Can't reach database server${address ? ` at ${address}` : ""}`;
|
|
518
|
-
}
|
|
519
|
-
case "DatabaseDoesNotExist": {
|
|
520
|
-
const db = err.cause.db ?? "(not available)";
|
|
521
|
-
return `Database \`${db}\` does not exist on the database server`;
|
|
522
|
-
}
|
|
523
|
-
case "SocketTimeout":
|
|
524
|
-
return `Operation has timed out`;
|
|
525
|
-
case "DatabaseAlreadyExists": {
|
|
526
|
-
const db = err.cause.db ?? "(not available)";
|
|
527
|
-
return `Database \`${db}\` already exists on the database server`;
|
|
528
|
-
}
|
|
529
|
-
case "DatabaseAccessDenied": {
|
|
530
|
-
const db = err.cause.db ?? "(not available)";
|
|
531
|
-
return `User was denied access on the database \`${db}\``;
|
|
532
|
-
}
|
|
533
|
-
case "TlsConnectionError": {
|
|
534
|
-
return `Error opening a TLS connection: ${err.cause.reason}`;
|
|
535
|
-
}
|
|
536
|
-
case "ConnectionClosed": {
|
|
537
|
-
return "Server has closed the connection.";
|
|
538
|
-
}
|
|
539
|
-
case "TransactionAlreadyClosed":
|
|
540
|
-
return err.cause.cause;
|
|
541
|
-
case "LengthMismatch": {
|
|
542
|
-
const column = err.cause.column ?? "(not available)";
|
|
543
|
-
return `The provided value for the column is too long for the column's type. Column: ${column}`;
|
|
544
|
-
}
|
|
545
|
-
case "UniqueConstraintViolation":
|
|
546
|
-
return `Unique constraint failed on the ${renderConstraint(err.cause.constraint)}`;
|
|
547
|
-
case "ForeignKeyConstraintViolation":
|
|
548
|
-
return `Foreign key constraint violated on the ${renderConstraint(err.cause.constraint)}`;
|
|
549
|
-
case "UnsupportedNativeDataType":
|
|
550
|
-
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\`.`;
|
|
551
|
-
case "NullConstraintViolation":
|
|
552
|
-
return `Null constraint violation on the ${renderConstraint(err.cause.constraint)}`;
|
|
553
|
-
case "ValueOutOfRange":
|
|
554
|
-
return `Value out of range for the type: ${err.cause.cause}`;
|
|
555
|
-
case "TableDoesNotExist": {
|
|
556
|
-
const table = err.cause.table ?? "(not available)";
|
|
557
|
-
return `The table \`${table}\` does not exist in the current database.`;
|
|
558
|
-
}
|
|
559
|
-
case "ColumnNotFound": {
|
|
560
|
-
const column = err.cause.column ?? "(not available)";
|
|
561
|
-
return `The column \`${column}\` does not exist in the current database.`;
|
|
562
|
-
}
|
|
563
|
-
case "InvalidIsolationLevel":
|
|
564
|
-
return `Invalid isolation level \`${err.cause.level}\``;
|
|
565
|
-
case "InconsistentColumnData":
|
|
566
|
-
return `Inconsistent column data: ${err.cause.cause}`;
|
|
567
|
-
case "MissingFullTextSearchIndex":
|
|
568
|
-
return "Cannot find a fulltext index to use for the native search, try adding a @@fulltext([Fields...]) to your schema";
|
|
569
|
-
case "TransactionWriteConflict":
|
|
570
|
-
return `Transaction failed due to a write conflict or a deadlock. Please retry your transaction`;
|
|
571
|
-
case "GenericJs":
|
|
572
|
-
return `Error in external connector (id ${err.cause.id})`;
|
|
573
|
-
case "TooManyConnections":
|
|
574
|
-
return `Too many database connections opened: ${err.cause.cause}`;
|
|
575
|
-
case "sqlite":
|
|
576
|
-
case "postgres":
|
|
577
|
-
case "mysql":
|
|
578
|
-
case "mssql":
|
|
579
|
-
return;
|
|
580
|
-
default:
|
|
581
|
-
assertNever(err.cause, `Unknown error: ${err.cause}`);
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
function renderConstraint(constraint) {
|
|
585
|
-
if (constraint && "fields" in constraint) {
|
|
586
|
-
return `fields: (${constraint.fields.map((field) => `\`${field}\``).join(", ")})`;
|
|
587
|
-
} else if (constraint && "index" in constraint) {
|
|
588
|
-
return `constraint: \`${constraint.index}\``;
|
|
589
|
-
} else if (constraint && "foreignKey" in constraint) {
|
|
590
|
-
return `foreign key`;
|
|
591
|
-
}
|
|
592
|
-
return "(not available)";
|
|
702
|
+
attributes: {
|
|
703
|
+
"db.query.text": query.sql,
|
|
704
|
+
"db.system.name": providerToOtelSystem(provider)
|
|
705
|
+
}
|
|
706
|
+
},
|
|
707
|
+
async () => {
|
|
708
|
+
const timestamp = /* @__PURE__ */ new Date();
|
|
709
|
+
const startInstant = performance.now();
|
|
710
|
+
const result = await execute();
|
|
711
|
+
const endInstant = performance.now();
|
|
712
|
+
onQuery?.({
|
|
713
|
+
timestamp,
|
|
714
|
+
duration: endInstant - startInstant,
|
|
715
|
+
query: query.sql,
|
|
716
|
+
params: query.args
|
|
717
|
+
});
|
|
718
|
+
return result;
|
|
719
|
+
}
|
|
720
|
+
);
|
|
593
721
|
}
|
|
594
722
|
|
|
595
723
|
// src/interpreter/generators.ts
|
|
@@ -693,7 +821,98 @@ var ProductGenerator = class {
|
|
|
693
821
|
}
|
|
694
822
|
};
|
|
695
823
|
|
|
696
|
-
// src/
|
|
824
|
+
// src/interpreter/in-memory-processing.ts
|
|
825
|
+
function processRecords(value, ops) {
|
|
826
|
+
if (value == null) {
|
|
827
|
+
return value;
|
|
828
|
+
}
|
|
829
|
+
if (typeof value === "string") {
|
|
830
|
+
return processRecords(JSON.parse(value), ops);
|
|
831
|
+
}
|
|
832
|
+
if (Array.isArray(value)) {
|
|
833
|
+
return processManyRecords(value, ops);
|
|
834
|
+
}
|
|
835
|
+
return processOneRecord(value, ops);
|
|
836
|
+
}
|
|
837
|
+
function processOneRecord(record, ops) {
|
|
838
|
+
if (ops.pagination) {
|
|
839
|
+
const { skip, take, cursor } = ops.pagination;
|
|
840
|
+
if (skip !== null && skip > 0) {
|
|
841
|
+
return null;
|
|
842
|
+
}
|
|
843
|
+
if (take === 0) {
|
|
844
|
+
return null;
|
|
845
|
+
}
|
|
846
|
+
if (cursor !== null && !doKeysMatch(record, cursor)) {
|
|
847
|
+
return null;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
return processNestedRecords(record, ops.nested);
|
|
851
|
+
}
|
|
852
|
+
function processNestedRecords(record, opsMap) {
|
|
853
|
+
for (const [key, ops] of Object.entries(opsMap)) {
|
|
854
|
+
record[key] = processRecords(record[key], ops);
|
|
855
|
+
}
|
|
856
|
+
return record;
|
|
857
|
+
}
|
|
858
|
+
function processManyRecords(records, ops) {
|
|
859
|
+
if (ops.distinct !== null) {
|
|
860
|
+
const fields = ops.linkingFields !== null ? [...ops.distinct, ...ops.linkingFields] : ops.distinct;
|
|
861
|
+
records = distinctBy(records, fields);
|
|
862
|
+
}
|
|
863
|
+
if (ops.pagination) {
|
|
864
|
+
records = paginate(records, ops.pagination, ops.linkingFields);
|
|
865
|
+
}
|
|
866
|
+
if (ops.reverse) {
|
|
867
|
+
records.reverse();
|
|
868
|
+
}
|
|
869
|
+
if (Object.keys(ops.nested).length === 0) {
|
|
870
|
+
return records;
|
|
871
|
+
}
|
|
872
|
+
return records.map((record) => processNestedRecords(record, ops.nested));
|
|
873
|
+
}
|
|
874
|
+
function distinctBy(records, fields) {
|
|
875
|
+
const seen = /* @__PURE__ */ new Set();
|
|
876
|
+
const result = [];
|
|
877
|
+
for (const record of records) {
|
|
878
|
+
const key = getRecordKey(record, fields);
|
|
879
|
+
if (!seen.has(key)) {
|
|
880
|
+
seen.add(key);
|
|
881
|
+
result.push(record);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
return result;
|
|
885
|
+
}
|
|
886
|
+
function paginate(records, pagination, linkingFields) {
|
|
887
|
+
if (linkingFields === null) {
|
|
888
|
+
return paginateSingleList(records, pagination);
|
|
889
|
+
}
|
|
890
|
+
const groupedByParent = /* @__PURE__ */ new Map();
|
|
891
|
+
for (const record of records) {
|
|
892
|
+
const parentKey = getRecordKey(record, linkingFields);
|
|
893
|
+
if (!groupedByParent.has(parentKey)) {
|
|
894
|
+
groupedByParent.set(parentKey, []);
|
|
895
|
+
}
|
|
896
|
+
groupedByParent.get(parentKey).push(record);
|
|
897
|
+
}
|
|
898
|
+
const groupList = Array.from(groupedByParent.entries());
|
|
899
|
+
groupList.sort(([aId], [bId]) => aId < bId ? -1 : aId > bId ? 1 : 0);
|
|
900
|
+
return groupList.flatMap(([, elems]) => paginateSingleList(elems, pagination));
|
|
901
|
+
}
|
|
902
|
+
function paginateSingleList(list, { cursor, skip, take }) {
|
|
903
|
+
const cursorIndex = cursor !== null ? list.findIndex((item) => doKeysMatch(item, cursor)) : 0;
|
|
904
|
+
if (cursorIndex === -1) {
|
|
905
|
+
return [];
|
|
906
|
+
}
|
|
907
|
+
const start = cursorIndex + (skip ?? 0);
|
|
908
|
+
const end = take !== null ? start + take : list.length;
|
|
909
|
+
return list.slice(start, end);
|
|
910
|
+
}
|
|
911
|
+
function getRecordKey(record, fields) {
|
|
912
|
+
return JSON.stringify(fields.map((field) => record[field]));
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// src/query-plan.ts
|
|
697
916
|
function isPrismaValuePlaceholder(value) {
|
|
698
917
|
return typeof value === "object" && value !== null && value["prisma__type"] === "param";
|
|
699
918
|
}
|
|
@@ -707,18 +926,22 @@ function isPrismaValueBigInt(value) {
|
|
|
707
926
|
return typeof value === "object" && value !== null && value["prisma__type"] === "bigint";
|
|
708
927
|
}
|
|
709
928
|
|
|
710
|
-
// src/interpreter/
|
|
711
|
-
function renderQuery(dbQuery, scope, generators) {
|
|
929
|
+
// src/interpreter/render-query.ts
|
|
930
|
+
function renderQuery(dbQuery, scope, generators, maxChunkSize) {
|
|
712
931
|
const queryType = dbQuery.type;
|
|
932
|
+
const params = evaluateParams(dbQuery.params, scope, generators);
|
|
713
933
|
switch (queryType) {
|
|
714
934
|
case "rawSql":
|
|
715
|
-
return renderRawSql(dbQuery.sql, evaluateParams(dbQuery.params, scope, generators));
|
|
716
|
-
case "templateSql":
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
935
|
+
return [renderRawSql(dbQuery.sql, evaluateParams(dbQuery.params, scope, generators))];
|
|
936
|
+
case "templateSql": {
|
|
937
|
+
const chunks = dbQuery.chunkable ? chunkParams(dbQuery.fragments, params, maxChunkSize) : [params];
|
|
938
|
+
return chunks.map((params2) => {
|
|
939
|
+
if (maxChunkSize !== void 0 && params2.length > maxChunkSize) {
|
|
940
|
+
throw new UserFacingError("The query parameter limit supported by your database is exceeded.", "P2029");
|
|
941
|
+
}
|
|
942
|
+
return renderTemplateSql(dbQuery.fragments, dbQuery.placeholderFormat, params2);
|
|
943
|
+
});
|
|
944
|
+
}
|
|
722
945
|
default:
|
|
723
946
|
assertNever(queryType, `Invalid query type`);
|
|
724
947
|
}
|
|
@@ -756,61 +979,36 @@ function evaluateParam(param, scope, generators) {
|
|
|
756
979
|
return value;
|
|
757
980
|
}
|
|
758
981
|
function renderTemplateSql(fragments, placeholderFormat, params) {
|
|
759
|
-
let
|
|
760
|
-
|
|
982
|
+
let sql = "";
|
|
983
|
+
const ctx = { placeholderNumber: 1 };
|
|
761
984
|
const flattenedParams = [];
|
|
762
|
-
const
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
if (paramIndex >= params.length) {
|
|
767
|
-
throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
|
|
768
|
-
}
|
|
769
|
-
flattenedParams.push(params[paramIndex++]);
|
|
770
|
-
return formatPlaceholder(placeholderFormat, placeholderNumber++);
|
|
771
|
-
case "stringChunk":
|
|
772
|
-
return fragment.chunk;
|
|
773
|
-
case "parameterTuple": {
|
|
774
|
-
if (paramIndex >= params.length) {
|
|
775
|
-
throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
|
|
776
|
-
}
|
|
777
|
-
const paramValue = params[paramIndex++];
|
|
778
|
-
const paramArray = Array.isArray(paramValue) ? paramValue : [paramValue];
|
|
779
|
-
const placeholders = paramArray.length == 0 ? "NULL" : paramArray.map((value) => {
|
|
780
|
-
flattenedParams.push(value);
|
|
781
|
-
return formatPlaceholder(placeholderFormat, placeholderNumber++);
|
|
782
|
-
}).join(",");
|
|
783
|
-
return `(${placeholders})`;
|
|
784
|
-
}
|
|
785
|
-
case "parameterTupleList": {
|
|
786
|
-
if (paramIndex >= params.length) {
|
|
787
|
-
throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
|
|
788
|
-
}
|
|
789
|
-
const paramValue = params[paramIndex++];
|
|
790
|
-
if (!Array.isArray(paramValue)) {
|
|
791
|
-
throw new Error(`Malformed query template. Tuple list expected.`);
|
|
792
|
-
}
|
|
793
|
-
if (paramValue.length === 0) {
|
|
794
|
-
throw new Error(`Malformed query template. Tuple list cannot be empty.`);
|
|
795
|
-
}
|
|
796
|
-
const tupleList = paramValue.map((tuple) => {
|
|
797
|
-
if (!Array.isArray(tuple)) {
|
|
798
|
-
throw new Error(`Malformed query template. Tuple expected.`);
|
|
799
|
-
}
|
|
800
|
-
const elements = tuple.map((value) => {
|
|
801
|
-
flattenedParams.push(value);
|
|
802
|
-
return formatPlaceholder(placeholderFormat, placeholderNumber++);
|
|
803
|
-
}).join(fragment.itemSeparator);
|
|
804
|
-
return `${fragment.itemPrefix}${elements}${fragment.itemSuffix}`;
|
|
805
|
-
}).join(fragment.groupSeparator);
|
|
806
|
-
return tupleList;
|
|
807
|
-
}
|
|
808
|
-
default:
|
|
809
|
-
assertNever(fragmentType, "Invalid fragment type");
|
|
810
|
-
}
|
|
811
|
-
}).join("");
|
|
985
|
+
for (const fragment of pairFragmentsWithParams(fragments, params)) {
|
|
986
|
+
flattenedParams.push(...flattenedFragmentParams(fragment));
|
|
987
|
+
sql += renderFragment(fragment, placeholderFormat, ctx);
|
|
988
|
+
}
|
|
812
989
|
return renderRawSql(sql, flattenedParams);
|
|
813
990
|
}
|
|
991
|
+
function renderFragment(fragment, placeholderFormat, ctx) {
|
|
992
|
+
const fragmentType = fragment.type;
|
|
993
|
+
switch (fragmentType) {
|
|
994
|
+
case "parameter":
|
|
995
|
+
return formatPlaceholder(placeholderFormat, ctx.placeholderNumber++);
|
|
996
|
+
case "stringChunk":
|
|
997
|
+
return fragment.chunk;
|
|
998
|
+
case "parameterTuple": {
|
|
999
|
+
const placeholders = fragment.value.length == 0 ? "NULL" : fragment.value.map(() => formatPlaceholder(placeholderFormat, ctx.placeholderNumber++)).join(",");
|
|
1000
|
+
return `(${placeholders})`;
|
|
1001
|
+
}
|
|
1002
|
+
case "parameterTupleList": {
|
|
1003
|
+
return fragment.value.map((tuple) => {
|
|
1004
|
+
const elements = tuple.map(() => formatPlaceholder(placeholderFormat, ctx.placeholderNumber++)).join(fragment.itemSeparator);
|
|
1005
|
+
return `${fragment.itemPrefix}${elements}${fragment.itemSuffix}`;
|
|
1006
|
+
}).join(fragment.groupSeparator);
|
|
1007
|
+
}
|
|
1008
|
+
default:
|
|
1009
|
+
assertNever(fragmentType, "Invalid fragment type");
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
814
1012
|
function formatPlaceholder(placeholderFormat, placeholderNumber) {
|
|
815
1013
|
return placeholderFormat.hasNumbering ? `${placeholderFormat.prefix}${placeholderNumber}` : placeholderFormat.prefix;
|
|
816
1014
|
}
|
|
@@ -843,8 +1041,145 @@ function toArgType(value) {
|
|
|
843
1041
|
function doesRequireEvaluation(param) {
|
|
844
1042
|
return isPrismaValuePlaceholder(param) || isPrismaValueGenerator(param);
|
|
845
1043
|
}
|
|
1044
|
+
function* pairFragmentsWithParams(fragments, params) {
|
|
1045
|
+
let index = 0;
|
|
1046
|
+
for (const fragment of fragments) {
|
|
1047
|
+
switch (fragment.type) {
|
|
1048
|
+
case "parameter": {
|
|
1049
|
+
if (index >= params.length) {
|
|
1050
|
+
throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
|
|
1051
|
+
}
|
|
1052
|
+
yield { ...fragment, value: params[index++] };
|
|
1053
|
+
break;
|
|
1054
|
+
}
|
|
1055
|
+
case "stringChunk": {
|
|
1056
|
+
yield fragment;
|
|
1057
|
+
break;
|
|
1058
|
+
}
|
|
1059
|
+
case "parameterTuple": {
|
|
1060
|
+
if (index >= params.length) {
|
|
1061
|
+
throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
|
|
1062
|
+
}
|
|
1063
|
+
const value = params[index++];
|
|
1064
|
+
yield { ...fragment, value: Array.isArray(value) ? value : [value] };
|
|
1065
|
+
break;
|
|
1066
|
+
}
|
|
1067
|
+
case "parameterTupleList": {
|
|
1068
|
+
if (index >= params.length) {
|
|
1069
|
+
throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
|
|
1070
|
+
}
|
|
1071
|
+
const value = params[index++];
|
|
1072
|
+
if (!Array.isArray(value)) {
|
|
1073
|
+
throw new Error(`Malformed query template. Tuple list expected.`);
|
|
1074
|
+
}
|
|
1075
|
+
if (value.length === 0) {
|
|
1076
|
+
throw new Error(`Malformed query template. Tuple list cannot be empty.`);
|
|
1077
|
+
}
|
|
1078
|
+
for (const tuple of value) {
|
|
1079
|
+
if (!Array.isArray(tuple)) {
|
|
1080
|
+
throw new Error(`Malformed query template. Tuple expected.`);
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
yield { ...fragment, value };
|
|
1084
|
+
break;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
function* flattenedFragmentParams(fragment) {
|
|
1090
|
+
switch (fragment.type) {
|
|
1091
|
+
case "parameter":
|
|
1092
|
+
yield fragment.value;
|
|
1093
|
+
break;
|
|
1094
|
+
case "stringChunk":
|
|
1095
|
+
break;
|
|
1096
|
+
case "parameterTuple":
|
|
1097
|
+
yield* fragment.value;
|
|
1098
|
+
break;
|
|
1099
|
+
case "parameterTupleList":
|
|
1100
|
+
for (const tuple of fragment.value) {
|
|
1101
|
+
yield* tuple;
|
|
1102
|
+
}
|
|
1103
|
+
break;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
function chunkParams(fragments, params, maxChunkSize) {
|
|
1107
|
+
let totalParamCount = 0;
|
|
1108
|
+
let maxParamsPerFragment = 0;
|
|
1109
|
+
for (const fragment of pairFragmentsWithParams(fragments, params)) {
|
|
1110
|
+
let paramSize = 0;
|
|
1111
|
+
for (const _ of flattenedFragmentParams(fragment)) {
|
|
1112
|
+
void _;
|
|
1113
|
+
paramSize++;
|
|
1114
|
+
}
|
|
1115
|
+
maxParamsPerFragment = Math.max(maxParamsPerFragment, paramSize);
|
|
1116
|
+
totalParamCount += paramSize;
|
|
1117
|
+
}
|
|
1118
|
+
let chunkedParams = [[]];
|
|
1119
|
+
for (const fragment of pairFragmentsWithParams(fragments, params)) {
|
|
1120
|
+
switch (fragment.type) {
|
|
1121
|
+
case "parameter": {
|
|
1122
|
+
for (const params2 of chunkedParams) {
|
|
1123
|
+
params2.push(fragment.value);
|
|
1124
|
+
}
|
|
1125
|
+
break;
|
|
1126
|
+
}
|
|
1127
|
+
case "stringChunk": {
|
|
1128
|
+
break;
|
|
1129
|
+
}
|
|
1130
|
+
case "parameterTuple": {
|
|
1131
|
+
const thisParamCount = fragment.value.length;
|
|
1132
|
+
let chunks = [];
|
|
1133
|
+
if (maxChunkSize && // Have we split the parameters into chunks already?
|
|
1134
|
+
chunkedParams.length === 1 && // Is this the fragment that has the most parameters?
|
|
1135
|
+
thisParamCount === maxParamsPerFragment && // Do we need chunking to fit the parameters?
|
|
1136
|
+
totalParamCount > maxChunkSize && // Would chunking enable us to fit the parameters?
|
|
1137
|
+
totalParamCount - thisParamCount < maxChunkSize) {
|
|
1138
|
+
const availableSize = maxChunkSize - (totalParamCount - thisParamCount);
|
|
1139
|
+
chunks = chunkArray(fragment.value, availableSize);
|
|
1140
|
+
} else {
|
|
1141
|
+
chunks = [fragment.value];
|
|
1142
|
+
}
|
|
1143
|
+
chunkedParams = chunkedParams.flatMap((params2) => chunks.map((chunk) => [...params2, chunk]));
|
|
1144
|
+
break;
|
|
1145
|
+
}
|
|
1146
|
+
case "parameterTupleList": {
|
|
1147
|
+
const thisParamCount = fragment.value.reduce((acc, tuple) => acc + tuple.length, 0);
|
|
1148
|
+
const completeChunks = [];
|
|
1149
|
+
let currentChunk = [];
|
|
1150
|
+
let currentChunkParamCount = 0;
|
|
1151
|
+
for (const tuple of fragment.value) {
|
|
1152
|
+
if (maxChunkSize && // Have we split the parameters into chunks already?
|
|
1153
|
+
chunkedParams.length === 1 && // Is this the fragment that has the most parameters?
|
|
1154
|
+
thisParamCount === maxParamsPerFragment && // Is there anything in the current chunk?
|
|
1155
|
+
currentChunk.length > 0 && // Will adding this tuple exceed the max chunk size?
|
|
1156
|
+
totalParamCount - thisParamCount + currentChunkParamCount + tuple.length > maxChunkSize) {
|
|
1157
|
+
completeChunks.push(currentChunk);
|
|
1158
|
+
currentChunk = [];
|
|
1159
|
+
currentChunkParamCount = 0;
|
|
1160
|
+
}
|
|
1161
|
+
currentChunk.push(tuple);
|
|
1162
|
+
currentChunkParamCount += tuple.length;
|
|
1163
|
+
}
|
|
1164
|
+
if (currentChunk.length > 0) {
|
|
1165
|
+
completeChunks.push(currentChunk);
|
|
1166
|
+
}
|
|
1167
|
+
chunkedParams = chunkedParams.flatMap((params2) => completeChunks.map((chunk) => [...params2, chunk]));
|
|
1168
|
+
break;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
return chunkedParams;
|
|
1173
|
+
}
|
|
1174
|
+
function chunkArray(array, chunkSize) {
|
|
1175
|
+
const result = [];
|
|
1176
|
+
for (let i = 0; i < array.length; i += chunkSize) {
|
|
1177
|
+
result.push(array.slice(i, i + chunkSize));
|
|
1178
|
+
}
|
|
1179
|
+
return result;
|
|
1180
|
+
}
|
|
846
1181
|
|
|
847
|
-
// src/interpreter/
|
|
1182
|
+
// src/interpreter/serialize-sql.ts
|
|
848
1183
|
var import_driver_adapter_utils2 = require("@prisma/driver-adapter-utils");
|
|
849
1184
|
function serializeSql(resultSet) {
|
|
850
1185
|
const mappers = resultSet.columnTypes.map((type) => {
|
|
@@ -875,29 +1210,90 @@ function serializeSql(resultSet) {
|
|
|
875
1210
|
);
|
|
876
1211
|
}
|
|
877
1212
|
function serializeRawSql(resultSet) {
|
|
878
|
-
const types = resultSet.columnTypes.map((type) => serializeColumnType(type));
|
|
879
|
-
const mappers = types.map((type) => {
|
|
880
|
-
switch (type) {
|
|
881
|
-
case "bytes":
|
|
882
|
-
return (value) => Array.isArray(value) ? new Uint8Array(value) : value;
|
|
883
|
-
case "int":
|
|
884
|
-
return (value) => value === null ? null : typeof value === "number" ? value : parseInt(`${value}`, 10);
|
|
885
|
-
case "bigint":
|
|
886
|
-
return (value) => value === null ? null : typeof value === "bigint" ? value : BigInt(`${value}`);
|
|
887
|
-
case "json":
|
|
888
|
-
return (value) => typeof value === "string" ? JSON.parse(value) : value;
|
|
889
|
-
case "bool":
|
|
890
|
-
return (value) => typeof value === "string" ? value === "true" || value === "1" : typeof value === "number" ? value === 1 : value;
|
|
891
|
-
default:
|
|
892
|
-
return (value) => value;
|
|
893
|
-
}
|
|
894
|
-
});
|
|
895
1213
|
return {
|
|
896
1214
|
columns: resultSet.columnNames,
|
|
897
1215
|
types: resultSet.columnTypes.map((type) => serializeColumnType(type)),
|
|
898
|
-
rows: resultSet.rows.map(
|
|
1216
|
+
rows: resultSet.rows.map(
|
|
1217
|
+
(row) => row.map((value, index) => serializeRawValue(value, resultSet.columnTypes[index]))
|
|
1218
|
+
)
|
|
899
1219
|
};
|
|
900
1220
|
}
|
|
1221
|
+
function serializeRawValue(value, type) {
|
|
1222
|
+
if (value === null) {
|
|
1223
|
+
return null;
|
|
1224
|
+
}
|
|
1225
|
+
switch (type) {
|
|
1226
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Int32:
|
|
1227
|
+
switch (typeof value) {
|
|
1228
|
+
case "number":
|
|
1229
|
+
return Math.trunc(value);
|
|
1230
|
+
case "string":
|
|
1231
|
+
return Math.trunc(Number(value));
|
|
1232
|
+
default:
|
|
1233
|
+
throw new Error(`Cannot serialize value of type ${typeof value} as Int32`);
|
|
1234
|
+
}
|
|
1235
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Int32Array:
|
|
1236
|
+
if (!Array.isArray(value)) {
|
|
1237
|
+
throw new Error(`Cannot serialize value of type ${typeof value} as Int32Array`);
|
|
1238
|
+
}
|
|
1239
|
+
return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Int32));
|
|
1240
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Int64:
|
|
1241
|
+
switch (typeof value) {
|
|
1242
|
+
case "number":
|
|
1243
|
+
return BigInt(Math.trunc(value));
|
|
1244
|
+
case "string":
|
|
1245
|
+
return value;
|
|
1246
|
+
default:
|
|
1247
|
+
throw new Error(`Cannot serialize value of type ${typeof value} as Int64`);
|
|
1248
|
+
}
|
|
1249
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Int64Array:
|
|
1250
|
+
if (!Array.isArray(value)) {
|
|
1251
|
+
throw new Error(`Cannot serialize value of type ${typeof value} as Int64Array`);
|
|
1252
|
+
}
|
|
1253
|
+
return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Int64));
|
|
1254
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Json:
|
|
1255
|
+
switch (typeof value) {
|
|
1256
|
+
case "string":
|
|
1257
|
+
return JSON.parse(value);
|
|
1258
|
+
default:
|
|
1259
|
+
throw new Error(`Cannot serialize value of type ${typeof value} as Json`);
|
|
1260
|
+
}
|
|
1261
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.JsonArray:
|
|
1262
|
+
if (!Array.isArray(value)) {
|
|
1263
|
+
throw new Error(`Cannot serialize value of type ${typeof value} as JsonArray`);
|
|
1264
|
+
}
|
|
1265
|
+
return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Json));
|
|
1266
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Bytes:
|
|
1267
|
+
if (Array.isArray(value)) {
|
|
1268
|
+
return new Uint8Array(value);
|
|
1269
|
+
} else {
|
|
1270
|
+
throw new Error(`Cannot serialize value of type ${typeof value} as Bytes`);
|
|
1271
|
+
}
|
|
1272
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.BytesArray:
|
|
1273
|
+
if (!Array.isArray(value)) {
|
|
1274
|
+
throw new Error(`Cannot serialize value of type ${typeof value} as BytesArray`);
|
|
1275
|
+
}
|
|
1276
|
+
return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Bytes));
|
|
1277
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.Boolean:
|
|
1278
|
+
switch (typeof value) {
|
|
1279
|
+
case "boolean":
|
|
1280
|
+
return value;
|
|
1281
|
+
case "string":
|
|
1282
|
+
return value === "true" || value === "1";
|
|
1283
|
+
case "number":
|
|
1284
|
+
return value === 1;
|
|
1285
|
+
default:
|
|
1286
|
+
throw new Error(`Cannot serialize value of type ${typeof value} as Boolean`);
|
|
1287
|
+
}
|
|
1288
|
+
case import_driver_adapter_utils2.ColumnTypeEnum.BooleanArray:
|
|
1289
|
+
if (!Array.isArray(value)) {
|
|
1290
|
+
throw new Error(`Cannot serialize value of type ${typeof value} as BooleanArray`);
|
|
1291
|
+
}
|
|
1292
|
+
return value.map((v) => serializeRawValue(v, import_driver_adapter_utils2.ColumnTypeEnum.Boolean));
|
|
1293
|
+
default:
|
|
1294
|
+
return value;
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
901
1297
|
function serializeColumnType(columnType) {
|
|
902
1298
|
switch (columnType) {
|
|
903
1299
|
case import_driver_adapter_utils2.ColumnTypeEnum.Int32:
|
|
@@ -1042,7 +1438,7 @@ function getErrorCode2(error) {
|
|
|
1042
1438
|
}
|
|
1043
1439
|
}
|
|
1044
1440
|
|
|
1045
|
-
// src/interpreter/
|
|
1441
|
+
// src/interpreter/query-interpreter.ts
|
|
1046
1442
|
var QueryInterpreter = class _QueryInterpreter {
|
|
1047
1443
|
#transactionManager;
|
|
1048
1444
|
#placeholderValues;
|
|
@@ -1052,6 +1448,7 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
1052
1448
|
#serializer;
|
|
1053
1449
|
#rawSerializer;
|
|
1054
1450
|
#provider;
|
|
1451
|
+
#connectioInfo;
|
|
1055
1452
|
constructor({
|
|
1056
1453
|
transactionManager,
|
|
1057
1454
|
placeholderValues,
|
|
@@ -1059,7 +1456,8 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
1059
1456
|
tracingHelper,
|
|
1060
1457
|
serializer,
|
|
1061
1458
|
rawSerializer,
|
|
1062
|
-
provider
|
|
1459
|
+
provider,
|
|
1460
|
+
connectionInfo
|
|
1063
1461
|
}) {
|
|
1064
1462
|
this.#transactionManager = transactionManager;
|
|
1065
1463
|
this.#placeholderValues = placeholderValues;
|
|
@@ -1068,6 +1466,7 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
1068
1466
|
this.#serializer = serializer;
|
|
1069
1467
|
this.#rawSerializer = rawSerializer ?? serializer;
|
|
1070
1468
|
this.#provider = provider;
|
|
1469
|
+
this.#connectioInfo = connectionInfo;
|
|
1071
1470
|
}
|
|
1072
1471
|
static forSql(options) {
|
|
1073
1472
|
return new _QueryInterpreter({
|
|
@@ -1077,7 +1476,8 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
1077
1476
|
tracingHelper: options.tracingHelper,
|
|
1078
1477
|
serializer: serializeSql,
|
|
1079
1478
|
rawSerializer: serializeRawSql,
|
|
1080
|
-
provider: options.provider
|
|
1479
|
+
provider: options.provider,
|
|
1480
|
+
connectionInfo: options.connectionInfo
|
|
1081
1481
|
});
|
|
1082
1482
|
}
|
|
1083
1483
|
async run(queryPlan, queryable) {
|
|
@@ -1138,21 +1538,41 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
1138
1538
|
};
|
|
1139
1539
|
}
|
|
1140
1540
|
case "execute": {
|
|
1141
|
-
const
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1541
|
+
const queries = renderQuery(node.args, scope, generators, this.#maxChunkSize());
|
|
1542
|
+
let sum = 0;
|
|
1543
|
+
for (const query of queries) {
|
|
1544
|
+
sum += await this.#withQuerySpanAndEvent(
|
|
1545
|
+
query,
|
|
1546
|
+
queryable,
|
|
1547
|
+
() => queryable.executeRaw(query).catch(
|
|
1548
|
+
(err) => node.args.type === "rawSql" ? rethrowAsUserFacingRawError(err) : rethrowAsUserFacing(err)
|
|
1549
|
+
)
|
|
1550
|
+
);
|
|
1551
|
+
}
|
|
1552
|
+
return { value: sum };
|
|
1145
1553
|
}
|
|
1146
1554
|
case "query": {
|
|
1147
|
-
const
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1555
|
+
const queries = renderQuery(node.args, scope, generators, this.#maxChunkSize());
|
|
1556
|
+
let results;
|
|
1557
|
+
for (const query of queries) {
|
|
1558
|
+
const result = await this.#withQuerySpanAndEvent(
|
|
1559
|
+
query,
|
|
1560
|
+
queryable,
|
|
1561
|
+
() => queryable.queryRaw(query).catch(
|
|
1562
|
+
(err) => node.args.type === "rawSql" ? rethrowAsUserFacingRawError(err) : rethrowAsUserFacing(err)
|
|
1563
|
+
)
|
|
1564
|
+
);
|
|
1565
|
+
if (results === void 0) {
|
|
1566
|
+
results = result;
|
|
1152
1567
|
} else {
|
|
1153
|
-
|
|
1568
|
+
results.rows.push(...result.rows);
|
|
1569
|
+
results.lastInsertId = result.lastInsertId;
|
|
1154
1570
|
}
|
|
1155
|
-
}
|
|
1571
|
+
}
|
|
1572
|
+
return {
|
|
1573
|
+
value: node.args.type === "rawSql" ? this.#rawSerializer(results) : this.#serializer(results),
|
|
1574
|
+
lastInsertId: results?.lastInsertId
|
|
1575
|
+
};
|
|
1156
1576
|
}
|
|
1157
1577
|
case "reverse": {
|
|
1158
1578
|
const { value, lastInsertId } = await this.interpretNode(node.args, queryable, scope, generators);
|
|
@@ -1231,43 +1651,12 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
1231
1651
|
case "diff": {
|
|
1232
1652
|
const { value: from } = await this.interpretNode(node.args.from, queryable, scope, generators);
|
|
1233
1653
|
const { value: to } = await this.interpretNode(node.args.to, queryable, scope, generators);
|
|
1234
|
-
const toSet = new Set(asList(to));
|
|
1235
|
-
return { value: asList(from).filter((item) => !toSet.has(item)) };
|
|
1236
|
-
}
|
|
1237
|
-
case "distinctBy": {
|
|
1238
|
-
const { value, lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
|
|
1239
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1240
|
-
const result = [];
|
|
1241
|
-
for (const item of asList(value)) {
|
|
1242
|
-
const key = getRecordKey(item, node.args.fields);
|
|
1243
|
-
if (!seen.has(key)) {
|
|
1244
|
-
seen.add(key);
|
|
1245
|
-
result.push(item);
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
return { value: result, lastInsertId };
|
|
1654
|
+
const toSet = new Set(asList(to).map((item) => JSON.stringify(item)));
|
|
1655
|
+
return { value: asList(from).filter((item) => !toSet.has(JSON.stringify(item))) };
|
|
1249
1656
|
}
|
|
1250
|
-
case "
|
|
1657
|
+
case "process": {
|
|
1251
1658
|
const { value, lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
|
|
1252
|
-
|
|
1253
|
-
const linkingFields = node.args.pagination.linkingFields;
|
|
1254
|
-
if (linkingFields !== null) {
|
|
1255
|
-
const groupedByParent = /* @__PURE__ */ new Map();
|
|
1256
|
-
for (const item of list) {
|
|
1257
|
-
const parentKey = getRecordKey(item, linkingFields);
|
|
1258
|
-
if (!groupedByParent.has(parentKey)) {
|
|
1259
|
-
groupedByParent.set(parentKey, []);
|
|
1260
|
-
}
|
|
1261
|
-
groupedByParent.get(parentKey).push(item);
|
|
1262
|
-
}
|
|
1263
|
-
const groupList = Array.from(groupedByParent.entries());
|
|
1264
|
-
groupList.sort(([aId], [bId]) => aId < bId ? -1 : aId > bId ? 1 : 0);
|
|
1265
|
-
return {
|
|
1266
|
-
value: groupList.flatMap(([, elems]) => paginate(elems, node.args.pagination)),
|
|
1267
|
-
lastInsertId
|
|
1268
|
-
};
|
|
1269
|
-
}
|
|
1270
|
-
return { value: paginate(list, node.args.pagination), lastInsertId };
|
|
1659
|
+
return { value: processRecords(value, node.args.operations), lastInsertId };
|
|
1271
1660
|
}
|
|
1272
1661
|
case "initializeRecord": {
|
|
1273
1662
|
const { lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
|
|
@@ -1289,6 +1678,34 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
1289
1678
|
assertNever(node, `Unexpected node type: ${node.type}`);
|
|
1290
1679
|
}
|
|
1291
1680
|
}
|
|
1681
|
+
#maxChunkSize() {
|
|
1682
|
+
if (this.#connectioInfo?.maxBindValues !== void 0) {
|
|
1683
|
+
return this.#connectioInfo.maxBindValues;
|
|
1684
|
+
}
|
|
1685
|
+
return this.#providerMaxChunkSize();
|
|
1686
|
+
}
|
|
1687
|
+
#providerMaxChunkSize() {
|
|
1688
|
+
if (this.#provider === void 0) {
|
|
1689
|
+
return void 0;
|
|
1690
|
+
}
|
|
1691
|
+
switch (this.#provider) {
|
|
1692
|
+
case "cockroachdb":
|
|
1693
|
+
case "postgres":
|
|
1694
|
+
case "postgresql":
|
|
1695
|
+
case "prisma+postgres":
|
|
1696
|
+
return 32766;
|
|
1697
|
+
case "mysql":
|
|
1698
|
+
return 65535;
|
|
1699
|
+
case "sqlite":
|
|
1700
|
+
return 999;
|
|
1701
|
+
case "sqlserver":
|
|
1702
|
+
return 2098;
|
|
1703
|
+
case "mongodb":
|
|
1704
|
+
return void 0;
|
|
1705
|
+
default:
|
|
1706
|
+
assertNever(this.#provider, `Unexpected provider: ${this.#provider}`);
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1292
1709
|
#withQuerySpanAndEvent(query, queryable, execute) {
|
|
1293
1710
|
return withQuerySpanAndEvent({
|
|
1294
1711
|
query,
|
|
@@ -1366,18 +1783,6 @@ function attachChildrenToParents(parentRecords, children) {
|
|
|
1366
1783
|
}
|
|
1367
1784
|
return parentRecords;
|
|
1368
1785
|
}
|
|
1369
|
-
function paginate(list, { cursor, skip, take }) {
|
|
1370
|
-
const cursorIndex = cursor !== null ? list.findIndex((item) => doKeysMatch(item, cursor)) : 0;
|
|
1371
|
-
if (cursorIndex === -1) {
|
|
1372
|
-
return [];
|
|
1373
|
-
}
|
|
1374
|
-
const start = cursorIndex + (skip ?? 0);
|
|
1375
|
-
const end = take !== null ? start + take : list.length;
|
|
1376
|
-
return list.slice(start, end);
|
|
1377
|
-
}
|
|
1378
|
-
function getRecordKey(record, fields) {
|
|
1379
|
-
return JSON.stringify(fields.map((field) => record[field]));
|
|
1380
|
-
}
|
|
1381
1786
|
function evalFieldInitializer(initializer, lastInsertId, scope, generators) {
|
|
1382
1787
|
switch (initializer.type) {
|
|
1383
1788
|
case "value":
|
|
@@ -1411,54 +1816,36 @@ function evalFieldOperation(op, value, scope, generators) {
|
|
|
1411
1816
|
}
|
|
1412
1817
|
}
|
|
1413
1818
|
|
|
1414
|
-
// src/json-protocol.ts
|
|
1415
|
-
var
|
|
1416
|
-
function
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
return result.map(normalizeJsonProtocolValues);
|
|
1422
|
-
}
|
|
1423
|
-
if (typeof result === "object") {
|
|
1424
|
-
if (isTaggedValue(result)) {
|
|
1425
|
-
return normalizeTaggedValue(result);
|
|
1426
|
-
}
|
|
1427
|
-
if (result.constructor !== null && result.constructor.name !== "Object") {
|
|
1428
|
-
return result;
|
|
1819
|
+
// src/raw-json-protocol.ts
|
|
1820
|
+
var import_decimal4 = __toESM(require("decimal.js"));
|
|
1821
|
+
function normalizeRawJsonProtocolResponse(response) {
|
|
1822
|
+
for (let i = 0; i < response.rows.length; i++) {
|
|
1823
|
+
const row = response.rows[i];
|
|
1824
|
+
for (let j = 0; j < row.length; j++) {
|
|
1825
|
+
row[j] = normalizeValue(response.types[j], row[j]);
|
|
1429
1826
|
}
|
|
1430
|
-
return mapObjectValues(result, normalizeJsonProtocolValues);
|
|
1431
1827
|
}
|
|
1432
|
-
return
|
|
1433
|
-
}
|
|
1434
|
-
function isTaggedValue(value) {
|
|
1435
|
-
return value !== null && typeof value == "object" && typeof value["$type"] === "string";
|
|
1828
|
+
return response;
|
|
1436
1829
|
}
|
|
1437
|
-
function
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
return { $type, value: String(value) };
|
|
1441
|
-
case "Bytes":
|
|
1442
|
-
return { $type, value };
|
|
1443
|
-
case "DateTime":
|
|
1444
|
-
return { $type, value: new Date(value).toISOString() };
|
|
1445
|
-
case "Decimal":
|
|
1446
|
-
return { $type, value: String(new import_decimal3.Decimal(value)) };
|
|
1447
|
-
case "Json":
|
|
1448
|
-
return { $type, value: JSON.stringify(JSON.parse(value)) };
|
|
1449
|
-
default:
|
|
1450
|
-
assertNever(value, "Unknown tagged value");
|
|
1830
|
+
function normalizeValue(type, value) {
|
|
1831
|
+
if (value === null) {
|
|
1832
|
+
return value;
|
|
1451
1833
|
}
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1834
|
+
switch (type) {
|
|
1835
|
+
case "bigint":
|
|
1836
|
+
return String(BigInt(value));
|
|
1837
|
+
case "decimal":
|
|
1838
|
+
return String(new import_decimal4.default(value));
|
|
1839
|
+
case "bigint-array":
|
|
1840
|
+
return value.map((v) => normalizeValue("bigint", v));
|
|
1841
|
+
case "decimal-array":
|
|
1842
|
+
return value.map((v) => normalizeValue("decimal", v));
|
|
1843
|
+
default:
|
|
1844
|
+
return value;
|
|
1457
1845
|
}
|
|
1458
|
-
return result;
|
|
1459
1846
|
}
|
|
1460
1847
|
|
|
1461
|
-
// src/
|
|
1848
|
+
// src/transaction-manager/transaction-manager.ts
|
|
1462
1849
|
var import_debug = require("@prisma/debug");
|
|
1463
1850
|
|
|
1464
1851
|
// src/crypto.ts
|
|
@@ -1470,7 +1857,7 @@ async function randomUUID() {
|
|
|
1470
1857
|
return crypto.randomUUID();
|
|
1471
1858
|
}
|
|
1472
1859
|
|
|
1473
|
-
// src/
|
|
1860
|
+
// src/transaction-manager/transaction-manager-error.ts
|
|
1474
1861
|
var TransactionManagerError = class extends UserFacingError {
|
|
1475
1862
|
name = "TransactionManagerError";
|
|
1476
1863
|
constructor(message, meta) {
|
|
@@ -1507,7 +1894,7 @@ var TransactionStartTimeoutError = class extends TransactionManagerError {
|
|
|
1507
1894
|
var TransactionExecutionTimeoutError = class extends TransactionManagerError {
|
|
1508
1895
|
constructor(operation, { timeout, timeTaken }) {
|
|
1509
1896
|
super(
|
|
1510
|
-
`A ${operation} cannot be executed on an expired transaction. The timeout for this transaction was ${timeout} ms, however ${timeTaken} ms passed since the start of the transaction. Consider increasing the interactive transaction timeout or doing less work in the transaction
|
|
1897
|
+
`A ${operation} cannot be executed on an expired transaction. The timeout for this transaction was ${timeout} ms, however ${timeTaken} ms passed since the start of the transaction. Consider increasing the interactive transaction timeout or doing less work in the transaction.`,
|
|
1511
1898
|
{ operation, timeout, timeTaken }
|
|
1512
1899
|
);
|
|
1513
1900
|
}
|
|
@@ -1523,7 +1910,7 @@ var InvalidTransactionIsolationLevelError = class extends TransactionManagerErro
|
|
|
1523
1910
|
}
|
|
1524
1911
|
};
|
|
1525
1912
|
|
|
1526
|
-
// src/
|
|
1913
|
+
// src/transaction-manager/transaction-manager.ts
|
|
1527
1914
|
var MAX_CLOSED_TRANSACTIONS = 100;
|
|
1528
1915
|
var debug = (0, import_debug.Debug)("prisma:client:transactionManager");
|
|
1529
1916
|
var COMMIT_QUERY = () => ({ sql: "COMMIT", args: [], argTypes: [] });
|
|
@@ -1578,7 +1965,7 @@ var TransactionManager = class {
|
|
|
1578
1965
|
this.transactions.set(transaction.id, transaction);
|
|
1579
1966
|
let hasTimedOut = false;
|
|
1580
1967
|
const startTimer = setTimeout(() => hasTimedOut = true, validatedOptions.maxWait);
|
|
1581
|
-
transaction.transaction = await this.driverAdapter.startTransaction(validatedOptions.isolationLevel);
|
|
1968
|
+
transaction.transaction = await this.driverAdapter.startTransaction(validatedOptions.isolationLevel).catch(rethrowAsUserFacing);
|
|
1582
1969
|
clearTimeout(startTimer);
|
|
1583
1970
|
switch (transaction.status) {
|
|
1584
1971
|
case "waiting":
|
|
@@ -1726,6 +2113,8 @@ var TransactionManager = class {
|
|
|
1726
2113
|
TransactionManager,
|
|
1727
2114
|
TransactionManagerError,
|
|
1728
2115
|
UserFacingError,
|
|
2116
|
+
convertCompactedRows,
|
|
2117
|
+
deserializeJsonResponse,
|
|
1729
2118
|
doKeysMatch,
|
|
1730
2119
|
isDeepStrictEqual,
|
|
1731
2120
|
isPrismaValueBigInt,
|
|
@@ -1734,5 +2123,6 @@ var TransactionManager = class {
|
|
|
1734
2123
|
isPrismaValuePlaceholder,
|
|
1735
2124
|
noopTracingHelper,
|
|
1736
2125
|
normalizeJsonProtocolValues,
|
|
2126
|
+
normalizeRawJsonProtocolResponse,
|
|
1737
2127
|
safeJsonStringify
|
|
1738
2128
|
});
|