mythix-orm-sql-base 1.7.3 → 1.8.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.
@@ -10,10 +10,14 @@ const {
10
10
  Model: ModelBase,
11
11
  } = require('mythix-orm');
12
12
 
13
+ const SQLQueryGeneratorBase = require('./sql-query-generator-base');
14
+
13
15
  const SAVE_POINT_NAME_CHARS = [ 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P' ];
14
16
  const MODEL_RELATIONS = Symbol.for('_mythixModelRelations');
15
17
 
16
18
  class SQLConnectionBase extends ConnectionBase {
19
+ static DefaultQueryGenerator = SQLQueryGeneratorBase;
20
+
17
21
  prepareArrayValuesForSQL(_array) {
18
22
  let array = Nife.arrayFlatten(_array);
19
23
 
@@ -85,7 +89,17 @@ class SQLConnectionBase extends ConnectionBase {
85
89
  return (!parts.length) ? null : parts.join(',');
86
90
  };
87
91
 
88
- let context = queryEngine._getRawQueryContext();
92
+ const isEmptyModel = (model) => {
93
+ if (!model)
94
+ return true;
95
+
96
+ if (model._mythixIsEmpty === false)
97
+ return false;
98
+
99
+ return true;
100
+ };
101
+
102
+ let context = queryEngine.getOperationContext();
89
103
  let fields = this.findAllFieldsFromFieldProjectionMap(columns);
90
104
  let rootModelName = context.rootModelName;
91
105
  let modelData = {};
@@ -140,16 +154,31 @@ class SQLConnectionBase extends ConnectionBase {
140
154
  if (!dataContext)
141
155
  dataContext = data[modelName] = {};
142
156
 
157
+ // Track empty models (can happen for left or right table joins)
158
+ if (remoteValue != null && !Object.prototype.hasOwnProperty.call(dataContext, '_mythixIsEmpty')) {
159
+ Object.defineProperties(dataContext, {
160
+ '_mythixIsEmpty': {
161
+ writable: true,
162
+ enumerable: false,
163
+ configurable: true,
164
+ value: false,
165
+ },
166
+ });
167
+ }
168
+
143
169
  dataContext[field.fieldName] = remoteValue;
144
170
  }
145
171
 
146
172
  let rootModel;
147
173
  for (let j = 0, jl = modelNames.length; j < jl; j++) {
148
- let modelName = modelNames[j];
149
- let info = modelInfo[modelName];
150
- let models = modelData[modelName];
151
- let model = data[modelName];
152
- let pkFieldName = info.pkFieldName;
174
+ let modelName = modelNames[j];
175
+ let model = data[modelName];
176
+ if (isEmptyModel(model))
177
+ continue;
178
+
179
+ let info = modelInfo[modelName];
180
+ let models = modelData[modelName];
181
+ let pkFieldName = info.pkFieldName;
153
182
  let index;
154
183
 
155
184
  if (!models)
@@ -209,7 +238,7 @@ class SQLConnectionBase extends ConnectionBase {
209
238
  if (Nife.isEmpty(modelDataMap))
210
239
  return [];
211
240
 
212
- let queryContext = queryEngine._getRawQueryContext();
241
+ let queryContext = queryEngine.getOperationContext();
213
242
  let rootModelName = queryContext.rootModelName;
214
243
  let RootModel = queryContext.rootModel;
215
244
  if (!rootModelName || !RootModel)
@@ -373,6 +402,7 @@ class SQLConnectionBase extends ConnectionBase {
373
402
  throw new Error(`${this.constructor.name}::update: Model's primary key is empty. Models being updated must have a valid primary key.`);
374
403
 
375
404
  query = query[primaryKeyFieldName].EQ(pkFieldValue);
405
+ query = await this.finalizeQuery('update', query, options);
376
406
 
377
407
  let sqlStr = queryGenerator.generateUpdateStatement(Model, model, query, options);
378
408
  if (!sqlStr)
@@ -394,11 +424,13 @@ class SQLConnectionBase extends ConnectionBase {
394
424
  if (!queryEngine)
395
425
  throw new Error(`${this.constructor.name}::updateAll: Model class or query is required to update.`);
396
426
 
397
- let rootModel = queryEngine._getRawQueryContext().rootModel;
427
+ let options = Object.assign({}, _options || {}, { isUpdateOperation: true });
428
+ queryEngine = await this.finalizeQuery('update', queryEngine, options);
429
+
430
+ let rootModel = queryEngine.getOperationContext().rootModel;
398
431
  if (!rootModel)
399
432
  throw new Error(`${this.constructor.name}::updateAll: Root model not found, and is required to update.`);
400
433
 
401
- let options = Object.assign({}, _options || {}, { isUpdateOperation: true });
402
434
  let queryGenerator = this.getQueryGenerator();
403
435
  let sqlStr = queryGenerator.generateUpdateStatement(rootModel, model, queryEngine, options);
404
436
 
@@ -416,8 +448,9 @@ class SQLConnectionBase extends ConnectionBase {
416
448
  if (options.truncate !== true)
417
449
  return;
418
450
 
451
+ let query = await this.finalizeQuery('delete', Model.where(this).unscoped(), options);
419
452
  let queryGenerator = this.getQueryGenerator();
420
- let sqlStr = queryGenerator.generateDeleteStatement(Model, Model.where(this).unscoped(), options);
453
+ let sqlStr = queryGenerator.generateDeleteStatement(Model, query, options);
421
454
 
422
455
  return await this.query(sqlStr, options);
423
456
  }
@@ -453,7 +486,8 @@ class SQLConnectionBase extends ConnectionBase {
453
486
  if (Nife.isEmpty(pkIDs))
454
487
  return;
455
488
 
456
- let sqlStr = queryGenerator.generateDeleteStatement(Model, Model.where(this).id.EQ(pkIDs));
489
+ let query = await this.finalizeQuery('delete', Model.where(this).id.EQ(pkIDs), options);
490
+ let sqlStr = queryGenerator.generateDeleteStatement(Model, query);
457
491
  if (!sqlStr)
458
492
  return;
459
493
 
@@ -478,11 +512,13 @@ class SQLConnectionBase extends ConnectionBase {
478
512
  if (!queryEngine)
479
513
  throw new Error(`${this.constructor.name}::destroy: Model class or query is required to destroy.`);
480
514
 
481
- let rootModel = queryEngine._getRawQueryContext().rootModel;
515
+ let options = modelsOrOptions || {};
516
+ queryEngine = await this.finalizeQuery('delete', queryEngine, options);
517
+
518
+ let rootModel = queryEngine.getOperationContext().rootModel;
482
519
  if (!rootModel)
483
520
  throw new Error(`${this.constructor.name}::destroy: Root model not found, and is required to destroy.`);
484
521
 
485
- let options = modelsOrOptions || {};
486
522
  let queryGenerator = this.getQueryGenerator();
487
523
  let sqlStr = queryGenerator.generateDeleteStatement(rootModel, queryEngine, options);
488
524
  return await this.query(sqlStr, options);
@@ -500,8 +536,10 @@ class SQLConnectionBase extends ConnectionBase {
500
536
  throw new TypeError(`${this.constructor.name}::select: First argument must be a model class or a query.`);
501
537
  }
502
538
 
503
- let queryContext = queryEngine._getRawQueryContext();
504
- let options = _options || {};
539
+ let options = _options || {};
540
+ queryEngine = await this.finalizeQuery('read', queryEngine, options);
541
+
542
+ let queryContext = queryEngine.getOperationContext();
505
543
  let batchSize = options.batchSize || 500;
506
544
  let startIndex = queryContext.offset || 0;
507
545
  let queryGenerator = this.getQueryGenerator();
@@ -549,9 +587,10 @@ class SQLConnectionBase extends ConnectionBase {
549
587
  if (!queryEngine)
550
588
  throw new TypeError(`${this.constructor.name}::aggregate: First argument must be a model class or a query.`);
551
589
 
590
+ queryEngine = await this.finalizeQuery('read', queryEngine, options);
552
591
  queryEngine = queryEngine.clone();
553
592
 
554
- let queryContext = queryEngine._getRawQueryContext();
593
+ let queryContext = queryEngine.getOperationContext();
555
594
  let distinct = queryContext.distinct;
556
595
  if (distinct) {
557
596
  let fullyQualifiedFieldName = distinct.getFullyQualifiedFieldName();
@@ -586,7 +625,7 @@ class SQLConnectionBase extends ConnectionBase {
586
625
  if (!queryEngine)
587
626
  throw new TypeError(`${this.constructor.name}::average: First argument must be a model class or a query.`);
588
627
 
589
- let rootModel = queryEngine._getRawQueryContext().rootModel;
628
+ let rootModel = queryEngine.getOperationContext().rootModel;
590
629
  let field = Utils.fieldToFullyQualifiedName(_field, rootModel);
591
630
 
592
631
  return await this.aggregate(queryEngine, new Literals.AverageLiteral(field), options);
@@ -597,7 +636,9 @@ class SQLConnectionBase extends ConnectionBase {
597
636
  if (!queryEngine)
598
637
  throw new TypeError(`${this.constructor.name}::count: First argument must be a model class or a query.`);
599
638
 
600
- let rootModel = queryEngine._getRawQueryContext().rootModel;
639
+ queryEngine = await this.finalizeQuery('read', queryEngine, options);
640
+
641
+ let rootModel = queryEngine.getOperationContext().rootModel;
601
642
  let field = (_field) ? Utils.fieldToFullyQualifiedName(_field, rootModel) : null;
602
643
 
603
644
  return await this.aggregate(queryEngine, new Literals.CountLiteral(field), options);
@@ -608,7 +649,9 @@ class SQLConnectionBase extends ConnectionBase {
608
649
  if (!queryEngine)
609
650
  throw new TypeError(`${this.constructor.name}::min: First argument must be a model class or a query.`);
610
651
 
611
- let rootModel = queryEngine._getRawQueryContext().rootModel;
652
+ queryEngine = await this.finalizeQuery('read', queryEngine, options);
653
+
654
+ let rootModel = queryEngine.getOperationContext().rootModel;
612
655
  let field = Utils.fieldToFullyQualifiedName(_field, rootModel);
613
656
 
614
657
  return await this.aggregate(queryEngine, new Literals.MinLiteral(field), options);
@@ -619,7 +662,9 @@ class SQLConnectionBase extends ConnectionBase {
619
662
  if (!queryEngine)
620
663
  throw new TypeError(`${this.constructor.name}::max: First argument must be a model class or a query.`);
621
664
 
622
- let rootModel = queryEngine._getRawQueryContext().rootModel;
665
+ queryEngine = await this.finalizeQuery('read', queryEngine, options);
666
+
667
+ let rootModel = queryEngine.getOperationContext().rootModel;
623
668
  let field = Utils.fieldToFullyQualifiedName(_field, rootModel);
624
669
 
625
670
  return await this.aggregate(queryEngine, new Literals.MaxLiteral(field), options);
@@ -630,7 +675,9 @@ class SQLConnectionBase extends ConnectionBase {
630
675
  if (!queryEngine)
631
676
  throw new TypeError(`${this.constructor.name}::sum: First argument must be a model class or a query.`);
632
677
 
633
- let rootModel = queryEngine._getRawQueryContext().rootModel;
678
+ queryEngine = await this.finalizeQuery('read', queryEngine, options);
679
+
680
+ let rootModel = queryEngine.getOperationContext().rootModel;
634
681
  let field = Utils.fieldToFullyQualifiedName(_field, rootModel);
635
682
 
636
683
  return await this.aggregate(queryEngine, new Literals.SumLiteral(field), options);
@@ -658,7 +705,9 @@ class SQLConnectionBase extends ConnectionBase {
658
705
  throw new TypeError(`${this.constructor.name}::pluck: First argument must be a model class or a query.`);
659
706
  }
660
707
 
661
- let queryContext = queryEngine._getRawQueryContext();
708
+ queryEngine = await this.finalizeQuery('read', queryEngine, options);
709
+
710
+ let queryContext = queryEngine.getOperationContext();
662
711
  let rootModel = queryContext.rootModel;
663
712
  let rootModelName = rootModel.getModelName();
664
713
 
@@ -227,7 +227,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
227
227
  let sqlOperator = this.generateSelectQueryOperatorFromQueryEngineOperator(queryPart, operator, value, false, options);
228
228
 
229
229
  if (QueryEngine.isQuery(value)) {
230
- if (!value._queryHasConditions())
230
+ if (!value.queryHasConditions())
231
231
  return '';
232
232
 
233
233
  if (sqlOperator === '=')
@@ -339,7 +339,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
339
339
  items.push(joinInfo);
340
340
  };
341
341
 
342
- let query = queryEngine._getRawQuery();
342
+ let query = queryEngine.getOperationStack();
343
343
  let joins = new Map();
344
344
 
345
345
  for (let i = 0, il = query.length; i < il; i++) {
@@ -353,11 +353,11 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
353
353
 
354
354
  // If the query has a condition, then it is a sub-query
355
355
  // not a join
356
- if (operatorValue._getRawQueryContext().condition)
356
+ if (operatorValue.getOperationContext().condition)
357
357
  continue;
358
358
 
359
359
  let joinType = this.generateSQLJoinTypeFromQueryEngineJoinType(queryPart.joinType, queryPart.joinOuter, options);
360
- let joinInfo = this.getJoinTableInfoFromQueryContexts(queryPart, operatorValue._getRawQueryContext(), joinType, options);
360
+ let joinInfo = this.getJoinTableInfoFromQueryContexts(queryPart, operatorValue.getOperationContext(), joinType, options);
361
361
 
362
362
  addToJoins(joinInfo);
363
363
  }
@@ -391,7 +391,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
391
391
  return '';
392
392
  };
393
393
 
394
- let query = queryEngine._getRawQuery();
394
+ let query = queryEngine.getOperationStack();
395
395
  let sqlParts = [];
396
396
  let hasValue = false;
397
397
 
@@ -590,7 +590,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
590
590
  if (options.includeRelations === true)
591
591
  queryEngine = queryEngine.clone().PROJECT('*');
592
592
 
593
- let rootModel = queryEngine._getRawQueryContext().rootModel;
593
+ let rootModel = queryEngine.getOperationContext().rootModel;
594
594
  if (!rootModel)
595
595
  throw new Error(`${this.constructor.name}::generateSelectStatement: No root model found.`);
596
596
 
@@ -1138,8 +1138,8 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
1138
1138
  }
1139
1139
 
1140
1140
  let escapedTableName = this.getEscapedTableName(Model, options);
1141
- if (queryEngine && queryEngine._queryHasConditions()) {
1142
- if (queryEngine._queryHasJoins()) {
1141
+ if (queryEngine && queryEngine.queryHasConditions()) {
1142
+ if (queryEngine.queryHasJoins()) {
1143
1143
  let pkField = Model.getPrimaryKeyField();
1144
1144
  if (!pkField)
1145
1145
  throw new Error(`${this.constructor.name}::generateDeleteStatement: Can not delete using table joins on a table with no primary key field.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mythix-orm-sql-base",
3
- "version": "1.7.3",
3
+ "version": "1.8.0",
4
4
  "description": "SQL base support for Mythix ORM",
5
5
  "main": "lib/index",
6
6
  "type": "commonjs",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "homepage": "https://github.com/th317erd/mythix-orm-sql-base#readme",
35
35
  "peerDependencies": {
36
- "mythix-orm": "^1.8.3"
36
+ "mythix-orm": "^1.10.2"
37
37
  },
38
38
  "dependencies": {
39
39
  "luxon": "^3.1.0",