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