@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.
@@ -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
- relationAliases: {},
51
- metadataLoader: this.metadataLoader
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
- this.relationAliases = this.relationResolver.buildRelationAliases(this.tableName());
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
- prepareData(params)
137
+ getQueryOptions()
115
138
  {
116
- let data = {};
117
- for(let key of Object.keys(params)){
118
- let fieldType = this.fieldTypes[key];
119
- if(!fieldType){
120
- data[key] = params[key];
121
- continue;
122
- }
123
- let castedValue = this.typeCaster.castValue(params[key], fieldType, key);
124
- if(undefined !== castedValue){
125
- data[key] = castedValue;
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 data;
157
+ return this.castDataFields(params, skipObjects);
129
158
  }
130
159
 
131
- prepareDataWithRelations(params, isCreate = false)
160
+ castDataFields(params, skipObjects = false)
132
161
  {
133
162
  let data = {};
134
- let relations = {};
135
163
  for(let key of Object.keys(params)){
136
- if(sc.hasOwn(this.foreignKeyMappings, key)){
137
- let relationName = this.foreignKeyMappings[key];
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(params[key])){
155
- data[key] = params[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(params[key], fieldType, key);
160
- if(undefined !== castedValue){
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 {...data, ...relations};
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(!sc.hasOwn(data, field)){
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(value, 'operator') && sc.hasOwn(value, 'value')){
197
- let operatorValue = this.processFilterValue(value.value, key);
198
- processedFilters[key] = this.applyOperator(operatorValue, value.operator, key);
199
- continue;
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.isObject(value) && !sc.isArray(value)){
202
- processedFilters[key] = this.processFilters(value);
199
+ if(sc.hasOwn(this.fieldDefaults, field)){
203
200
  continue;
204
201
  }
205
- processedFilters[key] = this.processFilterValue(value, key);
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
- 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);
204
+ if(0 < missingFields.length){
205
+ Logger.warning('Missing required fields for '+this.tableName()+': '+missingFields.join(', '));
238
206
  }
239
- let operatorsMap = {
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
- handleLikeOperator(value, fieldName)
210
+ async executeWithNormalization(operation, errorMessage, defaultReturn)
253
211
  {
254
- let cleanValue = String(value).replace(/%/g, '');
255
- if(this.typeCaster.isJsonFieldByName(fieldName) || this.isJsonField(fieldName)){
256
- return this.handleJsonTextSearch(cleanValue);
257
- }
258
- if('id' === fieldName || sc.hasOwn(this.referenceFields, fieldName)){
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.prepareDataWithRelations(params, true);
222
+ let preparedData = this.prepareData(params, {convertRelations: true, isCreate: true});
282
223
  this.ensureRequiredFields(preparedData);
283
- try {
284
- return await this.model.create({
285
- data: preparedData
286
- });
287
- } catch(error) {
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
- for(let relation of relations){
305
- let normalizedRelation = this.relationResolver.normalizeRelationName(relation);
306
- if(!sc.hasOwn(params, relation) && !sc.hasOwn(params, normalizedRelation)){
307
- continue;
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
- } catch(error) {
327
- Logger.error('Create with relations error: '+error.message);
328
- return false;
329
- }
330
- }
331
- try {
332
- return await this.model.create(createData);
333
- } catch(error) {
334
- Logger.error('Create with relations error: '+error.message);
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.prepareDataWithRelations(updatePatch);
342
- let processedFilters = this.processFilters(filters);
343
- try {
344
- return await this.model.updateMany({
345
- where: processedFilters,
346
- data: preparedData
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.prepareDataWithRelations(updatePatch);
358
- try {
359
- return await this.model.updateMany({
360
- where: filter,
361
- data: preparedData
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.prepareDataWithRelations(params);
377
- try {
378
- return await this.model.update({
379
- where: {id: castedId},
380
- data: preparedData
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.prepareDataWithRelations(params);
391
- let existing = false;
392
- if(params.id){
393
- let castedId = this.typeCaster.castToIdType(params.id);
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.id;
398
- try {
399
- return await this.model.update({
400
- where: {id: castedId},
401
- data: patch
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
- try {
413
- return await this.model.update({
414
- where: {id: this.typeCaster.castToIdType(existing.id)},
318
+ return this.executeWithNormalization(
319
+ () => this.model.update({
320
+ where: {[this.idFieldName]: this.typeCaster.castToIdType(existing[this.idFieldName])},
415
321
  data: preparedData
416
- });
417
- } catch(error) {
418
- Logger.error('Upsert update by filter error: '+error.message);
419
- return false;
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
- try {
430
- return await this.model.deleteMany({
431
- where: processedFilters
432
- });
433
- } catch(error) {
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
- try {
447
- return await this.model.delete({
448
- where: {id: castedId}
449
- });
450
- } catch(error) {
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
- try {
460
- return await this.model.count({
461
- where: processedFilters
462
- });
463
- } catch(error) {
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
- try {
482
- return await this.model.count(query);
483
- } catch(error) {
484
- Logger.error('Count with relations error: '+error.message);
485
- return 0;
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
- try {
492
- return await this.model.findMany(this.buildQueryOptions());
493
- } catch(error) {
494
- Logger.error('Load all error: '+error.message);
495
- return [];
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
- try {
516
- return await this.model.findMany(query);
517
- } catch(error) {
518
- Logger.error('Load error: '+error.message);
519
- return [];
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
- try {
542
- return await this.model.findMany(query);
543
- } catch(error) {
544
- Logger.error('Load by error: '+error.message);
545
- return [];
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
- try {
566
- return await this.model.findUnique({
567
- where: {id: castedId}
568
- });
569
- } catch(error) {
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: {id: this.typeCaster.castToIdType(id)}},
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
- try {
593
- return await this.model.findMany({
594
- where: {
595
- id: {in: castedIds}
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
- try {
610
- return await this.model.findFirst(query);
611
- } catch(error) {
612
- Logger.error('Load one error: '+error.message);
613
- return null;
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
- try {
636
- return await this.model.findFirst(query);
637
- } catch(error) {
638
- Logger.error('Load one by error: '+error.message);
639
- return null;
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
- try {
701
- return this.relationResolver.transformRelationResults(await modelMethod(query), includeData.include, includeData.mapping);
702
- } catch(error) {
703
- Logger.error(errorMessage+error.message);
704
- return defaultReturn;
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
  }