@prisma/client-engine-runtime 6.6.0-dev.9 → 6.6.0-dev.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,121 +1,119 @@
1
- var __defProp = Object.defineProperty;
2
- var __typeError = (msg) => {
3
- throw TypeError(msg);
1
+ // src/interpreter/generators.ts
2
+ import cuid1 from "@bugsnag/cuid";
3
+ import { createId as cuid2 } from "@paralleldrive/cuid2";
4
+ import { nanoid } from "nanoid";
5
+ import { ulid } from "ulid";
6
+ import { v4 as uuidv4, v7 as uuidv7 } from "uuid";
7
+ var GeneratorRegistry = class {
8
+ #generators = {};
9
+ constructor() {
10
+ this.register("now", new NowGenerator());
11
+ this.register("uuid", new UuidGenerator());
12
+ this.register("cuid", new CuidGenerator());
13
+ this.register("ulid", new UlidGenerator());
14
+ this.register("nanoid", new NanoIdGenerator());
15
+ }
16
+ /**
17
+ * Returns a snapshot of the generator registry. It's 'frozen' in time at the moment of this
18
+ * method being called, meaning that the built-in time-based generators will always return
19
+ * the same value on repeated calls as long as the same snapshot is used.
20
+ */
21
+ snapshot() {
22
+ return Object.create(this.#generators, {
23
+ now: { value: new NowGenerator() }
24
+ });
25
+ }
26
+ /**
27
+ * Registers a new generator with the given name.
28
+ */
29
+ register(name, generator) {
30
+ this.#generators[name] = generator;
31
+ }
32
+ };
33
+ var NowGenerator = class {
34
+ #now = /* @__PURE__ */ new Date();
35
+ generate() {
36
+ return this.#now.toISOString();
37
+ }
38
+ };
39
+ var UuidGenerator = class {
40
+ generate(arg) {
41
+ if (arg === 4) {
42
+ return uuidv4();
43
+ } else if (arg === 7) {
44
+ return uuidv7();
45
+ } else {
46
+ throw new Error("Invalid UUID generator arguments");
47
+ }
48
+ }
49
+ };
50
+ var CuidGenerator = class {
51
+ generate(arg) {
52
+ if (arg === 1) {
53
+ return cuid1();
54
+ } else if (arg === 2) {
55
+ return cuid2();
56
+ } else {
57
+ throw new Error("Invalid CUID generator arguments");
58
+ }
59
+ }
60
+ };
61
+ var UlidGenerator = class {
62
+ generate() {
63
+ return ulid();
64
+ }
65
+ };
66
+ var NanoIdGenerator = class {
67
+ generate(arg) {
68
+ if (typeof arg === "number") {
69
+ return nanoid(arg);
70
+ } else if (arg === void 0) {
71
+ return nanoid();
72
+ } else {
73
+ throw new Error("Invalid Nanoid generator arguments");
74
+ }
75
+ }
4
76
  };
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
8
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
9
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
10
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
11
- var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
12
77
 
13
78
  // src/QueryPlan.ts
14
79
  function isPrismaValuePlaceholder(value) {
15
80
  return typeof value === "object" && value !== null && value["prisma__type"] === "param";
16
81
  }
82
+ function isPrismaValueGenerator(value) {
83
+ return typeof value === "object" && value !== null && value["prisma__type"] === "generatorCall";
84
+ }
17
85
 
18
- // src/interpreter/renderQueryTemplate.ts
19
- var BEGIN_REPEAT = "/* prisma-comma-repeatable-start */";
20
- var END_REPEAT = "/* prisma-comma-repeatable-end */";
21
- function renderQueryTemplate({
22
- query,
23
- params
24
- }) {
25
- if (!query.includes(BEGIN_REPEAT)) {
26
- return { query, params };
27
- }
28
- const flattenedParams = [];
29
- let lastParamId = 1;
30
- let result = "";
31
- let templatePos = 0;
32
- let state = 0 /* Normal */;
33
- let stateBeforeQuote = 0 /* Normal */;
34
- while (templatePos < query.length) {
35
- const nextChar = query[templatePos];
36
- if (state === 1 /* Quoted */ && nextChar !== '"') {
37
- result += nextChar;
38
- templatePos++;
39
- continue;
40
- }
41
- if (nextChar === '"') {
42
- if (state === 1 /* Quoted */) {
43
- state = stateBeforeQuote;
44
- } else {
45
- stateBeforeQuote = state;
46
- state = 1 /* Quoted */;
47
- }
48
- result += nextChar;
49
- templatePos++;
50
- continue;
51
- }
52
- if (query.slice(templatePos, templatePos + BEGIN_REPEAT.length) === BEGIN_REPEAT) {
53
- if (state === 2 /* Repeating */) {
54
- throw new Error("Nested repetition is not allowed");
55
- }
56
- state = 2 /* Repeating */;
57
- templatePos += BEGIN_REPEAT.length;
58
- result += "(";
59
- continue;
60
- }
61
- if (query.slice(templatePos, templatePos + END_REPEAT.length) === END_REPEAT) {
62
- if (state === 0 /* Normal */) {
63
- throw new Error("Unmatched repetition end");
64
- }
65
- state = 0 /* Normal */;
66
- templatePos += END_REPEAT.length;
67
- result += ")";
68
- continue;
69
- }
70
- if (nextChar === "$") {
71
- const paramMatch = query.slice(templatePos + 1).match(/^\d+/);
72
- if (!paramMatch) {
73
- result += "$";
74
- templatePos++;
75
- continue;
76
- }
77
- templatePos += paramMatch[0].length + 1;
78
- const originalParamIdx = parseInt(paramMatch[0]);
79
- const paramValue = params[originalParamIdx - 1];
80
- switch (state) {
81
- case 0 /* Normal */: {
82
- flattenedParams.push(paramValue);
83
- result += `$${lastParamId++}`;
84
- break;
85
- }
86
- case 2 /* Repeating */: {
87
- const paramArray = Array.isArray(paramValue) ? paramValue : [paramValue];
88
- if (paramArray.length === 0) {
89
- result += "NULL";
90
- break;
91
- }
92
- paramArray.forEach((value, idx) => {
93
- flattenedParams.push(value);
94
- result += `$${lastParamId++}`;
95
- if (idx !== paramArray.length - 1) {
96
- result += ", ";
97
- }
98
- });
99
- break;
100
- }
101
- default: {
102
- throw new Error(`Unexpected state: ${state}`);
103
- }
104
- }
105
- continue;
106
- }
107
- result += nextChar;
108
- templatePos++;
109
- }
110
- return {
111
- query: result,
112
- params: flattenedParams
113
- };
86
+ // src/utils.ts
87
+ function assertNever(_, message) {
88
+ throw new Error(message);
114
89
  }
115
90
 
116
91
  // src/interpreter/renderQuery.ts
117
- function renderQuery({ query, params }, scope) {
118
- const substitutedParams = params.map((param) => {
92
+ function renderQuery(dbQuery, scope, generators) {
93
+ const queryType = dbQuery.type;
94
+ switch (queryType) {
95
+ case "rawSql":
96
+ return renderRawSql(dbQuery.sql, substituteParams(dbQuery.params, scope, generators));
97
+ case "templateSql":
98
+ return renderTemplateSql(
99
+ dbQuery.fragments,
100
+ dbQuery.placeholderFormat,
101
+ substituteParams(dbQuery.params, scope, generators)
102
+ );
103
+ default:
104
+ assertNever(queryType, `Invalid query type`);
105
+ }
106
+ }
107
+ function substituteParams(params, scope, generators) {
108
+ return params.map((param) => {
109
+ if (isPrismaValueGenerator(param)) {
110
+ const { name, args } = param.prisma__value;
111
+ const generator = generators[name];
112
+ if (!generator) {
113
+ throw new Error(`Encountered an unknown generator '${name}'`);
114
+ }
115
+ return generator.generate(...args);
116
+ }
119
117
  if (!isPrismaValuePlaceholder(param)) {
120
118
  return param;
121
119
  }
@@ -125,11 +123,48 @@ function renderQuery({ query, params }, scope) {
125
123
  }
126
124
  return value;
127
125
  });
128
- const { query: renderedQuery, params: expandedParams } = renderQueryTemplate({ query, params: substitutedParams });
129
- const argTypes = expandedParams.map((param) => toArgType(param));
126
+ }
127
+ function renderTemplateSql(fragments, placeholderFormat, params) {
128
+ let paramIndex = 0;
129
+ let placeholderNumber = 1;
130
+ const flattenedParams = [];
131
+ const sql = fragments.map((fragment) => {
132
+ const fragmentType = fragment.type;
133
+ switch (fragmentType) {
134
+ case "parameter":
135
+ if (paramIndex >= params.length) {
136
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
137
+ }
138
+ flattenedParams.push(params[paramIndex++]);
139
+ return formatPlaceholder(placeholderFormat, placeholderNumber++);
140
+ case "stringChunk":
141
+ return fragment.value;
142
+ case "parameterTuple": {
143
+ if (paramIndex >= params.length) {
144
+ throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
145
+ }
146
+ const paramValue = params[paramIndex++];
147
+ const paramArray = Array.isArray(paramValue) ? paramValue : [paramValue];
148
+ const placeholders = paramArray.length == 0 ? "NULL" : paramArray.map((value) => {
149
+ flattenedParams.push(value);
150
+ return formatPlaceholder(placeholderFormat, placeholderNumber++);
151
+ }).join(",");
152
+ return `(${placeholders})`;
153
+ }
154
+ default:
155
+ assertNever(fragmentType, "Invalid fragment type");
156
+ }
157
+ }).join("");
158
+ return renderRawSql(sql, flattenedParams);
159
+ }
160
+ function formatPlaceholder(placeholderFormat, placeholderNumber) {
161
+ return placeholderFormat.hasNumbering ? `${placeholderFormat.prefix}${placeholderNumber}` : placeholderFormat.prefix;
162
+ }
163
+ function renderRawSql(sql, params) {
164
+ const argTypes = params.map((param) => toArgType(param));
130
165
  return {
131
- sql: renderedQuery,
132
- args: expandedParams,
166
+ sql,
167
+ args: params,
133
168
  argTypes
134
169
  };
135
170
  }
@@ -198,24 +233,23 @@ function serialize(resultSet) {
198
233
  }
199
234
 
200
235
  // src/interpreter/QueryInterpreter.ts
201
- var _queryable, _placeholderValues, _onQuery, _QueryInterpreter_instances, withQueryEvent_fn;
202
236
  var QueryInterpreter = class {
203
- constructor({ queryable, placeholderValues, onQuery }) {
204
- __privateAdd(this, _QueryInterpreter_instances);
205
- __privateAdd(this, _queryable);
206
- __privateAdd(this, _placeholderValues);
207
- __privateAdd(this, _onQuery);
208
- __privateSet(this, _queryable, queryable);
209
- __privateSet(this, _placeholderValues, placeholderValues);
210
- __privateSet(this, _onQuery, onQuery);
211
- }
212
- async run(queryPlan) {
213
- return this.interpretNode(queryPlan, __privateGet(this, _placeholderValues));
214
- }
215
- async interpretNode(node, scope) {
237
+ #transactionManager;
238
+ #placeholderValues;
239
+ #onQuery;
240
+ #generators = new GeneratorRegistry();
241
+ constructor({ transactionManager, placeholderValues, onQuery }) {
242
+ this.#transactionManager = transactionManager;
243
+ this.#placeholderValues = placeholderValues;
244
+ this.#onQuery = onQuery;
245
+ }
246
+ async run(queryPlan, queryable) {
247
+ return this.interpretNode(queryPlan, queryable, this.#placeholderValues, this.#generators.snapshot());
248
+ }
249
+ async interpretNode(node, queryable, scope, generators) {
216
250
  switch (node.type) {
217
251
  case "seq": {
218
- const results = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope)));
252
+ const results = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
219
253
  return results[results.length - 1];
220
254
  }
221
255
  case "get": {
@@ -225,10 +259,10 @@ var QueryInterpreter = class {
225
259
  const nestedScope = Object.create(scope);
226
260
  await Promise.all(
227
261
  node.args.bindings.map(async (binding) => {
228
- nestedScope[binding.name] = await this.interpretNode(binding.expr, scope);
262
+ nestedScope[binding.name] = await this.interpretNode(binding.expr, queryable, scope, generators);
229
263
  })
230
264
  );
231
- return this.interpretNode(node.args.expr, nestedScope);
265
+ return this.interpretNode(node.args.expr, queryable, nestedScope, generators);
232
266
  }
233
267
  case "getFirstNonEmpty": {
234
268
  for (const name of node.args.names) {
@@ -240,41 +274,31 @@ var QueryInterpreter = class {
240
274
  return [];
241
275
  }
242
276
  case "concat": {
243
- const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope)));
277
+ const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
244
278
  return parts.reduce((acc, part) => acc.concat(asList(part)), []);
245
279
  }
246
280
  case "sum": {
247
- const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope)));
281
+ const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
248
282
  return parts.reduce((acc, part) => asNumber(acc) + asNumber(part));
249
283
  }
250
284
  case "execute": {
251
- const query = renderQuery(node.args, scope);
252
- return __privateMethod(this, _QueryInterpreter_instances, withQueryEvent_fn).call(this, query, async () => {
253
- const result = await __privateGet(this, _queryable).executeRaw(query);
254
- if (result.ok) {
255
- return result.value;
256
- } else {
257
- throw result.error;
258
- }
285
+ const query = renderQuery(node.args, scope, generators);
286
+ return this.#withQueryEvent(query, async () => {
287
+ return await queryable.executeRaw(query);
259
288
  });
260
289
  }
261
290
  case "query": {
262
- const query = renderQuery(node.args, scope);
263
- return __privateMethod(this, _QueryInterpreter_instances, withQueryEvent_fn).call(this, query, async () => {
264
- const result = await __privateGet(this, _queryable).queryRaw(query);
265
- if (result.ok) {
266
- return serialize(result.value);
267
- } else {
268
- throw result.error;
269
- }
291
+ const query = renderQuery(node.args, scope, generators);
292
+ return this.#withQueryEvent(query, async () => {
293
+ return serialize(await queryable.queryRaw(query));
270
294
  });
271
295
  }
272
296
  case "reverse": {
273
- const value = await this.interpretNode(node.args, scope);
297
+ const value = await this.interpretNode(node.args, queryable, scope, generators);
274
298
  return Array.isArray(value) ? value.reverse() : value;
275
299
  }
276
300
  case "unique": {
277
- const value = await this.interpretNode(node.args, scope);
301
+ const value = await this.interpretNode(node.args, queryable, scope, generators);
278
302
  if (!Array.isArray(value)) {
279
303
  return value;
280
304
  }
@@ -284,22 +308,22 @@ var QueryInterpreter = class {
284
308
  return value[0] ?? null;
285
309
  }
286
310
  case "required": {
287
- const value = await this.interpretNode(node.args, scope);
311
+ const value = await this.interpretNode(node.args, queryable, scope, generators);
288
312
  if (isEmpty(value)) {
289
313
  throw new Error("Required value is empty");
290
314
  }
291
315
  return value;
292
316
  }
293
317
  case "mapField": {
294
- const value = await this.interpretNode(node.args.records, scope);
318
+ const value = await this.interpretNode(node.args.records, queryable, scope, generators);
295
319
  return mapField(value, node.args.field);
296
320
  }
297
321
  case "join": {
298
- const parent = await this.interpretNode(node.args.parent, scope);
322
+ const parent = await this.interpretNode(node.args.parent, queryable, scope, generators);
299
323
  const children = await Promise.all(
300
324
  node.args.children.map(async (joinExpr) => ({
301
325
  joinExpr,
302
- childRecords: await this.interpretNode(joinExpr.child, scope)
326
+ childRecords: await this.interpretNode(joinExpr.child, queryable, scope, generators)
303
327
  }))
304
328
  );
305
329
  if (Array.isArray(parent)) {
@@ -310,30 +334,41 @@ var QueryInterpreter = class {
310
334
  }
311
335
  return attachChildrenToParent(asRecord(parent), children);
312
336
  }
337
+ case "transaction": {
338
+ if (!this.#transactionManager.enabled) {
339
+ return this.interpretNode(node.args, queryable, scope, generators);
340
+ }
341
+ const transactionManager = this.#transactionManager.manager;
342
+ const transactionInfo = await transactionManager.startTransaction();
343
+ const transaction = transactionManager.getTransaction(transactionInfo, "new");
344
+ try {
345
+ const value = await this.interpretNode(node.args, transaction, scope, generators);
346
+ await transactionManager.commitTransaction(transactionInfo.id);
347
+ return value;
348
+ } catch (e) {
349
+ await transactionManager.rollbackTransaction(transactionInfo.id);
350
+ throw e;
351
+ }
352
+ }
313
353
  default: {
314
354
  node;
315
355
  throw new Error(`Unexpected node type: ${node.type}`);
316
356
  }
317
357
  }
318
358
  }
319
- };
320
- _queryable = new WeakMap();
321
- _placeholderValues = new WeakMap();
322
- _onQuery = new WeakMap();
323
- _QueryInterpreter_instances = new WeakSet();
324
- withQueryEvent_fn = async function(query, execute) {
325
- var _a;
326
- const timestamp = /* @__PURE__ */ new Date();
327
- const startInstant = performance.now();
328
- const result = await execute();
329
- const endInstant = performance.now();
330
- (_a = __privateGet(this, _onQuery)) == null ? void 0 : _a.call(this, {
331
- timestamp,
332
- duration: endInstant - startInstant,
333
- query: query.sql,
334
- params: query.args
335
- });
336
- return result;
359
+ async #withQueryEvent(query, execute) {
360
+ const timestamp = /* @__PURE__ */ new Date();
361
+ const startInstant = performance.now();
362
+ const result = await execute();
363
+ const endInstant = performance.now();
364
+ this.#onQuery?.({
365
+ timestamp,
366
+ duration: endInstant - startInstant,
367
+ query: query.sql,
368
+ params: query.args
369
+ });
370
+ return result;
371
+ }
337
372
  };
338
373
  function isEmpty(value) {
339
374
  if (Array.isArray(value)) {
@@ -391,22 +426,16 @@ function childRecordMatchesParent(childRecord, parentRecord, joinExpr) {
391
426
  return true;
392
427
  }
393
428
 
394
- // src/transactionManager/Transaction.ts
395
- var IsolationLevel = /* @__PURE__ */ ((IsolationLevel2) => {
396
- IsolationLevel2["ReadUncommitted"] = "ReadUncommitted";
397
- IsolationLevel2["ReadCommitted"] = "ReadCommitted";
398
- IsolationLevel2["RepeatableRead"] = "RepeatableRead";
399
- IsolationLevel2["Snapshot"] = "Snapshot";
400
- IsolationLevel2["Serializable"] = "Serializable";
401
- return IsolationLevel2;
402
- })(IsolationLevel || {});
403
-
404
429
  // src/transactionManager/TransactionManager.ts
405
- import Debug from "@prisma/debug";
430
+ import { Debug } from "@prisma/debug";
406
431
 
407
- // src/utils.ts
408
- function assertNever(_, message) {
409
- throw new Error(message);
432
+ // src/crypto.ts
433
+ async function getCrypto() {
434
+ return globalThis.crypto ?? await import("node:crypto");
435
+ }
436
+ async function randomUUID() {
437
+ const crypto = await getCrypto();
438
+ return crypto.randomUUID();
410
439
  }
411
440
 
412
441
  // src/transactionManager/TransactionManagerErrors.ts
@@ -414,8 +443,8 @@ var TransactionManagerError = class extends Error {
414
443
  constructor(message, meta) {
415
444
  super("Transaction API error: " + message);
416
445
  this.meta = meta;
417
- __publicField(this, "code", "P2028");
418
446
  }
447
+ code = "P2028";
419
448
  };
420
449
  var TransactionDriverAdapterError = class extends TransactionManagerError {
421
450
  constructor(message, errorParams) {
@@ -465,35 +494,25 @@ var InvalidTransactionIsolationLevelError = class extends TransactionManagerErro
465
494
 
466
495
  // src/transactionManager/TransactionManager.ts
467
496
  var MAX_CLOSED_TRANSACTIONS = 100;
468
- var isolationLevelMap = {
469
- ReadUncommitted: "READ UNCOMMITTED",
470
- ReadCommitted: "READ COMMITTED",
471
- RepeatableRead: "REPEATABLE READ",
472
- Snapshot: "SNAPSHOT",
473
- Serializable: "SERIALIZABLE"
474
- };
475
497
  var debug = Debug("prisma:client:transactionManager");
476
498
  var COMMIT_QUERY = () => ({ sql: "COMMIT", args: [], argTypes: [] });
477
499
  var ROLLBACK_QUERY = () => ({ sql: "ROLLBACK", args: [], argTypes: [] });
478
- var ISOLATION_LEVEL_QUERY = (isolationLevel) => ({
479
- sql: "SET TRANSACTION ISOLATION LEVEL " + isolationLevelMap[isolationLevel],
480
- args: [],
481
- argTypes: []
482
- });
483
500
  var TransactionManager = class {
484
- constructor({ driverAdapter }) {
485
- // The map of active transactions.
486
- __publicField(this, "transactions", /* @__PURE__ */ new Map());
487
- // List of last closed transactions. Max MAX_CLOSED_TRANSACTIONS entries.
488
- // Used to provide better error messages than a generic "transaction not found".
489
- __publicField(this, "closedTransactions", []);
490
- __publicField(this, "driverAdapter");
501
+ // The map of active transactions.
502
+ transactions = /* @__PURE__ */ new Map();
503
+ // List of last closed transactions. Max MAX_CLOSED_TRANSACTIONS entries.
504
+ // Used to provide better error messages than a generic "transaction not found".
505
+ closedTransactions = [];
506
+ driverAdapter;
507
+ transactionOptions;
508
+ constructor({ driverAdapter, transactionOptions }) {
491
509
  this.driverAdapter = driverAdapter;
510
+ this.transactionOptions = transactionOptions;
492
511
  }
493
512
  async startTransaction(options) {
494
- const validatedOptions = this.validateOptions(options);
513
+ const validatedOptions = options !== void 0 ? this.validateOptions(options) : this.transactionOptions;
495
514
  const transaction = {
496
- id: globalThis.crypto.randomUUID(),
515
+ id: await randomUUID(),
497
516
  status: "waiting",
498
517
  timer: void 0,
499
518
  timeout: validatedOptions.timeout,
@@ -502,28 +521,17 @@ var TransactionManager = class {
502
521
  };
503
522
  this.transactions.set(transaction.id, transaction);
504
523
  transaction.timer = this.startTransactionTimeout(transaction.id, validatedOptions.maxWait);
505
- const txContext = await this.driverAdapter.transactionContext();
506
- if (!txContext.ok)
524
+ let startedTransaction;
525
+ try {
526
+ startedTransaction = await this.driverAdapter.startTransaction(validatedOptions.isolationLevel);
527
+ } catch (error) {
507
528
  throw new TransactionDriverAdapterError("Failed to start transaction.", {
508
- driverAdapterError: txContext.error
529
+ driverAdapterError: error
509
530
  });
510
- if (this.requiresSettingIsolationLevelFirst() && validatedOptions.isolationLevel) {
511
- await txContext.value.executeRaw(ISOLATION_LEVEL_QUERY(validatedOptions.isolationLevel));
512
- }
513
- const startedTransaction = await txContext.value.startTransaction();
514
- if (!startedTransaction.ok)
515
- throw new TransactionDriverAdapterError("Failed to start transaction.", {
516
- driverAdapterError: startedTransaction.error
517
- });
518
- if (!startedTransaction.value.options.usePhantomQuery) {
519
- await startedTransaction.value.executeRaw({ sql: "BEGIN", args: [], argTypes: [] });
520
- if (!this.requiresSettingIsolationLevelFirst() && validatedOptions.isolationLevel) {
521
- await txContext.value.executeRaw(ISOLATION_LEVEL_QUERY(validatedOptions.isolationLevel));
522
- }
523
531
  }
524
532
  switch (transaction.status) {
525
533
  case "waiting":
526
- transaction.transaction = startedTransaction.value;
534
+ transaction.transaction = startedTransaction;
527
535
  clearTimeout(transaction.timer);
528
536
  transaction.timer = void 0;
529
537
  transaction.status = "running";
@@ -603,20 +611,24 @@ var TransactionManager = class {
603
611
  debug("Closing transaction.", { transactionId: tx.id, status });
604
612
  tx.status = status;
605
613
  if (tx.transaction && status === "committed") {
606
- const result = await tx.transaction.commit();
607
- if (!result.ok)
614
+ try {
615
+ await tx.transaction.commit();
616
+ } catch (error) {
608
617
  throw new TransactionDriverAdapterError("Failed to commit transaction.", {
609
- driverAdapterError: result.error
618
+ driverAdapterError: error
610
619
  });
620
+ }
611
621
  if (!tx.transaction.options.usePhantomQuery) {
612
622
  await tx.transaction.executeRaw(COMMIT_QUERY());
613
623
  }
614
624
  } else if (tx.transaction) {
615
- const result = await tx.transaction.rollback();
616
- if (!result.ok)
625
+ try {
626
+ await tx.transaction.rollback();
627
+ } catch (error) {
617
628
  throw new TransactionDriverAdapterError("Failed to rollback transaction.", {
618
- driverAdapterError: result.error
629
+ driverAdapterError: error
619
630
  });
631
+ }
620
632
  if (!tx.transaction.options.usePhantomQuery) {
621
633
  await tx.transaction.executeRaw(ROLLBACK_QUERY());
622
634
  }
@@ -632,24 +644,18 @@ var TransactionManager = class {
632
644
  validateOptions(options) {
633
645
  if (!options.timeout) throw new TransactionManagerError("timeout is required");
634
646
  if (!options.maxWait) throw new TransactionManagerError("maxWait is required");
635
- if (options.isolationLevel === "Snapshot" /* Snapshot */)
636
- throw new InvalidTransactionIsolationLevelError(options.isolationLevel);
637
- if (this.driverAdapter.provider === "sqlite" && options.isolationLevel && options.isolationLevel !== "Serializable" /* Serializable */)
638
- throw new InvalidTransactionIsolationLevelError(options.isolationLevel);
647
+ if (options.isolationLevel === "SNAPSHOT") throw new InvalidTransactionIsolationLevelError(options.isolationLevel);
639
648
  return {
640
649
  ...options,
641
650
  timeout: options.timeout,
642
651
  maxWait: options.maxWait
643
652
  };
644
653
  }
645
- requiresSettingIsolationLevelFirst() {
646
- return this.driverAdapter.provider === "mysql";
647
- }
648
654
  };
649
655
  export {
650
- IsolationLevel,
651
656
  QueryInterpreter,
652
657
  TransactionManager,
653
658
  TransactionManagerError,
659
+ isPrismaValueGenerator,
654
660
  isPrismaValuePlaceholder
655
661
  };
@@ -1,14 +1,21 @@
1
- import { ErrorCapturingSqlQueryable } from '@prisma/driver-adapter-utils';
1
+ import { SqlQueryable } from '@prisma/driver-adapter-utils';
2
2
  import { QueryEvent } from '../events';
3
3
  import { QueryPlanNode } from '../QueryPlan';
4
+ import { type TransactionManager } from '../transactionManager/TransactionManager';
5
+ export type QueryInterpreterTransactionManager = {
6
+ enabled: true;
7
+ manager: TransactionManager;
8
+ } | {
9
+ enabled: false;
10
+ };
4
11
  export type QueryInterpreterOptions = {
5
- queryable: ErrorCapturingSqlQueryable;
12
+ transactionManager: QueryInterpreterTransactionManager;
6
13
  placeholderValues: Record<string, unknown>;
7
14
  onQuery?: (event: QueryEvent) => void;
8
15
  };
9
16
  export declare class QueryInterpreter {
10
17
  #private;
11
- constructor({ queryable, placeholderValues, onQuery }: QueryInterpreterOptions);
12
- run(queryPlan: QueryPlanNode): Promise<unknown>;
18
+ constructor({ transactionManager, placeholderValues, onQuery }: QueryInterpreterOptions);
19
+ run(queryPlan: QueryPlanNode, queryable: SqlQueryable): Promise<unknown>;
13
20
  private interpretNode;
14
21
  }