@vsrepo/prisma7-adapter 1.3.1 → 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.
- package/CHANGELOG.md +417 -0
- package/LICENSE +20 -20
- package/README.md +303 -299
- package/README.pt-BR.md +303 -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 +8 -8
- package/dist/index.js +1 -7
- package/dist/parsers/data.parser.d.ts +3 -33
- package/dist/parsers/data.parser.js +7 -45
- 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 +2 -10
- package/dist/parsers/order-by.parser.js +6 -19
- 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 -28
- package/dist/parsers/where.parser.js +49 -151
- package/dist/prisma7.adapter.d.ts +104 -81
- package/dist/prisma7.adapter.js +329 -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 +7 -12
- package/dist/types/adapter-config.type.js +1 -3
- package/dist/types/adapter-relations.type.d.ts +2 -2
- 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-orm-types.type.d.ts +2 -2
- package/dist/types/prisma7-orm-types.type.js +1 -3
- package/dist/types/relation.type.d.ts +25 -19
- 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,37 +1,25 @@
|
|
|
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;
|
|
@@ -39,34 +27,55 @@ class VSRepoPrisma7Adapter extends vsrepo_1.VSRepoAdapter {
|
|
|
39
27
|
constructor(prisma, config) {
|
|
40
28
|
super();
|
|
41
29
|
this.prisma = prisma;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
this.
|
|
45
|
-
this.
|
|
46
|
-
this.
|
|
47
|
-
this.
|
|
48
|
-
this.logger
|
|
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.
|
|
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
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
135
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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:
|
|
201
|
+
where: this.parseWhere(where),
|
|
174
202
|
[aggKey]: { [field]: true },
|
|
175
203
|
};
|
|
176
|
-
this.logger.logDebug(`Resolved Prisma arg for
|
|
177
|
-
const
|
|
178
|
-
|
|
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
|
|
227
|
+
throw mapPrismaError(error, "runInTransaction");
|
|
201
228
|
}
|
|
202
229
|
}
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
|
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
|
-
}
|
|
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
|
|
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
|
-
}
|
|
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
|
|
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
|
-
}
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
|
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
|
-
}
|
|
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
|
|
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
|
-
}
|
|
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
|
|
312
|
+
* Deletes every record matching `where` and returns the deleted records.
|
|
332
313
|
*
|
|
333
|
-
*
|
|
334
|
-
* `
|
|
335
|
-
*
|
|
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
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
* `
|
|
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 =
|
|
349
|
-
const findArg = {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
}
|
|
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
|
|
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
|
-
}
|
|
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
|
-
/**
|
|
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
|
-
|
|
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 } },
|
|
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
|
|
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
|
-
}
|
|
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
|
|
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);
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
}
|
|
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.
|
|
507
|
-
*
|
|
508
|
-
*
|
|
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
|
-
|
|
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
|
-
}
|
|
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
|
-
|
|
532
|
-
|
|
533
|
-
const
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
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
|
|
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
|
-
}
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
*
|
|
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).
|
|
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
|
|
636
|
+
return getPostgresPlaceholder(index);
|
|
663
637
|
case "mysql":
|
|
664
638
|
case "sqlite":
|
|
665
|
-
return
|
|
639
|
+
return getSqlitePlaceholder(index);
|
|
666
640
|
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);
|
|
641
|
+
return getSqlServerPlaceholder(index);
|
|
673
642
|
}
|
|
674
643
|
}
|
|
675
644
|
}
|
|
676
|
-
exports.VSRepoPrisma7Adapter = VSRepoPrisma7Adapter;
|
|
677
|
-
//# sourceMappingURL=prisma7.adapter.js.map
|