@reldens/storage 0.81.0 → 0.82.0
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/CLAUDE.md +125 -3
- package/bin/reldens-storage.js +63 -8
- package/lib/entities-generator.js +4 -3
- package/lib/generators/models-generation.js +161 -8
- package/lib/prisma/prisma-data-server.js +38 -4
- package/lib/prisma/prisma-driver.js +216 -368
- package/lib/prisma/prisma-filter-processor.js +146 -0
- package/lib/prisma/prisma-metadata-loader.js +7 -0
- package/lib/prisma/prisma-query-builder.js +42 -0
- package/lib/prisma/prisma-relation-resolver.js +168 -168
- package/lib/prisma/prisma-schema-generator.js +40 -33
- package/lib/prisma/prisma-type-caster.js +29 -0
- package/package.json +1 -1
|
@@ -8,6 +8,8 @@ const { BaseDriver } = require('../base-driver');
|
|
|
8
8
|
const { PrismaTypeCaster } = require('./prisma-type-caster');
|
|
9
9
|
const { PrismaMetadataLoader } = require('./prisma-metadata-loader');
|
|
10
10
|
const { PrismaRelationResolver } = require('./prisma-relation-resolver');
|
|
11
|
+
const { PrismaFilterProcessor } = require('./prisma-filter-processor');
|
|
12
|
+
const { PrismaQueryBuilder } = require('./prisma-query-builder');
|
|
11
13
|
const { Logger, sc } = require('@reldens/utils');
|
|
12
14
|
|
|
13
15
|
class PrismaDriver extends BaseDriver
|
|
@@ -26,6 +28,7 @@ class PrismaDriver extends BaseDriver
|
|
|
26
28
|
}
|
|
27
29
|
this.prisma = props.prisma;
|
|
28
30
|
this.model = props.model;
|
|
31
|
+
this.allRelationMappings = sc.get(props, 'allRelationMappings', {});
|
|
29
32
|
this.initHelpers();
|
|
30
33
|
this.initModelMetadata();
|
|
31
34
|
}
|
|
@@ -47,9 +50,19 @@ class PrismaDriver extends BaseDriver
|
|
|
47
50
|
});
|
|
48
51
|
this.relationResolver = new PrismaRelationResolver({
|
|
49
52
|
relationMetadata: {},
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
metadataLoader: this.metadataLoader,
|
|
54
|
+
allRelationMappings: this.allRelationMappings,
|
|
55
|
+
foreignKeyMappings: {},
|
|
56
|
+
foreignKeyTargetFields: {},
|
|
57
|
+
typeCaster: this.typeCaster
|
|
52
58
|
});
|
|
59
|
+
this.filterProcessor = new PrismaFilterProcessor({
|
|
60
|
+
typeCaster: this.typeCaster,
|
|
61
|
+
fieldTypes: {},
|
|
62
|
+
referenceFields: {},
|
|
63
|
+
jsonFields: new Set()
|
|
64
|
+
});
|
|
65
|
+
this.queryBuilder = new PrismaQueryBuilder();
|
|
53
66
|
}
|
|
54
67
|
|
|
55
68
|
initModelMetadata()
|
|
@@ -63,9 +76,11 @@ class PrismaDriver extends BaseDriver
|
|
|
63
76
|
this.fieldTypes = metadata.fieldTypes;
|
|
64
77
|
this.fieldDefaults = metadata.fieldDefaults;
|
|
65
78
|
this.idFieldType = metadata.idFieldType;
|
|
79
|
+
this.idFieldName = sc.get(metadata, 'idFieldName', 'id');
|
|
66
80
|
this.referenceFields = metadata.referenceFields;
|
|
67
81
|
this.relationMetadata = metadata.relationMetadata;
|
|
68
82
|
this.foreignKeyMappings = metadata.foreignKeyMappings;
|
|
83
|
+
this.foreignKeyTargetFields = sc.get(metadata, 'foreignKeyTargetFields', {});
|
|
69
84
|
this.jsonFields = metadata.jsonFields;
|
|
70
85
|
this.typeCaster.updateMetadata({
|
|
71
86
|
idFieldType: this.idFieldType,
|
|
@@ -76,9 +91,17 @@ class PrismaDriver extends BaseDriver
|
|
|
76
91
|
optionalFields: this.optionalFields
|
|
77
92
|
});
|
|
78
93
|
this.relationResolver.updateMetadata({
|
|
79
|
-
relationMetadata: this.relationMetadata
|
|
94
|
+
relationMetadata: this.relationMetadata,
|
|
95
|
+
foreignKeyMappings: this.foreignKeyMappings,
|
|
96
|
+
foreignKeyTargetFields: this.foreignKeyTargetFields
|
|
97
|
+
});
|
|
98
|
+
this.filterProcessor.updateMetadata({
|
|
99
|
+
fieldTypes: this.fieldTypes,
|
|
100
|
+
referenceFields: this.referenceFields,
|
|
101
|
+
jsonFields: this.jsonFields
|
|
80
102
|
});
|
|
81
|
-
|
|
103
|
+
let currentModelMappings = sc.get(this.allRelationMappings, this.tableName(), {});
|
|
104
|
+
this.relationResolver.setCurrentModelMappings(currentModelMappings);
|
|
82
105
|
}
|
|
83
106
|
|
|
84
107
|
databaseName()
|
|
@@ -111,183 +134,98 @@ class PrismaDriver extends BaseDriver
|
|
|
111
134
|
return this.relationResolver.getAllRelations();
|
|
112
135
|
}
|
|
113
136
|
|
|
114
|
-
|
|
137
|
+
getQueryOptions()
|
|
115
138
|
{
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
139
|
+
return {
|
|
140
|
+
select: this.select,
|
|
141
|
+
limit: this.limit,
|
|
142
|
+
offset: this.offset,
|
|
143
|
+
sortBy: this.sortBy,
|
|
144
|
+
sortDirection: this.sortDirection
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
prepareData(params, options = {})
|
|
149
|
+
{
|
|
150
|
+
let skipObjects = sc.get(options, 'skipObjects', false);
|
|
151
|
+
let convertRelations = sc.get(options, 'convertRelations', false);
|
|
152
|
+
let isCreate = sc.get(options, 'isCreate', false);
|
|
153
|
+
if(convertRelations){
|
|
154
|
+
let converted = this.relationResolver.convertForeignKeysToRelations(params, isCreate);
|
|
155
|
+
return this.castDataFields(converted, skipObjects);
|
|
127
156
|
}
|
|
128
|
-
return
|
|
157
|
+
return this.castDataFields(params, skipObjects);
|
|
129
158
|
}
|
|
130
159
|
|
|
131
|
-
|
|
160
|
+
castDataFields(params, skipObjects = false)
|
|
132
161
|
{
|
|
133
162
|
let data = {};
|
|
134
|
-
let relations = {};
|
|
135
163
|
for(let key of Object.keys(params)){
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
let value = params[key];
|
|
139
|
-
if(!this.typeCaster.isNullOrEmpty(value)){
|
|
140
|
-
relations[relationName] = {
|
|
141
|
-
connect: {id: this.typeCaster.castToIdType(value)}
|
|
142
|
-
};
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
|
-
if(!isCreate){
|
|
146
|
-
relations[relationName] = {
|
|
147
|
-
disconnect: true
|
|
148
|
-
};
|
|
149
|
-
}
|
|
164
|
+
let value = params[key];
|
|
165
|
+
if(skipObjects && sc.isObject(value) && !sc.isArray(value)){
|
|
150
166
|
continue;
|
|
151
167
|
}
|
|
152
168
|
let fieldType = this.fieldTypes[key];
|
|
153
169
|
if(!fieldType){
|
|
154
|
-
if(!this.typeCaster.isNullOrEmpty(
|
|
155
|
-
data[key] =
|
|
170
|
+
if(!skipObjects && !this.typeCaster.isNullOrEmpty(value)){
|
|
171
|
+
data[key] = value;
|
|
156
172
|
}
|
|
157
173
|
continue;
|
|
158
174
|
}
|
|
159
|
-
let castedValue = this.typeCaster.castValue(
|
|
160
|
-
if(
|
|
161
|
-
if(this.typeCaster.isJsonFieldType(fieldType) && null === castedValue){
|
|
175
|
+
let castedValue = this.typeCaster.castValue(value, fieldType, key);
|
|
176
|
+
if(this.typeCaster.isValidCastedValue(castedValue)){
|
|
177
|
+
if(this.typeCaster.isJsonFieldType(fieldType) && null === castedValue && !skipObjects){
|
|
162
178
|
continue;
|
|
163
179
|
}
|
|
164
180
|
data[key] = castedValue;
|
|
165
181
|
}
|
|
166
182
|
}
|
|
167
|
-
return
|
|
183
|
+
return data;
|
|
168
184
|
}
|
|
169
185
|
|
|
170
186
|
ensureRequiredFields(data)
|
|
171
187
|
{
|
|
172
188
|
let missingFields = [];
|
|
173
189
|
for(let field of this.requiredFields){
|
|
174
|
-
if(
|
|
175
|
-
missingFields.push(field);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
if(0 < missingFields.length){
|
|
179
|
-
Logger.warning('Missing required fields for '+this.tableName()+': '+missingFields.join(', '));
|
|
180
|
-
}
|
|
181
|
-
return data;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
processFilters(filters)
|
|
185
|
-
{
|
|
186
|
-
if(!sc.isObject(filters)){
|
|
187
|
-
return filters;
|
|
188
|
-
}
|
|
189
|
-
let processedFilters = {};
|
|
190
|
-
for(let key of Object.keys(filters)){
|
|
191
|
-
let value = filters[key];
|
|
192
|
-
if('OR' === key && sc.isArray(value)){
|
|
193
|
-
processedFilters.OR = value.map(condition => this.processFilters(condition));
|
|
190
|
+
if(sc.hasOwn(data, field)){
|
|
194
191
|
continue;
|
|
195
192
|
}
|
|
196
|
-
if(sc.hasOwn(
|
|
197
|
-
let
|
|
198
|
-
|
|
199
|
-
|
|
193
|
+
if(sc.hasOwn(this.foreignKeyMappings, field)){
|
|
194
|
+
let relationName = this.foreignKeyMappings[field];
|
|
195
|
+
if(sc.hasOwn(data, relationName)){
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
200
198
|
}
|
|
201
|
-
if(sc.
|
|
202
|
-
processedFilters[key] = this.processFilters(value);
|
|
199
|
+
if(sc.hasOwn(this.fieldDefaults, field)){
|
|
203
200
|
continue;
|
|
204
201
|
}
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
return processedFilters;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
processFilterValue(value, key)
|
|
211
|
-
{
|
|
212
|
-
if(sc.isArray(value)){
|
|
213
|
-
if('id' === key){
|
|
214
|
-
return value.map(id => this.typeCaster.castToIdType(id)).filter(id => null !== id);
|
|
215
|
-
}
|
|
216
|
-
let fieldType = this.fieldTypes[key];
|
|
217
|
-
if(fieldType){
|
|
218
|
-
return value.map(val => this.typeCaster.castValue(val, fieldType, key)).filter(val => undefined !== val);
|
|
219
|
-
}
|
|
220
|
-
return value;
|
|
221
|
-
}
|
|
222
|
-
if('id' === key){
|
|
223
|
-
return this.typeCaster.castToIdType(value);
|
|
224
|
-
}
|
|
225
|
-
let fieldType = this.fieldTypes[key];
|
|
226
|
-
if(fieldType){
|
|
227
|
-
let castedValue = this.typeCaster.castValue(value, fieldType, key);
|
|
228
|
-
return undefined !== castedValue ? castedValue : value;
|
|
202
|
+
missingFields.push(field);
|
|
229
203
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
applyOperator(value, operator, fieldName = null)
|
|
234
|
-
{
|
|
235
|
-
let upperOperator = operator ? operator.toUpperCase() : '';
|
|
236
|
-
if('LIKE' === upperOperator){
|
|
237
|
-
return this.handleLikeOperator(value, fieldName);
|
|
204
|
+
if(0 < missingFields.length){
|
|
205
|
+
Logger.warning('Missing required fields for '+this.tableName()+': '+missingFields.join(', '));
|
|
238
206
|
}
|
|
239
|
-
|
|
240
|
-
'=': value,
|
|
241
|
-
'!=': {not: value},
|
|
242
|
-
'>': {gt: value},
|
|
243
|
-
'>=': {gte: value},
|
|
244
|
-
'<': {lt: value},
|
|
245
|
-
'<=': {lte: value},
|
|
246
|
-
'IN': {in: value},
|
|
247
|
-
'NOT IN': {notIn: value}
|
|
248
|
-
};
|
|
249
|
-
return operatorsMap[upperOperator] || value;
|
|
207
|
+
return data;
|
|
250
208
|
}
|
|
251
209
|
|
|
252
|
-
|
|
210
|
+
async executeWithNormalization(operation, errorMessage, defaultReturn)
|
|
253
211
|
{
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
let numericValue = Number(cleanValue);
|
|
260
|
-
if(!isNaN(numericValue)){
|
|
261
|
-
return numericValue;
|
|
262
|
-
}
|
|
212
|
+
try {
|
|
213
|
+
return this.typeCaster.normalizeReturnData(await operation());
|
|
214
|
+
} catch(error) {
|
|
215
|
+
Logger.error(errorMessage+error.message);
|
|
216
|
+
return defaultReturn;
|
|
263
217
|
}
|
|
264
|
-
return {contains: cleanValue};
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
handleJsonTextSearch(searchValue)
|
|
268
|
-
{
|
|
269
|
-
return {
|
|
270
|
-
string_contains: searchValue
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
isJsonField(fieldName)
|
|
275
|
-
{
|
|
276
|
-
return this.jsonFields && this.jsonFields.has(fieldName);
|
|
277
218
|
}
|
|
278
219
|
|
|
279
220
|
async create(params)
|
|
280
221
|
{
|
|
281
|
-
let preparedData = this.
|
|
222
|
+
let preparedData = this.prepareData(params, {convertRelations: true, isCreate: true});
|
|
282
223
|
this.ensureRequiredFields(preparedData);
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
Logger.error('Create error: '+error.message);
|
|
289
|
-
return false;
|
|
290
|
-
}
|
|
224
|
+
return this.executeWithNormalization(
|
|
225
|
+
() => this.model.create({data: preparedData}),
|
|
226
|
+
'Create error: ',
|
|
227
|
+
false
|
|
228
|
+
);
|
|
291
229
|
}
|
|
292
230
|
|
|
293
231
|
async createWithRelations(params, relations)
|
|
@@ -301,69 +239,45 @@ class PrismaDriver extends BaseDriver
|
|
|
301
239
|
if(0 < relations.length){
|
|
302
240
|
let includeData = this.relationResolver.buildIncludeObjectWithMapping(relations);
|
|
303
241
|
createData.include = includeData.include;
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
309
|
-
let relationData = sc.get(params, relation, sc.get(params, normalizedRelation, null));
|
|
310
|
-
if(sc.isArray(relationData)){
|
|
311
|
-
createData.data[normalizedRelation] = {
|
|
312
|
-
connect: relationData.map(item => ({id: this.typeCaster.castToIdType(item.id)}))
|
|
313
|
-
};
|
|
314
|
-
continue;
|
|
315
|
-
}
|
|
316
|
-
createData.data[normalizedRelation] = {
|
|
317
|
-
connect: {id: this.typeCaster.castToIdType(relationData.id)}
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
try {
|
|
321
|
-
return this.relationResolver.transformRelationResults(
|
|
242
|
+
let relationData = this.relationResolver.buildCreateDataWithRelations(params, relations);
|
|
243
|
+
createData.data = {...createData.data, ...relationData};
|
|
244
|
+
return this.executeWithNormalization(
|
|
245
|
+
async () => this.relationResolver.transformRelationResults(
|
|
322
246
|
await this.model.create(createData),
|
|
323
247
|
includeData.include,
|
|
324
248
|
includeData.mapping
|
|
325
|
-
)
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
return false;
|
|
336
|
-
}
|
|
249
|
+
),
|
|
250
|
+
'Create with relations error: ',
|
|
251
|
+
false
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
return this.executeWithNormalization(
|
|
255
|
+
() => this.model.create(createData),
|
|
256
|
+
'Create with relations error: ',
|
|
257
|
+
false
|
|
258
|
+
);
|
|
337
259
|
}
|
|
338
260
|
|
|
339
261
|
async update(filters, updatePatch)
|
|
340
262
|
{
|
|
341
|
-
let preparedData = this.
|
|
342
|
-
let processedFilters = this.processFilters(filters);
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
} catch(error) {
|
|
349
|
-
Logger.error('Update error: '+error.message);
|
|
350
|
-
return false;
|
|
351
|
-
}
|
|
263
|
+
let preparedData = this.prepareData(updatePatch, {skipObjects: true});
|
|
264
|
+
let processedFilters = this.filterProcessor.processFilters(filters);
|
|
265
|
+
return this.executeWithNormalization(
|
|
266
|
+
() => this.model.updateMany({where: processedFilters, data: preparedData}),
|
|
267
|
+
'Update error: ',
|
|
268
|
+
false
|
|
269
|
+
);
|
|
352
270
|
}
|
|
353
271
|
|
|
354
272
|
async updateBy(field, fieldValue, updatePatch, operator = null)
|
|
355
273
|
{
|
|
356
|
-
let filter = this.createSingleFilter(field, fieldValue, operator);
|
|
357
|
-
let preparedData = this.
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
} catch(error) {
|
|
364
|
-
Logger.error('Update by error: '+error.message);
|
|
365
|
-
return false;
|
|
366
|
-
}
|
|
274
|
+
let filter = this.filterProcessor.createSingleFilter(field, fieldValue, operator);
|
|
275
|
+
let preparedData = this.prepareData(updatePatch, {skipObjects: true});
|
|
276
|
+
return this.executeWithNormalization(
|
|
277
|
+
() => this.model.updateMany({where: filter, data: preparedData}),
|
|
278
|
+
'Update by error: ',
|
|
279
|
+
false
|
|
280
|
+
);
|
|
367
281
|
}
|
|
368
282
|
|
|
369
283
|
async updateById(id, params)
|
|
@@ -373,51 +287,42 @@ class PrismaDriver extends BaseDriver
|
|
|
373
287
|
if(!found){
|
|
374
288
|
return false;
|
|
375
289
|
}
|
|
376
|
-
let preparedData = this.
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
} catch(error) {
|
|
383
|
-
Logger.error('Update by ID error: '+error.message);
|
|
384
|
-
return false;
|
|
385
|
-
}
|
|
290
|
+
let preparedData = this.prepareData(params, {convertRelations: true});
|
|
291
|
+
return this.executeWithNormalization(
|
|
292
|
+
() => this.model.update({where: {[this.idFieldName]: castedId}, data: preparedData}),
|
|
293
|
+
'Update by ID error: ',
|
|
294
|
+
false
|
|
295
|
+
);
|
|
386
296
|
}
|
|
387
297
|
|
|
388
298
|
async upsert(params, filters)
|
|
389
299
|
{
|
|
390
|
-
let preparedData = this.
|
|
391
|
-
let
|
|
392
|
-
if(
|
|
393
|
-
let castedId = this.typeCaster.castToIdType(
|
|
394
|
-
existing = await this.loadById(castedId);
|
|
300
|
+
let preparedData = this.prepareData(params, {convertRelations: true});
|
|
301
|
+
let idValue = params[this.idFieldName];
|
|
302
|
+
if(idValue){
|
|
303
|
+
let castedId = this.typeCaster.castToIdType(idValue);
|
|
304
|
+
let existing = await this.loadById(castedId);
|
|
395
305
|
if(existing){
|
|
396
306
|
let patch = Object.assign({}, preparedData);
|
|
397
|
-
delete patch.
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
} catch(error) {
|
|
404
|
-
Logger.error('Upsert update error: '+error.message);
|
|
405
|
-
return false;
|
|
406
|
-
}
|
|
307
|
+
delete patch[this.idFieldName];
|
|
308
|
+
return this.executeWithNormalization(
|
|
309
|
+
() => this.model.update({where: {[this.idFieldName]: castedId}, data: patch}),
|
|
310
|
+
'Upsert update error: ',
|
|
311
|
+
false
|
|
312
|
+
);
|
|
407
313
|
}
|
|
408
314
|
}
|
|
409
315
|
if(filters){
|
|
410
316
|
let existing = await this.loadOne(filters);
|
|
411
317
|
if(existing){
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
where: {
|
|
318
|
+
return this.executeWithNormalization(
|
|
319
|
+
() => this.model.update({
|
|
320
|
+
where: {[this.idFieldName]: this.typeCaster.castToIdType(existing[this.idFieldName])},
|
|
415
321
|
data: preparedData
|
|
416
|
-
})
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
}
|
|
322
|
+
}),
|
|
323
|
+
'Upsert update by filter error: ',
|
|
324
|
+
false
|
|
325
|
+
);
|
|
421
326
|
}
|
|
422
327
|
}
|
|
423
328
|
return await this.create(preparedData);
|
|
@@ -425,15 +330,12 @@ class PrismaDriver extends BaseDriver
|
|
|
425
330
|
|
|
426
331
|
async delete(filters = {})
|
|
427
332
|
{
|
|
428
|
-
let processedFilters = this.processFilters(filters);
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
Logger.error('Delete error: '+error.message);
|
|
435
|
-
return false;
|
|
436
|
-
}
|
|
333
|
+
let processedFilters = this.filterProcessor.processFilters(filters);
|
|
334
|
+
return this.executeWithNormalization(
|
|
335
|
+
() => this.model.deleteMany({where: processedFilters}),
|
|
336
|
+
'Delete error: ',
|
|
337
|
+
false
|
|
338
|
+
);
|
|
437
339
|
}
|
|
438
340
|
|
|
439
341
|
async deleteById(id)
|
|
@@ -443,27 +345,21 @@ class PrismaDriver extends BaseDriver
|
|
|
443
345
|
if(!found){
|
|
444
346
|
return false;
|
|
445
347
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
Logger.error('Delete by ID error: '+error.message);
|
|
452
|
-
return false;
|
|
453
|
-
}
|
|
348
|
+
return this.executeWithNormalization(
|
|
349
|
+
() => this.model.delete({where: {[this.idFieldName]: castedId}}),
|
|
350
|
+
'Delete by ID error: ',
|
|
351
|
+
false
|
|
352
|
+
);
|
|
454
353
|
}
|
|
455
354
|
|
|
456
355
|
async count(filters)
|
|
457
356
|
{
|
|
458
|
-
let processedFilters = this.processFilters(filters);
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
Logger.error('Count error: '+error.message);
|
|
465
|
-
return 0;
|
|
466
|
-
}
|
|
357
|
+
let processedFilters = this.filterProcessor.processFilters(filters);
|
|
358
|
+
return this.executeWithNormalization(
|
|
359
|
+
() => this.model.count({where: processedFilters}),
|
|
360
|
+
'Count error: ',
|
|
361
|
+
0
|
|
362
|
+
);
|
|
467
363
|
}
|
|
468
364
|
|
|
469
365
|
async countWithRelations(filters, relations)
|
|
@@ -471,36 +367,32 @@ class PrismaDriver extends BaseDriver
|
|
|
471
367
|
if(!sc.isArray(relations) || 0 === relations.length){
|
|
472
368
|
relations = this.getAllRelations();
|
|
473
369
|
}
|
|
474
|
-
let processedFilters = this.processFilters(filters);
|
|
475
|
-
let query = {
|
|
476
|
-
where: processedFilters
|
|
477
|
-
};
|
|
370
|
+
let processedFilters = this.filterProcessor.processFilters(filters);
|
|
371
|
+
let query = {where: processedFilters};
|
|
478
372
|
if(0 < relations.length){
|
|
479
373
|
query.include = this.relationResolver.buildIncludeObjectWithMapping(relations).include;
|
|
480
374
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
}
|
|
375
|
+
return this.executeWithNormalization(
|
|
376
|
+
() => this.model.count(query),
|
|
377
|
+
'Count with relations error: ',
|
|
378
|
+
0
|
|
379
|
+
);
|
|
487
380
|
}
|
|
488
381
|
|
|
489
382
|
async loadAll()
|
|
490
383
|
{
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
}
|
|
384
|
+
return this.executeWithNormalization(
|
|
385
|
+
() => this.model.findMany(this.queryBuilder.buildQueryOptions(this.getQueryOptions())),
|
|
386
|
+
'Load all error: ',
|
|
387
|
+
[]
|
|
388
|
+
);
|
|
497
389
|
}
|
|
498
390
|
|
|
499
391
|
async loadAllWithRelations(relations)
|
|
500
392
|
{
|
|
501
393
|
return this.executeQueryWithRelations(
|
|
502
394
|
(q) => this.model.findMany(q),
|
|
503
|
-
this.buildQueryOptions(),
|
|
395
|
+
this.queryBuilder.buildQueryOptions(this.getQueryOptions()),
|
|
504
396
|
relations,
|
|
505
397
|
'Load all with relations error: ',
|
|
506
398
|
[]
|
|
@@ -509,21 +401,20 @@ class PrismaDriver extends BaseDriver
|
|
|
509
401
|
|
|
510
402
|
async load(filters)
|
|
511
403
|
{
|
|
512
|
-
let processedFilters = this.processFilters(filters);
|
|
513
|
-
let query = this.buildQueryOptions();
|
|
404
|
+
let processedFilters = this.filterProcessor.processFilters(filters);
|
|
405
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions());
|
|
514
406
|
query.where = processedFilters;
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
}
|
|
407
|
+
return this.executeWithNormalization(
|
|
408
|
+
() => this.model.findMany(query),
|
|
409
|
+
'Load error: ',
|
|
410
|
+
[]
|
|
411
|
+
);
|
|
521
412
|
}
|
|
522
413
|
|
|
523
414
|
async loadWithRelations(filters, relations)
|
|
524
415
|
{
|
|
525
|
-
let query = this.buildQueryOptions();
|
|
526
|
-
query.where = this.processFilters(filters);
|
|
416
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions());
|
|
417
|
+
query.where = this.filterProcessor.processFilters(filters);
|
|
527
418
|
return this.executeQueryWithRelations(
|
|
528
419
|
(q) => this.model.findMany(q),
|
|
529
420
|
query,
|
|
@@ -535,21 +426,20 @@ class PrismaDriver extends BaseDriver
|
|
|
535
426
|
|
|
536
427
|
async loadBy(field, fieldValue, operator = null)
|
|
537
428
|
{
|
|
538
|
-
let filter = this.createSingleFilter(field, fieldValue, operator);
|
|
539
|
-
let query = this.buildQueryOptions();
|
|
429
|
+
let filter = this.filterProcessor.createSingleFilter(field, fieldValue, operator);
|
|
430
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions());
|
|
540
431
|
query.where = filter;
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
}
|
|
432
|
+
return this.executeWithNormalization(
|
|
433
|
+
() => this.model.findMany(query),
|
|
434
|
+
'Load by error: ',
|
|
435
|
+
[]
|
|
436
|
+
);
|
|
547
437
|
}
|
|
548
438
|
|
|
549
439
|
async loadByWithRelations(field, fieldValue, relations, operator = null)
|
|
550
440
|
{
|
|
551
|
-
let query = this.buildQueryOptions();
|
|
552
|
-
query.where = this.createSingleFilter(field, fieldValue, operator);
|
|
441
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions());
|
|
442
|
+
query.where = this.filterProcessor.createSingleFilter(field, fieldValue, operator);
|
|
553
443
|
return this.executeQueryWithRelations(
|
|
554
444
|
(q) => this.model.findMany(q),
|
|
555
445
|
query,
|
|
@@ -562,21 +452,18 @@ class PrismaDriver extends BaseDriver
|
|
|
562
452
|
async loadById(id)
|
|
563
453
|
{
|
|
564
454
|
let castedId = this.typeCaster.castToIdType(id);
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
Logger.error('Load by ID error: '+error.message);
|
|
571
|
-
return null;
|
|
572
|
-
}
|
|
455
|
+
return this.executeWithNormalization(
|
|
456
|
+
() => this.model.findUnique({where: {[this.idFieldName]: castedId}}),
|
|
457
|
+
'Load by ID error: ',
|
|
458
|
+
null
|
|
459
|
+
);
|
|
573
460
|
}
|
|
574
461
|
|
|
575
462
|
async loadByIdWithRelations(id, relations)
|
|
576
463
|
{
|
|
577
464
|
return this.executeQueryWithRelations(
|
|
578
465
|
(q) => this.model.findUnique(q),
|
|
579
|
-
{where: {
|
|
466
|
+
{where: {[this.idFieldName]: this.typeCaster.castToIdType(id)}},
|
|
580
467
|
relations,
|
|
581
468
|
'Load by ID with relations error: ',
|
|
582
469
|
null
|
|
@@ -589,35 +476,29 @@ class PrismaDriver extends BaseDriver
|
|
|
589
476
|
if(0 === castedIds.length){
|
|
590
477
|
return [];
|
|
591
478
|
}
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
});
|
|
598
|
-
} catch(error) {
|
|
599
|
-
Logger.error('Load by IDs error: '+error.message);
|
|
600
|
-
return [];
|
|
601
|
-
}
|
|
479
|
+
return this.executeWithNormalization(
|
|
480
|
+
() => this.model.findMany({where: {[this.idFieldName]: {in: castedIds}}}),
|
|
481
|
+
'Load by IDs error: ',
|
|
482
|
+
[]
|
|
483
|
+
);
|
|
602
484
|
}
|
|
603
485
|
|
|
604
486
|
async loadOne(filters)
|
|
605
487
|
{
|
|
606
|
-
let processedFilters = this.processFilters(filters);
|
|
607
|
-
let query = this.buildQueryOptions(false);
|
|
488
|
+
let processedFilters = this.filterProcessor.processFilters(filters);
|
|
489
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions(), false);
|
|
608
490
|
query.where = processedFilters;
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
}
|
|
491
|
+
return this.executeWithNormalization(
|
|
492
|
+
() => this.model.findFirst(query),
|
|
493
|
+
'Load one error: ',
|
|
494
|
+
null
|
|
495
|
+
);
|
|
615
496
|
}
|
|
616
497
|
|
|
617
498
|
async loadOneWithRelations(filters, relations)
|
|
618
499
|
{
|
|
619
|
-
let query = this.buildQueryOptions(false);
|
|
620
|
-
query.where = this.processFilters(filters);
|
|
500
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions(), false);
|
|
501
|
+
query.where = this.filterProcessor.processFilters(filters);
|
|
621
502
|
return this.executeQueryWithRelations(
|
|
622
503
|
(q) => this.model.findFirst(q),
|
|
623
504
|
query,
|
|
@@ -629,21 +510,20 @@ class PrismaDriver extends BaseDriver
|
|
|
629
510
|
|
|
630
511
|
async loadOneBy(field, fieldValue, operator = null)
|
|
631
512
|
{
|
|
632
|
-
let filter = this.createSingleFilter(field, fieldValue, operator);
|
|
633
|
-
let query = this.buildQueryOptions(false);
|
|
513
|
+
let filter = this.filterProcessor.createSingleFilter(field, fieldValue, operator);
|
|
514
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions(), false);
|
|
634
515
|
query.where = filter;
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
}
|
|
516
|
+
return this.executeWithNormalization(
|
|
517
|
+
() => this.model.findFirst(query),
|
|
518
|
+
'Load one by error: ',
|
|
519
|
+
null
|
|
520
|
+
);
|
|
641
521
|
}
|
|
642
522
|
|
|
643
523
|
async loadOneByWithRelations(field, fieldValue, relations, operator = null)
|
|
644
524
|
{
|
|
645
|
-
let query = this.buildQueryOptions(false);
|
|
646
|
-
query.where = this.createSingleFilter(field, fieldValue, operator);
|
|
525
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions(), false);
|
|
526
|
+
query.where = this.filterProcessor.createSingleFilter(field, fieldValue, operator);
|
|
647
527
|
return this.executeQueryWithRelations(
|
|
648
528
|
(q) => this.model.findFirst(q),
|
|
649
529
|
query,
|
|
@@ -653,41 +533,6 @@ class PrismaDriver extends BaseDriver
|
|
|
653
533
|
);
|
|
654
534
|
}
|
|
655
535
|
|
|
656
|
-
buildQueryOptions(useLimit = true)
|
|
657
|
-
{
|
|
658
|
-
let queryOptions = {};
|
|
659
|
-
if(0 < this.select.length){
|
|
660
|
-
queryOptions.select = {};
|
|
661
|
-
for(let field of this.select){
|
|
662
|
-
queryOptions.select[field] = true;
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
if(useLimit && 0 !== this.limit){
|
|
666
|
-
queryOptions.take = this.limit;
|
|
667
|
-
}
|
|
668
|
-
if(0 !== this.offset){
|
|
669
|
-
queryOptions.skip = this.offset;
|
|
670
|
-
}
|
|
671
|
-
if(false !== this.sortBy && false !== this.sortDirection){
|
|
672
|
-
queryOptions.orderBy = {
|
|
673
|
-
[this.sortBy]: this.sortDirection.toLowerCase()
|
|
674
|
-
};
|
|
675
|
-
}
|
|
676
|
-
return queryOptions;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
createSingleFilter(field, fieldValue, operator = null)
|
|
680
|
-
{
|
|
681
|
-
let filter = {};
|
|
682
|
-
let processedValue = this.processFilterValue(fieldValue, field);
|
|
683
|
-
if(null === operator){
|
|
684
|
-
filter[field] = processedValue;
|
|
685
|
-
return filter;
|
|
686
|
-
}
|
|
687
|
-
filter[field] = {operator, value: processedValue};
|
|
688
|
-
return this.processFilters(filter);
|
|
689
|
-
}
|
|
690
|
-
|
|
691
536
|
async executeQueryWithRelations(modelMethod, query, relations, errorMessage, defaultReturn)
|
|
692
537
|
{
|
|
693
538
|
if(!sc.isArray(relations) || 0 === relations.length){
|
|
@@ -697,12 +542,15 @@ class PrismaDriver extends BaseDriver
|
|
|
697
542
|
if(0 < Object.keys(includeData.include).length){
|
|
698
543
|
query.include = includeData.include;
|
|
699
544
|
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
545
|
+
return this.executeWithNormalization(
|
|
546
|
+
async () => this.relationResolver.transformRelationResults(
|
|
547
|
+
await modelMethod(query),
|
|
548
|
+
includeData.include,
|
|
549
|
+
includeData.mapping
|
|
550
|
+
),
|
|
551
|
+
errorMessage,
|
|
552
|
+
defaultReturn
|
|
553
|
+
);
|
|
706
554
|
}
|
|
707
555
|
|
|
708
556
|
}
|