@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.
@@ -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,101 @@ 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, isCreate);
127
156
  }
128
- return data;
157
+ return this.castDataFields(params, skipObjects, isCreate);
129
158
  }
130
159
 
131
- prepareDataWithRelations(params, isCreate = false)
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
- 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)){
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(params[key])){
155
- data[key] = params[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(params[key], fieldType, key);
160
- if(undefined !== castedValue){
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 {...data, ...relations};
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(!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));
193
+ if(sc.hasOwn(data, field)){
194
194
  continue;
195
195
  }
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;
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.isObject(value) && !sc.isArray(value)){
202
- processedFilters[key] = this.processFilters(value);
202
+ if(sc.hasOwn(this.fieldDefaults, field)){
203
203
  continue;
204
204
  }
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);
205
+ missingFields.push(field);
224
206
  }
225
- let fieldType = this.fieldTypes[key];
226
- if(fieldType){
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
- 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;
210
+ return data;
250
211
  }
251
212
 
252
- handleLikeOperator(value, fieldName)
213
+ async executeWithNormalization(operation, errorMessage, defaultReturn)
253
214
  {
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
- }
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.prepareDataWithRelations(params, true);
225
+ let preparedData = this.prepareData(params, {convertRelations: true, isCreate: true});
282
226
  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
- }
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
- 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(
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
- } 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
- }
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.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
- }
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.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
- }
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.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
- }
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.prepareDataWithRelations(params);
391
- let existing = false;
392
- if(params.id){
393
- let castedId = this.typeCaster.castToIdType(params.id);
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.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
- }
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
- try {
413
- return await this.model.update({
414
- where: {id: this.typeCaster.castToIdType(existing.id)},
321
+ return this.executeWithNormalization(
322
+ () => this.model.update({
323
+ where: {[this.idFieldName]: this.typeCaster.castToIdType(existing[this.idFieldName])},
415
324
  data: preparedData
416
- });
417
- } catch(error) {
418
- Logger.error('Upsert update by filter error: '+error.message);
419
- return false;
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
- 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
- }
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
- 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
- }
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
- 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
- }
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
- try {
482
- return await this.model.count(query);
483
- } catch(error) {
484
- Logger.error('Count with relations error: '+error.message);
485
- return 0;
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
- try {
492
- return await this.model.findMany(this.buildQueryOptions());
493
- } catch(error) {
494
- Logger.error('Load all error: '+error.message);
495
- return [];
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
- try {
516
- return await this.model.findMany(query);
517
- } catch(error) {
518
- Logger.error('Load error: '+error.message);
519
- return [];
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
- try {
542
- return await this.model.findMany(query);
543
- } catch(error) {
544
- Logger.error('Load by error: '+error.message);
545
- return [];
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
- 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
- }
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: {id: this.typeCaster.castToIdType(id)}},
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
- 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
- }
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
- try {
610
- return await this.model.findFirst(query);
611
- } catch(error) {
612
- Logger.error('Load one error: '+error.message);
613
- return null;
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
- try {
636
- return await this.model.findFirst(query);
637
- } catch(error) {
638
- Logger.error('Load one by error: '+error.message);
639
- return null;
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
- 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
- }
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
  }