@reldens/storage 0.81.0 → 0.83.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 +219 -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,101 @@ 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, isCreate);
|
|
127
156
|
}
|
|
128
|
-
return
|
|
157
|
+
return this.castDataFields(params, skipObjects, isCreate);
|
|
129
158
|
}
|
|
130
159
|
|
|
131
|
-
|
|
160
|
+
castDataFields(params, skipObjects = false, isCreate = false)
|
|
132
161
|
{
|
|
133
162
|
let data = {};
|
|
134
|
-
let relations = {};
|
|
135
163
|
for(let key of Object.keys(params)){
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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)){
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if(isCreate && key === this.idFieldName && this.typeCaster.isNullOrEmpty(value)){
|
|
150
169
|
continue;
|
|
151
170
|
}
|
|
152
171
|
let fieldType = this.fieldTypes[key];
|
|
153
172
|
if(!fieldType){
|
|
154
|
-
if(!this.typeCaster.isNullOrEmpty(
|
|
155
|
-
data[key] =
|
|
173
|
+
if(!skipObjects && !this.typeCaster.isNullOrEmpty(value)){
|
|
174
|
+
data[key] = value;
|
|
156
175
|
}
|
|
157
176
|
continue;
|
|
158
177
|
}
|
|
159
|
-
let castedValue = this.typeCaster.castValue(
|
|
160
|
-
if(
|
|
161
|
-
if(this.typeCaster.isJsonFieldType(fieldType) && null === castedValue){
|
|
178
|
+
let castedValue = this.typeCaster.castValue(value, fieldType, key);
|
|
179
|
+
if(this.typeCaster.isValidCastedValue(castedValue)){
|
|
180
|
+
if(this.typeCaster.isJsonFieldType(fieldType) && null === castedValue && !skipObjects){
|
|
162
181
|
continue;
|
|
163
182
|
}
|
|
164
183
|
data[key] = castedValue;
|
|
165
184
|
}
|
|
166
185
|
}
|
|
167
|
-
return
|
|
186
|
+
return data;
|
|
168
187
|
}
|
|
169
188
|
|
|
170
189
|
ensureRequiredFields(data)
|
|
171
190
|
{
|
|
172
191
|
let missingFields = [];
|
|
173
192
|
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));
|
|
193
|
+
if(sc.hasOwn(data, field)){
|
|
194
194
|
continue;
|
|
195
195
|
}
|
|
196
|
-
if(sc.hasOwn(
|
|
197
|
-
let
|
|
198
|
-
|
|
199
|
-
|
|
196
|
+
if(sc.hasOwn(this.foreignKeyMappings, field)){
|
|
197
|
+
let relationName = this.foreignKeyMappings[field];
|
|
198
|
+
if(sc.hasOwn(data, relationName)){
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
200
201
|
}
|
|
201
|
-
if(sc.
|
|
202
|
-
processedFilters[key] = this.processFilters(value);
|
|
202
|
+
if(sc.hasOwn(this.fieldDefaults, field)){
|
|
203
203
|
continue;
|
|
204
204
|
}
|
|
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);
|
|
205
|
+
missingFields.push(field);
|
|
224
206
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
let castedValue = this.typeCaster.castValue(value, fieldType, key);
|
|
228
|
-
return undefined !== castedValue ? castedValue : value;
|
|
229
|
-
}
|
|
230
|
-
return value;
|
|
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);
|
|
207
|
+
if(0 < missingFields.length){
|
|
208
|
+
Logger.warning('Missing required fields for '+this.tableName()+': '+missingFields.join(', '));
|
|
238
209
|
}
|
|
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;
|
|
210
|
+
return data;
|
|
250
211
|
}
|
|
251
212
|
|
|
252
|
-
|
|
213
|
+
async executeWithNormalization(operation, errorMessage, defaultReturn)
|
|
253
214
|
{
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
let numericValue = Number(cleanValue);
|
|
260
|
-
if(!isNaN(numericValue)){
|
|
261
|
-
return numericValue;
|
|
262
|
-
}
|
|
215
|
+
try {
|
|
216
|
+
return this.typeCaster.normalizeReturnData(await operation());
|
|
217
|
+
} catch(error) {
|
|
218
|
+
Logger.error(errorMessage+error.message);
|
|
219
|
+
return defaultReturn;
|
|
263
220
|
}
|
|
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
221
|
}
|
|
278
222
|
|
|
279
223
|
async create(params)
|
|
280
224
|
{
|
|
281
|
-
let preparedData = this.
|
|
225
|
+
let preparedData = this.prepareData(params, {convertRelations: true, isCreate: true});
|
|
282
226
|
this.ensureRequiredFields(preparedData);
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
Logger.error('Create error: '+error.message);
|
|
289
|
-
return false;
|
|
290
|
-
}
|
|
227
|
+
return this.executeWithNormalization(
|
|
228
|
+
() => this.model.create({data: preparedData}),
|
|
229
|
+
'Create error: ',
|
|
230
|
+
false
|
|
231
|
+
);
|
|
291
232
|
}
|
|
292
233
|
|
|
293
234
|
async createWithRelations(params, relations)
|
|
@@ -301,69 +242,45 @@ class PrismaDriver extends BaseDriver
|
|
|
301
242
|
if(0 < relations.length){
|
|
302
243
|
let includeData = this.relationResolver.buildIncludeObjectWithMapping(relations);
|
|
303
244
|
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(
|
|
245
|
+
let relationData = this.relationResolver.buildCreateDataWithRelations(params, relations);
|
|
246
|
+
createData.data = {...createData.data, ...relationData};
|
|
247
|
+
return this.executeWithNormalization(
|
|
248
|
+
async () => this.relationResolver.transformRelationResults(
|
|
322
249
|
await this.model.create(createData),
|
|
323
250
|
includeData.include,
|
|
324
251
|
includeData.mapping
|
|
325
|
-
)
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
return false;
|
|
336
|
-
}
|
|
252
|
+
),
|
|
253
|
+
'Create with relations error: ',
|
|
254
|
+
false
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
return this.executeWithNormalization(
|
|
258
|
+
() => this.model.create(createData),
|
|
259
|
+
'Create with relations error: ',
|
|
260
|
+
false
|
|
261
|
+
);
|
|
337
262
|
}
|
|
338
263
|
|
|
339
264
|
async update(filters, updatePatch)
|
|
340
265
|
{
|
|
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
|
-
}
|
|
266
|
+
let preparedData = this.prepareData(updatePatch, {skipObjects: true});
|
|
267
|
+
let processedFilters = this.filterProcessor.processFilters(filters);
|
|
268
|
+
return this.executeWithNormalization(
|
|
269
|
+
() => this.model.updateMany({where: processedFilters, data: preparedData}),
|
|
270
|
+
'Update error: ',
|
|
271
|
+
false
|
|
272
|
+
);
|
|
352
273
|
}
|
|
353
274
|
|
|
354
275
|
async updateBy(field, fieldValue, updatePatch, operator = null)
|
|
355
276
|
{
|
|
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
|
-
}
|
|
277
|
+
let filter = this.filterProcessor.createSingleFilter(field, fieldValue, operator);
|
|
278
|
+
let preparedData = this.prepareData(updatePatch, {skipObjects: true});
|
|
279
|
+
return this.executeWithNormalization(
|
|
280
|
+
() => this.model.updateMany({where: filter, data: preparedData}),
|
|
281
|
+
'Update by error: ',
|
|
282
|
+
false
|
|
283
|
+
);
|
|
367
284
|
}
|
|
368
285
|
|
|
369
286
|
async updateById(id, params)
|
|
@@ -373,51 +290,42 @@ class PrismaDriver extends BaseDriver
|
|
|
373
290
|
if(!found){
|
|
374
291
|
return false;
|
|
375
292
|
}
|
|
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
|
-
}
|
|
293
|
+
let preparedData = this.prepareData(params, {convertRelations: true});
|
|
294
|
+
return this.executeWithNormalization(
|
|
295
|
+
() => this.model.update({where: {[this.idFieldName]: castedId}, data: preparedData}),
|
|
296
|
+
'Update by ID error: ',
|
|
297
|
+
false
|
|
298
|
+
);
|
|
386
299
|
}
|
|
387
300
|
|
|
388
301
|
async upsert(params, filters)
|
|
389
302
|
{
|
|
390
|
-
let preparedData = this.
|
|
391
|
-
let
|
|
392
|
-
if(
|
|
393
|
-
let castedId = this.typeCaster.castToIdType(
|
|
394
|
-
existing = await this.loadById(castedId);
|
|
303
|
+
let preparedData = this.prepareData(params, {convertRelations: true});
|
|
304
|
+
let idValue = params[this.idFieldName];
|
|
305
|
+
if(idValue){
|
|
306
|
+
let castedId = this.typeCaster.castToIdType(idValue);
|
|
307
|
+
let existing = await this.loadById(castedId);
|
|
395
308
|
if(existing){
|
|
396
309
|
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
|
-
}
|
|
310
|
+
delete patch[this.idFieldName];
|
|
311
|
+
return this.executeWithNormalization(
|
|
312
|
+
() => this.model.update({where: {[this.idFieldName]: castedId}, data: patch}),
|
|
313
|
+
'Upsert update error: ',
|
|
314
|
+
false
|
|
315
|
+
);
|
|
407
316
|
}
|
|
408
317
|
}
|
|
409
318
|
if(filters){
|
|
410
319
|
let existing = await this.loadOne(filters);
|
|
411
320
|
if(existing){
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
where: {
|
|
321
|
+
return this.executeWithNormalization(
|
|
322
|
+
() => this.model.update({
|
|
323
|
+
where: {[this.idFieldName]: this.typeCaster.castToIdType(existing[this.idFieldName])},
|
|
415
324
|
data: preparedData
|
|
416
|
-
})
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
}
|
|
325
|
+
}),
|
|
326
|
+
'Upsert update by filter error: ',
|
|
327
|
+
false
|
|
328
|
+
);
|
|
421
329
|
}
|
|
422
330
|
}
|
|
423
331
|
return await this.create(preparedData);
|
|
@@ -425,15 +333,12 @@ class PrismaDriver extends BaseDriver
|
|
|
425
333
|
|
|
426
334
|
async delete(filters = {})
|
|
427
335
|
{
|
|
428
|
-
let processedFilters = this.processFilters(filters);
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
Logger.error('Delete error: '+error.message);
|
|
435
|
-
return false;
|
|
436
|
-
}
|
|
336
|
+
let processedFilters = this.filterProcessor.processFilters(filters);
|
|
337
|
+
return this.executeWithNormalization(
|
|
338
|
+
() => this.model.deleteMany({where: processedFilters}),
|
|
339
|
+
'Delete error: ',
|
|
340
|
+
false
|
|
341
|
+
);
|
|
437
342
|
}
|
|
438
343
|
|
|
439
344
|
async deleteById(id)
|
|
@@ -443,27 +348,21 @@ class PrismaDriver extends BaseDriver
|
|
|
443
348
|
if(!found){
|
|
444
349
|
return false;
|
|
445
350
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
Logger.error('Delete by ID error: '+error.message);
|
|
452
|
-
return false;
|
|
453
|
-
}
|
|
351
|
+
return this.executeWithNormalization(
|
|
352
|
+
() => this.model.delete({where: {[this.idFieldName]: castedId}}),
|
|
353
|
+
'Delete by ID error: ',
|
|
354
|
+
false
|
|
355
|
+
);
|
|
454
356
|
}
|
|
455
357
|
|
|
456
358
|
async count(filters)
|
|
457
359
|
{
|
|
458
|
-
let processedFilters = this.processFilters(filters);
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
Logger.error('Count error: '+error.message);
|
|
465
|
-
return 0;
|
|
466
|
-
}
|
|
360
|
+
let processedFilters = this.filterProcessor.processFilters(filters);
|
|
361
|
+
return this.executeWithNormalization(
|
|
362
|
+
() => this.model.count({where: processedFilters}),
|
|
363
|
+
'Count error: ',
|
|
364
|
+
0
|
|
365
|
+
);
|
|
467
366
|
}
|
|
468
367
|
|
|
469
368
|
async countWithRelations(filters, relations)
|
|
@@ -471,36 +370,32 @@ class PrismaDriver extends BaseDriver
|
|
|
471
370
|
if(!sc.isArray(relations) || 0 === relations.length){
|
|
472
371
|
relations = this.getAllRelations();
|
|
473
372
|
}
|
|
474
|
-
let processedFilters = this.processFilters(filters);
|
|
475
|
-
let query = {
|
|
476
|
-
where: processedFilters
|
|
477
|
-
};
|
|
373
|
+
let processedFilters = this.filterProcessor.processFilters(filters);
|
|
374
|
+
let query = {where: processedFilters};
|
|
478
375
|
if(0 < relations.length){
|
|
479
376
|
query.include = this.relationResolver.buildIncludeObjectWithMapping(relations).include;
|
|
480
377
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
}
|
|
378
|
+
return this.executeWithNormalization(
|
|
379
|
+
() => this.model.count(query),
|
|
380
|
+
'Count with relations error: ',
|
|
381
|
+
0
|
|
382
|
+
);
|
|
487
383
|
}
|
|
488
384
|
|
|
489
385
|
async loadAll()
|
|
490
386
|
{
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
}
|
|
387
|
+
return this.executeWithNormalization(
|
|
388
|
+
() => this.model.findMany(this.queryBuilder.buildQueryOptions(this.getQueryOptions())),
|
|
389
|
+
'Load all error: ',
|
|
390
|
+
[]
|
|
391
|
+
);
|
|
497
392
|
}
|
|
498
393
|
|
|
499
394
|
async loadAllWithRelations(relations)
|
|
500
395
|
{
|
|
501
396
|
return this.executeQueryWithRelations(
|
|
502
397
|
(q) => this.model.findMany(q),
|
|
503
|
-
this.buildQueryOptions(),
|
|
398
|
+
this.queryBuilder.buildQueryOptions(this.getQueryOptions()),
|
|
504
399
|
relations,
|
|
505
400
|
'Load all with relations error: ',
|
|
506
401
|
[]
|
|
@@ -509,21 +404,20 @@ class PrismaDriver extends BaseDriver
|
|
|
509
404
|
|
|
510
405
|
async load(filters)
|
|
511
406
|
{
|
|
512
|
-
let processedFilters = this.processFilters(filters);
|
|
513
|
-
let query = this.buildQueryOptions();
|
|
407
|
+
let processedFilters = this.filterProcessor.processFilters(filters);
|
|
408
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions());
|
|
514
409
|
query.where = processedFilters;
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
}
|
|
410
|
+
return this.executeWithNormalization(
|
|
411
|
+
() => this.model.findMany(query),
|
|
412
|
+
'Load error: ',
|
|
413
|
+
[]
|
|
414
|
+
);
|
|
521
415
|
}
|
|
522
416
|
|
|
523
417
|
async loadWithRelations(filters, relations)
|
|
524
418
|
{
|
|
525
|
-
let query = this.buildQueryOptions();
|
|
526
|
-
query.where = this.processFilters(filters);
|
|
419
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions());
|
|
420
|
+
query.where = this.filterProcessor.processFilters(filters);
|
|
527
421
|
return this.executeQueryWithRelations(
|
|
528
422
|
(q) => this.model.findMany(q),
|
|
529
423
|
query,
|
|
@@ -535,21 +429,20 @@ class PrismaDriver extends BaseDriver
|
|
|
535
429
|
|
|
536
430
|
async loadBy(field, fieldValue, operator = null)
|
|
537
431
|
{
|
|
538
|
-
let filter = this.createSingleFilter(field, fieldValue, operator);
|
|
539
|
-
let query = this.buildQueryOptions();
|
|
432
|
+
let filter = this.filterProcessor.createSingleFilter(field, fieldValue, operator);
|
|
433
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions());
|
|
540
434
|
query.where = filter;
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
}
|
|
435
|
+
return this.executeWithNormalization(
|
|
436
|
+
() => this.model.findMany(query),
|
|
437
|
+
'Load by error: ',
|
|
438
|
+
[]
|
|
439
|
+
);
|
|
547
440
|
}
|
|
548
441
|
|
|
549
442
|
async loadByWithRelations(field, fieldValue, relations, operator = null)
|
|
550
443
|
{
|
|
551
|
-
let query = this.buildQueryOptions();
|
|
552
|
-
query.where = this.createSingleFilter(field, fieldValue, operator);
|
|
444
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions());
|
|
445
|
+
query.where = this.filterProcessor.createSingleFilter(field, fieldValue, operator);
|
|
553
446
|
return this.executeQueryWithRelations(
|
|
554
447
|
(q) => this.model.findMany(q),
|
|
555
448
|
query,
|
|
@@ -562,21 +455,18 @@ class PrismaDriver extends BaseDriver
|
|
|
562
455
|
async loadById(id)
|
|
563
456
|
{
|
|
564
457
|
let castedId = this.typeCaster.castToIdType(id);
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
Logger.error('Load by ID error: '+error.message);
|
|
571
|
-
return null;
|
|
572
|
-
}
|
|
458
|
+
return this.executeWithNormalization(
|
|
459
|
+
() => this.model.findUnique({where: {[this.idFieldName]: castedId}}),
|
|
460
|
+
'Load by ID error: ',
|
|
461
|
+
null
|
|
462
|
+
);
|
|
573
463
|
}
|
|
574
464
|
|
|
575
465
|
async loadByIdWithRelations(id, relations)
|
|
576
466
|
{
|
|
577
467
|
return this.executeQueryWithRelations(
|
|
578
468
|
(q) => this.model.findUnique(q),
|
|
579
|
-
{where: {
|
|
469
|
+
{where: {[this.idFieldName]: this.typeCaster.castToIdType(id)}},
|
|
580
470
|
relations,
|
|
581
471
|
'Load by ID with relations error: ',
|
|
582
472
|
null
|
|
@@ -589,35 +479,29 @@ class PrismaDriver extends BaseDriver
|
|
|
589
479
|
if(0 === castedIds.length){
|
|
590
480
|
return [];
|
|
591
481
|
}
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
});
|
|
598
|
-
} catch(error) {
|
|
599
|
-
Logger.error('Load by IDs error: '+error.message);
|
|
600
|
-
return [];
|
|
601
|
-
}
|
|
482
|
+
return this.executeWithNormalization(
|
|
483
|
+
() => this.model.findMany({where: {[this.idFieldName]: {in: castedIds}}}),
|
|
484
|
+
'Load by IDs error: ',
|
|
485
|
+
[]
|
|
486
|
+
);
|
|
602
487
|
}
|
|
603
488
|
|
|
604
489
|
async loadOne(filters)
|
|
605
490
|
{
|
|
606
|
-
let processedFilters = this.processFilters(filters);
|
|
607
|
-
let query = this.buildQueryOptions(false);
|
|
491
|
+
let processedFilters = this.filterProcessor.processFilters(filters);
|
|
492
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions(), false);
|
|
608
493
|
query.where = processedFilters;
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
}
|
|
494
|
+
return this.executeWithNormalization(
|
|
495
|
+
() => this.model.findFirst(query),
|
|
496
|
+
'Load one error: ',
|
|
497
|
+
null
|
|
498
|
+
);
|
|
615
499
|
}
|
|
616
500
|
|
|
617
501
|
async loadOneWithRelations(filters, relations)
|
|
618
502
|
{
|
|
619
|
-
let query = this.buildQueryOptions(false);
|
|
620
|
-
query.where = this.processFilters(filters);
|
|
503
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions(), false);
|
|
504
|
+
query.where = this.filterProcessor.processFilters(filters);
|
|
621
505
|
return this.executeQueryWithRelations(
|
|
622
506
|
(q) => this.model.findFirst(q),
|
|
623
507
|
query,
|
|
@@ -629,21 +513,20 @@ class PrismaDriver extends BaseDriver
|
|
|
629
513
|
|
|
630
514
|
async loadOneBy(field, fieldValue, operator = null)
|
|
631
515
|
{
|
|
632
|
-
let filter = this.createSingleFilter(field, fieldValue, operator);
|
|
633
|
-
let query = this.buildQueryOptions(false);
|
|
516
|
+
let filter = this.filterProcessor.createSingleFilter(field, fieldValue, operator);
|
|
517
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions(), false);
|
|
634
518
|
query.where = filter;
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
}
|
|
519
|
+
return this.executeWithNormalization(
|
|
520
|
+
() => this.model.findFirst(query),
|
|
521
|
+
'Load one by error: ',
|
|
522
|
+
null
|
|
523
|
+
);
|
|
641
524
|
}
|
|
642
525
|
|
|
643
526
|
async loadOneByWithRelations(field, fieldValue, relations, operator = null)
|
|
644
527
|
{
|
|
645
|
-
let query = this.buildQueryOptions(false);
|
|
646
|
-
query.where = this.createSingleFilter(field, fieldValue, operator);
|
|
528
|
+
let query = this.queryBuilder.buildQueryOptions(this.getQueryOptions(), false);
|
|
529
|
+
query.where = this.filterProcessor.createSingleFilter(field, fieldValue, operator);
|
|
647
530
|
return this.executeQueryWithRelations(
|
|
648
531
|
(q) => this.model.findFirst(q),
|
|
649
532
|
query,
|
|
@@ -653,41 +536,6 @@ class PrismaDriver extends BaseDriver
|
|
|
653
536
|
);
|
|
654
537
|
}
|
|
655
538
|
|
|
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
539
|
async executeQueryWithRelations(modelMethod, query, relations, errorMessage, defaultReturn)
|
|
692
540
|
{
|
|
693
541
|
if(!sc.isArray(relations) || 0 === relations.length){
|
|
@@ -697,12 +545,15 @@ class PrismaDriver extends BaseDriver
|
|
|
697
545
|
if(0 < Object.keys(includeData.include).length){
|
|
698
546
|
query.include = includeData.include;
|
|
699
547
|
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
548
|
+
return this.executeWithNormalization(
|
|
549
|
+
async () => this.relationResolver.transformRelationResults(
|
|
550
|
+
await modelMethod(query),
|
|
551
|
+
includeData.include,
|
|
552
|
+
includeData.mapping
|
|
553
|
+
),
|
|
554
|
+
errorMessage,
|
|
555
|
+
defaultReturn
|
|
556
|
+
);
|
|
706
557
|
}
|
|
707
558
|
|
|
708
559
|
}
|