@vsrepo/prisma7-adapter 1.3.2 → 2.0.0-dev

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.
Files changed (77) hide show
  1. package/CHANGELOG.md +417 -0
  2. package/LICENSE +20 -20
  3. package/README.md +303 -299
  4. package/README.pt-BR.md +303 -299
  5. package/dist/constants/provider-capabilities.constant.d.ts +17 -0
  6. package/dist/constants/provider-capabilities.constant.js +27 -0
  7. package/dist/index.d.ts +8 -8
  8. package/dist/index.js +1 -7
  9. package/dist/parsers/data.parser.d.ts +3 -33
  10. package/dist/parsers/data.parser.js +7 -45
  11. package/dist/parsers/include.parser.d.ts +1 -1
  12. package/dist/parsers/include.parser.js +3 -7
  13. package/dist/parsers/order-by.parser.d.ts +1 -10
  14. package/dist/parsers/order-by.parser.js +3 -16
  15. package/dist/parsers/select.parser.d.ts +1 -1
  16. package/dist/parsers/select.parser.js +3 -7
  17. package/dist/parsers/where.parser.d.ts +4 -29
  18. package/dist/parsers/where.parser.js +49 -148
  19. package/dist/prisma7.adapter.d.ts +104 -81
  20. package/dist/prisma7.adapter.js +329 -362
  21. package/dist/resolvers/map-prisma-error.resolver.d.ts +0 -11
  22. package/dist/resolvers/map-prisma-error.resolver.js +48 -72
  23. package/dist/resolvers/merge-entities.resolver.d.ts +11 -15
  24. package/dist/resolvers/merge-entities.resolver.js +29 -38
  25. package/dist/resolvers/resolve-provider.resolver.d.ts +2 -22
  26. package/dist/resolvers/resolve-provider.resolver.js +10 -33
  27. package/dist/types/adapter-config.type.d.ts +7 -12
  28. package/dist/types/adapter-config.type.js +1 -3
  29. package/dist/types/adapter-relations.type.d.ts +2 -2
  30. package/dist/types/adapter-relations.type.js +1 -3
  31. package/dist/types/plain-object.type.js +1 -3
  32. package/dist/types/prisma-arg-like.type.js +1 -3
  33. package/dist/types/prisma-client-models.type.d.ts +4 -4
  34. package/dist/types/prisma-client-models.type.js +1 -3
  35. package/dist/types/prisma-provider.type.d.ts +1 -1
  36. package/dist/types/prisma-provider.type.js +1 -3
  37. package/dist/types/prisma-repository-like.type.d.ts +1 -1
  38. package/dist/types/prisma-repository-like.type.js +1 -3
  39. package/dist/types/prisma7-client-like.type.d.ts +1 -8
  40. package/dist/types/prisma7-client-like.type.js +1 -3
  41. package/dist/types/prisma7-orm-types.type.d.ts +2 -2
  42. package/dist/types/prisma7-orm-types.type.js +1 -3
  43. package/dist/types/relation.type.d.ts +25 -19
  44. package/dist/types/relation.type.js +1 -3
  45. package/dist/validators/is-decimal.validator.d.ts +2 -5
  46. package/dist/validators/is-decimal.validator.js +3 -6
  47. package/dist/validators/is-plain-object.validator.d.ts +1 -1
  48. package/dist/validators/is-plain-object.validator.js +3 -7
  49. package/dist/validators/validate-prisma-client.validator.d.ts +1 -14
  50. package/dist/validators/validate-prisma-client.validator.js +7 -24
  51. package/package.json +108 -91
  52. package/dist/index.js.map +0 -1
  53. package/dist/parsers/data.parser.js.map +0 -1
  54. package/dist/parsers/include.parser.js.map +0 -1
  55. package/dist/parsers/order-by.parser.js.map +0 -1
  56. package/dist/parsers/select.parser.js.map +0 -1
  57. package/dist/parsers/where.parser.js.map +0 -1
  58. package/dist/prisma7.adapter.js.map +0 -1
  59. package/dist/resolvers/map-prisma-error.resolver.js.map +0 -1
  60. package/dist/resolvers/merge-entities.resolver.js.map +0 -1
  61. package/dist/resolvers/resolve-provider.resolver.js.map +0 -1
  62. package/dist/types/adapter-config.type.js.map +0 -1
  63. package/dist/types/adapter-relations.type.js.map +0 -1
  64. package/dist/types/plain-object.type.js.map +0 -1
  65. package/dist/types/prisma-arg-like.type.js.map +0 -1
  66. package/dist/types/prisma-client-models.type.js.map +0 -1
  67. package/dist/types/prisma-provider.type.js.map +0 -1
  68. package/dist/types/prisma-repository-like.type.js.map +0 -1
  69. package/dist/types/prisma7-client-like.type.js.map +0 -1
  70. package/dist/types/prisma7-orm-types.type.js.map +0 -1
  71. package/dist/types/relation.type.js.map +0 -1
  72. package/dist/validators/is-decimal.validator.js.map +0 -1
  73. package/dist/validators/is-plain-object.validator.js.map +0 -1
  74. package/dist/validators/validate-adapter-config.validator.d.ts +0 -8
  75. package/dist/validators/validate-adapter-config.validator.js +0 -78
  76. package/dist/validators/validate-adapter-config.validator.js.map +0 -1
  77. package/dist/validators/validate-prisma-client.validator.js.map +0 -1
@@ -1,37 +1,25 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VSRepoPrisma7Adapter = void 0;
4
- const vsrepo_1 = require("vsrepo");
5
- const where_parser_1 = require("./parsers/where.parser");
6
- const include_parser_1 = require("./parsers/include.parser");
7
- const select_parser_1 = require("./parsers/select.parser");
8
- const order_by_parser_1 = require("./parsers/order-by.parser");
9
- const data_parser_1 = require("./parsers/data.parser");
10
- const merge_entities_resolver_1 = require("./resolvers/merge-entities.resolver");
11
- const map_prisma_error_resolver_1 = require("./resolvers/map-prisma-error.resolver");
12
- const resolve_provider_resolver_1 = require("./resolvers/resolve-provider.resolver");
13
- const validate_adapter_config_validator_1 = require("./validators/validate-adapter-config.validator");
14
- const validate_prisma_client_validator_1 = require("./validators/validate-prisma-client.validator");
1
+ import { AdapterErrorCode, getPostgresPlaceholder, getSqlitePlaceholder, getSqlServerPlaceholder, VSLogger, VSLogLevel, VSRepoAdapter, VSRepoAdapterError, } from "vsrepo";
2
+ import { RETURNING_MANY_PROVIDERS, SKIP_DUPLICATES_PROVIDERS } from "./constants/provider-capabilities.constant.js";
3
+ import { parsePrismaWhere } from "./parsers/where.parser.js";
4
+ import { parsePrismaInclude } from "./parsers/include.parser.js";
5
+ import { parsePrismaSelect } from "./parsers/select.parser.js";
6
+ import { parsePrismaOrderBy } from "./parsers/order-by.parser.js";
7
+ import { parsePrismaWriteData } from "./parsers/data.parser.js";
8
+ // import { mergeEntities } from "./resolvers/merge-entities.resolver.js";
9
+ import { mapPrismaError } from "./resolvers/map-prisma-error.resolver.js";
10
+ import { resolveProvider } from "./resolvers/resolve-provider.resolver.js";
11
+ import { validatePrismaClient } from "./validators/validate-prisma-client.validator.js";
12
+ import { isDecimal } from "./validators/is-decimal.validator.js";
15
13
  /**
16
- * `VSRepoAdapter` implementation for Prisma 7. Translates every method of the
17
- * adapter contract into Prisma Client calls, resolving `VSRepoWhere`/`Ordering`/
18
- * `select`/`include` through the parsers, and — when a
19
- * `relations` config is provided — resolving relation fields on `create`/
20
- * `update`/`upsert`/`merge` the same way the v1 of VSRepository did (see
21
- * `Relation`).
22
- *
23
- * Every method always rejects with a `VSRepoAdapterError` — any error raised
24
- * by Prisma (or by the adapter itself) is translated through `mapPrismaError`
25
- * before leaving the adapter, so callers never have to deal with a raw
26
- * Prisma/driver error shape.
14
+ * `VSRepoAdapter` implementation for Prisma 7.
27
15
  *
28
16
  * @template T Entity type this adapter operates on.
29
17
  *
30
18
  * @publicApi
31
19
  */
32
- class VSRepoPrisma7Adapter extends vsrepo_1.VSRepoAdapter {
20
+ export class VSRepoPrisma7Adapter extends VSRepoAdapter {
33
21
  prisma;
34
- tableName;
22
+ modelName;
35
23
  pkName;
36
24
  relations;
37
25
  logger;
@@ -39,34 +27,55 @@ class VSRepoPrisma7Adapter extends vsrepo_1.VSRepoAdapter {
39
27
  constructor(prisma, config) {
40
28
  super();
41
29
  this.prisma = prisma;
42
- const validated = (0, validate_adapter_config_validator_1.validateAdapterConfig)(config);
43
- (0, validate_prisma_client_validator_1.validatePrismaClient)(prisma, validated.tableName);
44
- this.tableName = validated.tableName;
45
- this.pkName = validated.pkName;
46
- this.relations = validated.relations;
47
- this.provider = (0, resolve_provider_resolver_1.resolveProvider)(prisma, validated.provider);
48
- this.logger = new vsrepo_1.VSLogger(validated.logLevel ?? vsrepo_1.VSLogLevel.WARN, this.constructor.name + "Logger", validated.logSlowThresholdMs ?? 300);
49
- this.logger.logInfo(`${this.constructor.name} initialized for table '${this.tableName}' (pkName: '${this.pkName}'${this.relations ? `, relations: [${Object.keys(this.relations).join(", ")}]` : ""}, provider: ${this.provider ? `'${this.provider}'` : "<not detected>"})`);
30
+ validatePrismaClient(prisma, config.modelName);
31
+ this.modelName = config.modelName;
32
+ this.pkName = config.pkName;
33
+ this.relations = config.relations;
34
+ this.provider = resolveProvider(prisma, config.provider);
35
+ this.logger = new VSLogger(config.logLevel ?? VSLogLevel.WARN, this.constructor.name + "Logger");
36
+ this.logger.logInfo(`${this.constructor.name} initialized for table '${this.modelName}' (pkName: '${this.pkName}'${this.relations ? `, relations: [${Object.keys(this.relations).join(", ")}]` : ""}, provider: ${this.provider ? `'${this.provider}'` : "<not detected>"})`);
50
37
  }
51
38
  getPrismaRepository(db) {
52
- return db ? db[this.tableName] : this.prisma[this.tableName];
39
+ return db ? db[this.modelName] : this.prisma[this.modelName];
53
40
  }
54
41
  /** Resolves the "read" part of a Prisma arg: select/include/orderBy/pagination. */
55
42
  resolveReadArg(options) {
56
- options ??= {};
57
- const prismaSelect = options.select && (0, select_parser_1.parsePrismaSelect)(options.select);
58
- const prismaInclude = prismaSelect
59
- ? undefined
60
- : options.relations && (0, include_parser_1.parsePrismaInclude)(options.relations);
43
+ if (!options)
44
+ return {};
45
+ const prismaSelect = options.select && parsePrismaSelect(options.select);
46
+ const prismaInclude = prismaSelect ? undefined : options.relations && parsePrismaInclude(options.relations);
61
47
  return {
62
48
  select: prismaSelect,
63
49
  include: prismaInclude,
64
- orderBy: (0, order_by_parser_1.parsePrismaOrderBy)(options.order),
50
+ orderBy: parsePrismaOrderBy(options.order),
65
51
  skip: options.pagination?.offset,
66
52
  take: options.pagination?.limit,
67
- distinct: options.distinct,
68
53
  };
69
54
  }
55
+ /** Parses a `where` for this adapter's provider (rejecting what the provider cannot run). */
56
+ parseWhere(where) {
57
+ return parsePrismaWhere(where, this.provider);
58
+ }
59
+ /**
60
+ * `createManyReturning` and `updateManyReturning` rely on Prisma's `createManyAndReturn` /
61
+ * `updateManyAndReturn`, which only exist on PostgreSQL, CockroachDB and SQLite.
62
+ */
63
+ assertReturningManySupported(methodName) {
64
+ if (RETURNING_MANY_PROVIDERS.has(this.provider))
65
+ return;
66
+ throw new VSRepoAdapterError(`'${methodName}' is not supported by the '${this.provider}' provider, since Prisma only provides ` +
67
+ `createManyAndReturn/updateManyAndReturn on PostgreSQL, CockroachDB and SQLite.`, AdapterErrorCode.NOT_SUPPORTED, null);
68
+ }
69
+ /**
70
+ * `ignoreConflicts` is translated to Prisma's `skipDuplicates`, which isn't available on
71
+ * SQL Server and SQLite. Rejects with `NOT_SUPPORTED` instead of leaving it to Prisma.
72
+ */
73
+ assertIgnoreConflictsSupported(methodName, ignoreConflicts) {
74
+ if (!ignoreConflicts || SKIP_DUPLICATES_PROVIDERS.has(this.provider))
75
+ return;
76
+ throw new VSRepoAdapterError(`The 'ignoreConflicts' option of '${methodName}' is not supported by the '${this.provider}' provider, since Prisma only ` +
77
+ `supports skipDuplicates on PostgreSQL, MySQL and CockroachDB. Remove 'ignoreConflicts' to run it without skipping conflicts.`, AdapterErrorCode.NOT_SUPPORTED, null);
78
+ }
70
79
  /**
71
80
  * Strips relation fields from a payload — used by `createMany`/`updateMany`/
72
81
  * `updateManyReturning`, since those Prisma operations don't support nested
@@ -82,7 +91,7 @@ class VSRepoPrisma7Adapter extends vsrepo_1.VSRepoAdapter {
82
91
  if (value === undefined)
83
92
  continue;
84
93
  if (key in this.relations) {
85
- throw new vsrepo_1.VSRepoAdapterError(`Field '${key}' is a configured relation, but Prisma's *Many operations don't support nested relation writes.`, vsrepo_1.AdapterErrorCode.NOT_SUPPORTED, null);
94
+ throw new VSRepoAdapterError(`Field '${key}' is a configured relation, but Prisma's *Many operations don't support nested relation writes.`, AdapterErrorCode.NOT_SUPPORTED, null);
86
95
  }
87
96
  data[key] = value;
88
97
  }
@@ -117,28 +126,47 @@ class VSRepoPrisma7Adapter extends vsrepo_1.VSRepoAdapter {
117
126
  * evaluated server-side against the row's current value, never as a
118
127
  * client-side read-modify-write. `value` is passed through as-is:
119
128
  * Prisma accepts a `number`, `bigint`, or any `Decimal`/`DecimalJsLike`
120
- * value (which covers a {@link DecimalLike} like `Prisma.Decimal`)
129
+ * value (which covers a `DecimalLike` like `Prisma.Decimal`)
121
130
  * depending on the target column's type.
122
131
  *
123
132
  * Prisma's `update()` already returns the row reflecting the state
124
133
  * *after* the write, so no follow-up read is needed here.
125
134
  */
126
135
  async atomicUpdate(operation, field, value, where, options) {
127
- const start = this.logger.startPerformLog(`run ${operation}One`);
136
+ const methodName = `${operation}One`;
137
+ const start = this.logger.startPerformLog(`run ${methodName}`);
128
138
  try {
129
139
  const arg = {
130
- ...this.resolveReadArg(options),
131
- where: (0, where_parser_1.parsePrismaWhere)(where),
140
+ ...this.resolveReadArg({ select: options?.select, relations: options?.relations }),
141
+ where: this.parseWhere(where),
132
142
  data: { [field]: { [operation]: value } },
133
143
  };
134
- this.logger.logDebug(`Resolved Prisma arg for '${operation}One'`, arg);
135
- return await this.getPrismaRepository(options?.db).update(arg);
144
+ this.logger.logDebug(`Resolved Prisma arg for ${methodName}`, arg);
145
+ const result = await this.getPrismaRepository(options?.db).update(arg);
146
+ this.logger.endPerformLog(start);
147
+ return result;
136
148
  }
137
149
  catch (error) {
138
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, `${operation}One`);
150
+ this.logger.endPerformLog(start);
151
+ throw mapPrismaError(error, methodName);
152
+ }
153
+ }
154
+ async atomicUpdateMany(operation, field, value, where, options) {
155
+ const methodName = `${operation}Many`;
156
+ const start = this.logger.startPerformLog(`run ${methodName}`);
157
+ try {
158
+ const arg = {
159
+ where: this.parseWhere(where),
160
+ data: { [field]: { [operation]: value } },
161
+ };
162
+ this.logger.logDebug(`Resolved Prisma arg for ${methodName}`, arg);
163
+ const result = await this.getPrismaRepository(options?.db).updateMany(arg);
164
+ this.logger.endPerformLog(start);
165
+ return result;
139
166
  }
140
- finally {
167
+ catch (error) {
141
168
  this.logger.endPerformLog(start);
169
+ throw mapPrismaError(error, methodName);
142
170
  }
143
171
  }
144
172
  /**
@@ -152,7 +180,7 @@ class VSRepoPrisma7Adapter extends vsrepo_1.VSRepoAdapter {
152
180
  return null;
153
181
  if (typeof value === "bigint")
154
182
  return Number(value);
155
- if (typeof value?.toNumber === "function") {
183
+ if (isDecimal(value)) {
156
184
  return value.toNumber();
157
185
  }
158
186
  return Number(value);
@@ -170,18 +198,17 @@ class VSRepoPrisma7Adapter extends vsrepo_1.VSRepoAdapter {
170
198
  const aggKey = `_${operation}`;
171
199
  try {
172
200
  const arg = {
173
- where: (0, where_parser_1.parsePrismaWhere)(where),
201
+ where: this.parseWhere(where),
174
202
  [aggKey]: { [field]: true },
175
203
  };
176
- this.logger.logDebug(`Resolved Prisma arg for '${operation}'`, arg);
177
- const result = await this.getPrismaRepository(options?.db).aggregate(arg);
178
- return this.toNullableNumber(result?.[aggKey]?.[field]);
204
+ this.logger.logDebug(`Resolved Prisma arg for ${operation}`, arg);
205
+ const aggResult = await this.getPrismaRepository(options?.db).aggregate(arg);
206
+ this.logger.endPerformLog(start);
207
+ return this.toNullableNumber(aggResult?.[aggKey]?.[field]);
179
208
  }
180
209
  catch (error) {
181
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, operation);
182
- }
183
- finally {
184
210
  this.logger.endPerformLog(start);
211
+ throw mapPrismaError(error, operation);
185
212
  }
186
213
  }
187
214
  /** Returns the underlying ORM client instance used outside of transactions. */
@@ -197,277 +224,207 @@ class VSRepoPrisma7Adapter extends vsrepo_1.VSRepoAdapter {
197
224
  });
198
225
  }
199
226
  catch (error) {
200
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "runInTransaction");
227
+ throw mapPrismaError(error, "runInTransaction");
201
228
  }
202
229
  }
203
- /** Fetches a single record matching `where`. */
204
- async findOne(where, options) {
205
- const start = this.logger.startPerformLog("run findOne");
230
+ async execMethod(fn, methodName, arg) {
231
+ const start = this.logger.startPerformLog(`run ${methodName}`);
206
232
  try {
207
- const arg = { ...this.resolveReadArg(options), where: (0, where_parser_1.parsePrismaWhere)(where) };
208
- this.logger.logDebug("Resolved Prisma arg for 'findOne'", arg);
209
- return await this.getPrismaRepository(options?.db).findFirst(arg);
233
+ this.logger.logDebug(`Resolved Prisma arg for ${methodName}`, arg);
234
+ const result = await fn();
235
+ this.logger.endPerformLog(start);
236
+ return result;
210
237
  }
211
238
  catch (error) {
212
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "findOne");
213
- }
214
- finally {
215
239
  this.logger.endPerformLog(start);
240
+ throw mapPrismaError(error, methodName);
216
241
  }
217
242
  }
243
+ /** Fetches a single record matching `where`. */
244
+ async findOne(where, options) {
245
+ const arg = { ...this.resolveReadArg(options), where: this.parseWhere(where) };
246
+ return this.execMethod(() => this.getPrismaRepository(options?.db).findFirst(arg), "findOne", arg);
247
+ }
218
248
  /** Fetches a single record matching `where`, throwing if none is found. */
219
249
  async findOneOrThrow(where, options) {
220
- const start = this.logger.startPerformLog("run findOneOrThrow");
221
- try {
222
- const arg = { ...this.resolveReadArg(options), where: (0, where_parser_1.parsePrismaWhere)(where) };
223
- this.logger.logDebug("Resolved Prisma arg for 'findOneOrThrow'", arg);
224
- return await this.getPrismaRepository(options?.db).findFirstOrThrow(arg);
225
- }
226
- catch (error) {
227
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "findOneOrThrow");
228
- }
229
- finally {
230
- this.logger.endPerformLog(start);
231
- }
250
+ const arg = { ...this.resolveReadArg(options), where: this.parseWhere(where) };
251
+ return this.execMethod(() => this.getPrismaRepository(options?.db).findFirstOrThrow(arg), "findOneOrThrow", arg);
232
252
  }
233
253
  /** Fetches all records matching `where`. */
234
254
  async findMany(where, options) {
235
- const start = this.logger.startPerformLog("run findMany");
236
- try {
237
- const arg = { ...this.resolveReadArg(options), where: (0, where_parser_1.parsePrismaWhere)(where) };
238
- this.logger.logDebug("Resolved Prisma arg for 'findMany'", arg);
239
- return await this.getPrismaRepository(options?.db).findMany(arg);
240
- }
241
- catch (error) {
242
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "findMany");
243
- }
244
- finally {
245
- this.logger.endPerformLog(start);
246
- }
255
+ const arg = { ...this.resolveReadArg(options), where: this.parseWhere(where) };
256
+ return this.execMethod(() => this.getPrismaRepository(options?.db).findMany(arg), "findMany", arg);
247
257
  }
248
258
  /** Creates or updates (upsert) a single record. */
249
259
  async save(obj, options) {
250
- const start = this.logger.startPerformLog("run save");
251
- try {
252
- const objAny = obj;
253
- const pkValue = objAny[this.pkName];
254
- const readArg = this.resolveReadArg(options);
255
- const repo = this.getPrismaRepository(options?.db);
256
- if (pkValue === undefined) {
257
- const { create } = (0, data_parser_1.parsePrismaWriteData)(objAny, this.pkName, this.relations);
258
- const arg = { ...readArg, data: create };
259
- this.logger.logDebug("Resolved Prisma arg for 'save' (create)", arg);
260
- return await repo.create(arg);
261
- }
262
- const { create, update } = (0, data_parser_1.parsePrismaWriteData)(objAny, this.pkName, this.relations);
263
- const arg = { ...readArg, where: { [this.pkName]: pkValue }, create, update };
264
- this.logger.logDebug("Resolved Prisma arg for 'save' (upsert)", arg);
265
- return await repo.upsert(arg);
266
- }
267
- catch (error) {
268
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "save");
269
- }
270
- finally {
271
- this.logger.endPerformLog(start);
272
- }
260
+ const objAny = obj;
261
+ const pkValue = objAny[this.pkName];
262
+ const readArg = this.resolveReadArg({ select: options?.select, relations: options?.relations });
263
+ const repo = this.getPrismaRepository(options?.db);
264
+ const { create, update } = parsePrismaWriteData(objAny, this.pkName, this.relations, true);
265
+ if (pkValue === undefined) {
266
+ const arg = { ...readArg, data: create };
267
+ return this.execMethod(() => repo.create(arg), "save (create)", arg);
268
+ }
269
+ const arg = { ...readArg, where: { [this.pkName]: pkValue }, create, update };
270
+ return this.execMethod(() => repo.upsert(arg), "save (upsert)", arg);
273
271
  }
274
272
  /**
275
273
  * Creates or updates (upsert) multiple records. Prisma has no native bulk
276
274
  * upsert, so each record is saved individually inside a transaction —
277
- * reusing `options.db` when it's already a transaction client (see
278
- * `runTransactional`).
275
+ * reusing `options.db` when it's already a transaction client.
279
276
  */
280
277
  async saveMany(objs, options) {
281
278
  const start = this.logger.startPerformLog("run saveMany");
282
279
  try {
283
280
  this.logger.logDebug(`Saving ${objs.length} record(s) individually inside a transaction`);
284
- return await this.runTransactional(options?.db, async (tx) => {
281
+ const result = await this.runTransactional(options?.db, async (tx) => {
282
+ const optionsResolved = { ...options, db: tx };
285
283
  const saved = [];
286
284
  for (let i = 0; i < objs.length; i++) {
287
285
  const obj = objs[i];
288
- saved.push(await this.save(obj, { ...options, db: tx }));
286
+ saved.push(await this.save(obj, optionsResolved));
289
287
  }
290
288
  return saved;
291
289
  });
290
+ this.logger.endPerformLog(start);
291
+ return result;
292
292
  }
293
293
  catch (error) {
294
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "saveMany");
295
- }
296
- finally {
297
294
  this.logger.endPerformLog(start);
295
+ throw mapPrismaError(error, "saveMany");
298
296
  }
299
297
  }
300
298
  /** Deletes a single record matching `where`. */
301
299
  async delete(where, options) {
302
- const start = this.logger.startPerformLog("run delete");
303
- try {
304
- const arg = { ...this.resolveReadArg(options), where: (0, where_parser_1.parsePrismaWhere)(where) };
305
- this.logger.logDebug("Resolved Prisma arg for 'delete'", arg);
306
- return await this.getPrismaRepository(options?.db).delete(arg);
307
- }
308
- catch (error) {
309
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "delete");
310
- }
311
- finally {
312
- this.logger.endPerformLog(start);
313
- }
300
+ const arg = {
301
+ ...this.resolveReadArg({ select: options?.select, relations: options?.relations }),
302
+ where: this.parseWhere(where),
303
+ };
304
+ return this.execMethod(() => this.getPrismaRepository(options?.db).delete(arg), "delete", arg);
314
305
  }
315
306
  /** Deletes every record matching `where`, returning the count of affected rows. */
316
307
  async deleteMany(where, options) {
317
- const start = this.logger.startPerformLog("run deleteMany");
318
- try {
319
- const arg = { where: (0, where_parser_1.parsePrismaWhere)(where) };
320
- this.logger.logDebug("Resolved Prisma arg for 'deleteMany'", arg);
321
- return await this.getPrismaRepository(options?.db).deleteMany(arg);
322
- }
323
- catch (error) {
324
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "deleteMany");
325
- }
326
- finally {
327
- this.logger.endPerformLog(start);
328
- }
308
+ const arg = { where: this.parseWhere(where) };
309
+ return this.execMethod(() => this.getPrismaRepository(options?.db).deleteMany(arg), "deleteMany", arg);
329
310
  }
330
311
  /**
331
- * Deletes every record matching `where`, returning the deleted records.
312
+ * Deletes every record matching `where` and returns the deleted records.
332
313
  *
333
- * Prisma has no `deleteManyAndReturn`, so this does a `findMany` on
334
- * `where` first and then re-applies the same `where` to a `deleteMany`,
335
- * both inside a transaction (`runTransactional`).
314
+ * In the absence of a native `deleteManyAndReturn`, this fetches matching records
315
+ * via `findMany` first, extracts their primary keys, and then deletes them by ID
316
+ * using `{ [pkName]: { in: pks } }` inside a transaction.
336
317
  *
337
- * Because the delete is driven by the same `where` (not by the fetched
338
- * records), a concurrent change between the two operations can make them
339
- * diverge — e.g. a row inserted after the `findMany` matching the `where`
340
- * would still be deleted, while a row changed to stop matching wouldn't.
341
- * If you need to guarantee no concurrency issues, run this method inside a
342
- * `repository.transaction()` with a higher isolation level, e.g.
343
- * `TransactionIsolationLevel.SERIALIZABLE`.
318
+ * Key behaviors:
319
+ * - **Primary Key Handling:** If `options.select` omits the primary key, it is
320
+ * temporarily added to the query so the subsequent batch delete can target
321
+ * those exact IDs, and stripped from the returned objects afterward.
322
+ * - **Concurrency & Isolation:** Deleting strictly by the fetched IDs ensures only
323
+ * the exact returned rows are removed (avoiding deleting newly inserted rows that
324
+ * match `where`). However, if a row is modified or deleted concurrently between
325
+ * the read and the delete step, race conditions can still occur unless wrapped
326
+ * in a transaction with an appropriate isolation level (e.g., `SERIALIZABLE`).
344
327
  */
345
328
  async deleteManyReturning(where, options) {
346
329
  const start = this.logger.startPerformLog("run deleteManyReturning");
347
330
  try {
348
- const prismaWhere = (0, where_parser_1.parsePrismaWhere)(where);
349
- const findArg = { ...this.resolveReadArg(options), where: prismaWhere };
350
- const deleteArg = { where: prismaWhere };
351
- this.logger.logDebug("Resolved Prisma args for 'deleteManyReturning'", {
352
- findArg,
353
- deleteArg,
354
- });
355
- return await this.runTransactional(options?.db, async (tx) => {
331
+ const prismaWhere = this.parseWhere(where);
332
+ const findArg = {
333
+ ...this.resolveReadArg({ select: options?.select, relations: options?.relations }),
334
+ where: prismaWhere,
335
+ };
336
+ const userRequestedPk = findArg.include || !findArg.select || !!findArg.select[this.pkName];
337
+ if (!userRequestedPk) {
338
+ findArg.select[this.pkName] = true;
339
+ }
340
+ this.logger.logDebug("Resolved Prisma args for deleteManyReturning", findArg);
341
+ const result = await this.runTransactional(options?.db, async (tx) => {
356
342
  const repo = this.getPrismaRepository(tx);
357
343
  const records = await repo.findMany(findArg);
358
- await repo.deleteMany(deleteArg);
344
+ if (records.length === 0)
345
+ return [];
346
+ const pks = records.map((rec) => rec[this.pkName]);
347
+ await repo.deleteMany({ where: { [this.pkName]: { in: pks } } });
359
348
  return records;
360
349
  });
350
+ if (!userRequestedPk) {
351
+ for (const obj of result) {
352
+ delete obj[this.pkName];
353
+ }
354
+ }
355
+ this.logger.endPerformLog(start);
356
+ return result;
361
357
  }
362
358
  catch (error) {
363
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "deleteManyReturning");
364
- }
365
- finally {
366
359
  this.logger.endPerformLog(start);
360
+ throw mapPrismaError(error, "deleteManyReturning");
367
361
  }
368
362
  }
369
363
  /** Updates a single record matching `where`. */
370
364
  async update(where, obj, options) {
371
- const start = this.logger.startPerformLog("run update");
372
- try {
373
- const { update } = (0, data_parser_1.parsePrismaWriteData)(obj, this.pkName, this.relations);
374
- const arg = {
375
- ...this.resolveReadArg(options),
376
- where: (0, where_parser_1.parsePrismaWhere)(where),
377
- data: update,
378
- };
379
- this.logger.logDebug("Resolved Prisma arg for 'update'", arg);
380
- return await this.getPrismaRepository(options?.db).update(arg);
381
- }
382
- catch (error) {
383
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "update");
384
- }
385
- finally {
386
- this.logger.endPerformLog(start);
387
- }
365
+ const { update } = parsePrismaWriteData(obj, this.pkName, this.relations);
366
+ const arg = {
367
+ ...this.resolveReadArg({ select: options?.select, relations: options?.relations }),
368
+ where: this.parseWhere(where),
369
+ data: update,
370
+ };
371
+ return this.execMethod(() => this.getPrismaRepository(options?.db).update(arg), "update", arg);
388
372
  }
389
373
  /** Updates every record matching `where`, returning the count of affected rows. */
390
374
  async updateMany(where, obj, options) {
391
- const start = this.logger.startPerformLog("run updateMany");
392
- try {
393
- const data = this.stripRelationFields(obj);
394
- const arg = { where: (0, where_parser_1.parsePrismaWhere)(where), data };
395
- this.logger.logDebug("Resolved Prisma arg for 'updateMany'", arg);
396
- return await this.getPrismaRepository(options?.db).updateMany(arg);
397
- }
398
- catch (error) {
399
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "updateMany");
400
- }
401
- finally {
402
- this.logger.endPerformLog(start);
403
- }
375
+ const data = this.stripRelationFields(obj);
376
+ const arg = { where: this.parseWhere(where), data };
377
+ return this.execMethod(() => this.getPrismaRepository(options?.db).updateMany(arg), "updateMany", arg);
404
378
  }
405
- /** Updates every record matching `where`, returning the updated records. */
379
+ /**
380
+ * Updates every record matching `where`, returning the updated records.
381
+ *
382
+ * Rejects with `NOT_SUPPORTED` on providers without `updateManyAndReturn` (MySQL and SQL Server).
383
+ */
406
384
  async updateManyReturning(where, obj, options) {
407
385
  const start = this.logger.startPerformLog("run updateManyReturning");
408
386
  try {
409
- const data = this.stripRelationFields(obj);
410
- const readArg = this.resolveReadArg(options);
411
- const arg = {
412
- ...readArg,
413
- where: (0, where_parser_1.parsePrismaWhere)(where),
414
- data,
415
- };
416
- this.logger.logDebug("Resolved Prisma arg for 'updateManyReturning'", arg);
417
- return await this.runTransactional(options?.db, async (tx) => {
418
- const repo = this.getPrismaRepository(tx);
419
- const updated = await repo.updateManyAndReturn({
420
- ...arg,
421
- include: undefined,
422
- select: { [this.pkName]: true },
423
- });
424
- const idsUpdated = updated.map((_) => _[this.pkName]);
425
- return repo.findMany({
426
- ...readArg,
427
- where: { [this.pkName]: { in: idsUpdated } },
387
+ this.assertReturningManySupported("updateManyReturning");
388
+ const readArg = this.resolveReadArg({ select: options?.select, relations: options?.relations });
389
+ const arg = { where: this.parseWhere(where), data: this.stripRelationFields(obj) };
390
+ this.logger.logDebug("Resolved Prisma args for updateManyReturning", { ...readArg, ...arg });
391
+ let result;
392
+ if (!readArg.select && !readArg.include) {
393
+ result = await this.getPrismaRepository(options?.db).updateManyAndReturn(arg);
394
+ }
395
+ else {
396
+ result = await this.runTransactional(options?.db, async (tx) => {
397
+ const repo = this.getPrismaRepository(tx);
398
+ const updated = await repo.updateManyAndReturn({ ...arg, select: { [this.pkName]: true } });
399
+ const idsUpdated = updated.map((_) => _[this.pkName]);
400
+ return await repo.findMany({
401
+ ...readArg,
402
+ where: { [this.pkName]: { in: idsUpdated } },
403
+ });
428
404
  });
429
- });
405
+ }
406
+ this.logger.endPerformLog(start);
407
+ return result;
430
408
  }
431
409
  catch (error) {
432
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "updateManyReturning");
433
- }
434
- finally {
435
410
  this.logger.endPerformLog(start);
411
+ throw mapPrismaError(error, "updateManyReturning");
436
412
  }
437
413
  }
438
414
  /** Returns the number of records matching `where`. */
439
415
  async count(where, options) {
440
- const start = this.logger.startPerformLog("run count");
441
- try {
442
- const readArg = this.resolveReadArg(options);
443
- const arg = { ...readArg, where: (0, where_parser_1.parsePrismaWhere)(where) };
444
- this.logger.logDebug("Resolved Prisma arg for 'count'", arg);
445
- return await this.getPrismaRepository(options?.db).count(arg);
446
- }
447
- catch (error) {
448
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "count");
449
- }
450
- finally {
451
- this.logger.endPerformLog(start);
452
- }
416
+ const arg = { where: this.parseWhere(where) };
417
+ return this.execMethod(() => this.getPrismaRepository(options?.db).count(arg), "count", arg);
453
418
  }
454
419
  /** Checks whether at least one record matching `where` exists. */
455
420
  async exists(where, options) {
456
- const start = this.logger.startPerformLog("run exists");
457
- try {
458
- const arg = { where: (0, where_parser_1.parsePrismaWhere)(where), select: { [this.pkName]: true } };
459
- this.logger.logDebug("Resolved Prisma arg for 'exists'", arg);
421
+ const arg = { where: this.parseWhere(where), select: { [this.pkName]: true } };
422
+ return this.execMethod(async () => {
460
423
  const result = await this.getPrismaRepository(options?.db).findFirst(arg);
461
424
  return result !== null;
462
- }
463
- catch (error) {
464
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "exists");
465
- }
466
- finally {
467
- this.logger.endPerformLog(start);
468
- }
425
+ }, "exists", arg);
469
426
  }
470
- /** Executes a raw query/statement against the underlying database, used by `@QueryMethod`. */
427
+ /** Executes a raw query/statement against the underlying database. */
471
428
  async query(query, options) {
472
429
  const modifying = options?.modifying ?? false;
473
430
  const db = options?.db ?? this.prisma;
@@ -475,128 +432,114 @@ class VSRepoPrisma7Adapter extends vsrepo_1.VSRepoAdapter {
475
432
  const start = this.logger.startPerformLog(`run raw query (modifying: ${modifying})`);
476
433
  try {
477
434
  this.logger.logDebug("Running raw query", { query, args, modifying });
478
- return modifying
435
+ const result = modifying
479
436
  ? await db.$executeRawUnsafe(query, ...args)
480
437
  : await db.$queryRawUnsafe(query, ...args);
438
+ this.logger.endPerformLog(start);
439
+ return result;
481
440
  }
482
441
  catch (error) {
483
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "query");
484
- }
485
- finally {
486
442
  this.logger.endPerformLog(start);
443
+ throw mapPrismaError(error, "query");
487
444
  }
488
445
  }
489
446
  /** Creates a single record. */
490
447
  async create(obj, options) {
491
- const start = this.logger.startPerformLog("run create");
492
- try {
493
- const { create } = (0, data_parser_1.parsePrismaWriteData)(obj, this.pkName, this.relations);
494
- const arg = { ...this.resolveReadArg(options), data: create };
495
- this.logger.logDebug("Resolved Prisma arg for 'create'", arg);
496
- return await this.getPrismaRepository(options?.db).create(arg);
497
- }
498
- catch (error) {
499
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "create");
500
- }
501
- finally {
502
- this.logger.endPerformLog(start);
503
- }
448
+ const { create } = parsePrismaWriteData(obj, this.pkName, this.relations);
449
+ const arg = {
450
+ ...this.resolveReadArg({ select: options?.select, relations: options?.relations }),
451
+ data: create,
452
+ };
453
+ return this.execMethod(() => this.getPrismaRepository(options?.db).create(arg), "create", arg);
504
454
  }
505
455
  /**
506
- * Creates multiple records in a single operation. Relation fields are
507
- * stripped (see `stripRelationFields`), since Prisma's `createMany` doesn't
508
- * support nested writes.
456
+ * Creates multiple records in a single operation.
457
+ *
458
+ * Rejects with `NOT_SUPPORTED` when `ignoreConflicts` is used on a provider without
459
+ * `skipDuplicates` (SQL Server and SQLite).
509
460
  */
510
461
  async createMany(objs, options) {
511
- const start = this.logger.startPerformLog("run createMany");
512
- try {
513
- const data = objs.map(obj => this.stripRelationFields(obj));
514
- const arg = { data, skipDuplicates: options?.ignoreConflicts };
515
- this.logger.logDebug("Resolved Prisma arg for 'createMany'", arg);
516
- return await this.getPrismaRepository(options?.db).createMany(arg);
517
- }
518
- catch (error) {
519
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "createMany");
520
- }
521
- finally {
522
- this.logger.endPerformLog(start);
523
- }
462
+ this.assertIgnoreConflictsSupported("createMany", options?.ignoreConflicts);
463
+ const data = objs.map(obj => this.stripRelationFields(obj));
464
+ const arg = { data, skipDuplicates: options?.ignoreConflicts };
465
+ return this.execMethod(() => this.getPrismaRepository(options?.db).createMany(arg), "createMany", arg);
524
466
  }
525
467
  /**
526
468
  * Creates multiple records in a single operation, returning the created records.
469
+ *
470
+ * Rejects with `NOT_SUPPORTED` on providers without `createManyAndReturn` (MySQL and SQL Server),
471
+ * and when `ignoreConflicts` is used on a provider without `skipDuplicates` (SQL Server and SQLite).
527
472
  */
528
473
  async createManyReturning(objs, options) {
529
474
  const start = this.logger.startPerformLog("run createManyReturning");
530
475
  try {
531
- const data = objs.map(obj => this.stripRelationFields(obj));
532
- const readArg = this.resolveReadArg(options);
533
- const arg = { data, skipDuplicates: options?.ignoreConflicts };
534
- this.logger.logDebug("Resolved Prisma arg for 'createManyReturning'", arg);
535
- return await this.runTransactional(options?.db, async (tx) => {
536
- const repo = this.getPrismaRepository(tx);
537
- const created = await repo.createManyAndReturn({
538
- ...arg,
539
- include: undefined,
540
- select: { [this.pkName]: true },
541
- });
542
- const idsCreated = created.map((_) => _[this.pkName]);
543
- return repo.findMany({
544
- ...readArg,
545
- where: { [this.pkName]: { in: idsCreated } },
476
+ this.assertReturningManySupported("createManyReturning");
477
+ this.assertIgnoreConflictsSupported("createManyReturning", options?.ignoreConflicts);
478
+ const readArg = this.resolveReadArg({ select: options?.select, relations: options?.relations });
479
+ const arg = {
480
+ data: objs.map(obj => this.stripRelationFields(obj)),
481
+ skipDuplicates: options?.ignoreConflicts,
482
+ };
483
+ this.logger.logDebug("Resolved Prisma args for createManyReturning", { ...readArg, ...arg });
484
+ let result;
485
+ if (!readArg.select && !readArg.include) {
486
+ result = await this.getPrismaRepository(options?.db).createManyAndReturn(arg);
487
+ }
488
+ else {
489
+ result = await this.runTransactional(options?.db, async (tx) => {
490
+ const repo = this.getPrismaRepository(tx);
491
+ const created = await repo.createManyAndReturn({ ...arg, select: { [this.pkName]: true } });
492
+ const idsCreated = created.map((_) => _[this.pkName]);
493
+ return await repo.findMany({
494
+ ...readArg,
495
+ where: { [this.pkName]: { in: idsCreated } },
496
+ });
546
497
  });
547
- });
548
- }
549
- catch (error) {
550
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "createManyReturning");
551
- }
552
- finally {
498
+ }
553
499
  this.logger.endPerformLog(start);
554
- }
555
- }
556
- /**
557
- * Fetches the record matching `where` and returns it deep-merged with
558
- * `obj`, WITHOUT persisting anything — same behavior the v1 of
559
- * VSRepository had (see `mergeEntities`). It's on the caller to decide
560
- * what to do with the result (e.g. call `save` next).
561
- */
562
- async merge(where, obj, options) {
563
- const start = this.logger.startPerformLog("run merge");
564
- try {
565
- const arg = { ...this.resolveReadArg(options), where: (0, where_parser_1.parsePrismaWhere)(where) };
566
- this.logger.logDebug("Resolved Prisma arg for 'merge'", arg);
567
- const result = await this.getPrismaRepository(options?.db).findFirst(arg);
568
- if (!result)
569
- return null;
570
- return (0, merge_entities_resolver_1.mergeEntities)(result, obj, this.relations);
500
+ return result;
571
501
  }
572
502
  catch (error) {
573
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "merge");
574
- }
575
- finally {
576
503
  this.logger.endPerformLog(start);
577
- }
578
- }
504
+ throw mapPrismaError(error, "createManyReturning");
505
+ }
506
+ }
507
+ // /**
508
+ // * Fetches the record matching `where` and returns it merged with `obj`,
509
+ // * WITHOUT persisting anything. Only the configured `relations` are merged;
510
+ // * every other value is replaced. It's on the caller to decide what to do
511
+ // * with the result (e.g. call `save` next).
512
+ // */
513
+ // async merge<K extends DeepPartial<T>>(
514
+ // where: VSRepoWhere<T>,
515
+ // obj: K,
516
+ // options?: SimpleAdapterMethodOptions<T>,
517
+ // ): Promise<(K & T) | null> {
518
+ // const arg = {
519
+ // ...this.resolveReadArg({ select: options?.select, relations: options?.relations }),
520
+ // where: this.parseWhere(where),
521
+ // };
522
+ // return this.execMethod(
523
+ // async () => {
524
+ // const result = await this.getPrismaRepository(options?.db).findFirst(arg);
525
+ // if (!result) return null;
526
+ // return mergeEntities(result, obj as PlainObject, this.relations) as K & T;
527
+ // },
528
+ // "merge",
529
+ // arg,
530
+ // );
531
+ // }
579
532
  /** Creates a record if none matches `where`, otherwise updates it. */
580
533
  async upsert(where, create, update, options) {
581
- const start = this.logger.startPerformLog("run upsert");
582
- try {
583
- const parsedCreate = (0, data_parser_1.parsePrismaWriteData)(create, this.pkName, this.relations).create;
584
- const parsedUpdate = (0, data_parser_1.parsePrismaWriteData)(update, this.pkName, this.relations).update;
585
- const arg = {
586
- ...this.resolveReadArg(options),
587
- where: (0, where_parser_1.parsePrismaWhere)(where),
588
- create: parsedCreate,
589
- update: parsedUpdate,
590
- };
591
- this.logger.logDebug("Resolved Prisma arg for 'upsert'", arg);
592
- return await this.getPrismaRepository(options?.db).upsert(arg);
593
- }
594
- catch (error) {
595
- throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, "upsert");
596
- }
597
- finally {
598
- this.logger.endPerformLog(start);
599
- }
534
+ const parsedCreate = parsePrismaWriteData(create, this.pkName, this.relations).create;
535
+ const parsedUpdate = parsePrismaWriteData(update, this.pkName, this.relations).update;
536
+ const arg = {
537
+ ...this.resolveReadArg({ select: options?.select, relations: options?.relations }),
538
+ where: this.parseWhere(where),
539
+ create: parsedCreate,
540
+ update: parsedUpdate,
541
+ };
542
+ return this.execMethod(() => this.getPrismaRepository(options?.db).upsert(arg), "upsert", arg);
600
543
  }
601
544
  /**
602
545
  * Atomically adds `value` to `field` on the record matching `where`,
@@ -605,24 +548,55 @@ class VSRepoPrisma7Adapter extends vsrepo_1.VSRepoAdapter {
605
548
  async incrementOne(field, value, where, options) {
606
549
  return this.atomicUpdate("increment", field, value, where, options);
607
550
  }
608
- /** Same as {@link VSRepoPrisma7Adapter.incrementOne}, subtracting `value` instead of adding it. */
551
+ /**
552
+ * Atomically subtracts `value` to `field` on the record matching `where`,
553
+ * via Prisma's native `{ field: { decrement: value } }` write.
554
+ */
609
555
  async decrementOne(field, value, where, options) {
610
556
  return this.atomicUpdate("decrement", field, value, where, options);
611
557
  }
612
- /** Same as {@link VSRepoPrisma7Adapter.incrementOne}, multiplying the field's current value by `value`. */
558
+ /**
559
+ * Atomically multiplies `value` to `field` on the record matching `where`,
560
+ * via Prisma's native `{ field: { multiply: value } }` write.
561
+ */
613
562
  async multiplyOne(field, value, where, options) {
614
563
  return this.atomicUpdate("multiply", field, value, where, options);
615
564
  }
616
565
  /**
617
- * Same as {@link VSRepoPrisma7Adapter.incrementOne}, dividing the
618
- * field's current value by `value`. Division-by-zero is not handled by
619
- * the adapter — it's whatever Postgres does natively (raises a
620
- * `division_by_zero` error for integer columns; `Infinity`/`NaN` are not
621
- * representable in a numeric/decimal column, so those also error).
566
+ * Atomically divides `value` to `field` on the record matching `where`,
567
+ * via Prisma's native `{ field: { divide: value } }` write.
622
568
  */
623
569
  async divideOne(field, value, where, options) {
624
570
  return this.atomicUpdate("divide", field, value, where, options);
625
571
  }
572
+ /**
573
+ * Atomically adds `value` to `field` on every record matching `where`,
574
+ * via Prisma's native `{ field: { increment: value } }` write.
575
+ */
576
+ async incrementMany(field, value, where, options) {
577
+ return this.atomicUpdateMany("increment", field, value, where, options);
578
+ }
579
+ /**
580
+ * Atomically subtracts `value` from `field` on every record matching `where`,
581
+ * via Prisma's native `{ field: { decrement: value } }` write.
582
+ */
583
+ async decrementMany(field, value, where, options) {
584
+ return this.atomicUpdateMany("decrement", field, value, where, options);
585
+ }
586
+ /**
587
+ * Atomically multiplies `field` by `value` on every record matching `where`,
588
+ * via Prisma's native `{ field: { multiply: value } }` write.
589
+ */
590
+ async multiplyMany(field, value, where, options) {
591
+ return this.atomicUpdateMany("multiply", field, value, where, options);
592
+ }
593
+ /**
594
+ * Atomically divides `field` by `value` on every record matching `where`,
595
+ * via Prisma's native `{ field: { divide: value } }` write.
596
+ */
597
+ async divideMany(field, value, where, options) {
598
+ return this.atomicUpdateMany("divide", field, value, where, options);
599
+ }
626
600
  /**
627
601
  * Returns the sum of `field` across every record matching `where` (all
628
602
  * records if `where` is empty), or `null` if no record matches.
@@ -659,19 +633,12 @@ class VSRepoPrisma7Adapter extends vsrepo_1.VSRepoAdapter {
659
633
  switch (this.provider) {
660
634
  case "postgresql":
661
635
  case "cockroachdb":
662
- return `$${index + 1}`;
636
+ return getPostgresPlaceholder(index);
663
637
  case "mysql":
664
638
  case "sqlite":
665
- return "?";
639
+ return getSqlitePlaceholder(index);
666
640
  case "sqlserver":
667
- return `@P${index + 1}`;
668
- default:
669
- throw new vsrepo_1.VSRepoAdapterError("Cannot resolve the raw-query placeholder syntax: the Prisma provider couldn't be detected from the client, " +
670
- "and no 'provider' was set in the adapter config. Set 'provider' in the VSRepoPrisma7Adapter config (one of: " +
671
- "postgresql, cockroachdb, mysql, sqlite, sqlserver) to enable raw-query placeholder compilation " +
672
- "(e.g. VSSql fragments and 'vsPlaceholders').", vsrepo_1.AdapterErrorCode.NOT_SUPPORTED, null);
641
+ return getSqlServerPlaceholder(index);
673
642
  }
674
643
  }
675
644
  }
676
- exports.VSRepoPrisma7Adapter = VSRepoPrisma7Adapter;
677
- //# sourceMappingURL=prisma7.adapter.js.map