mythix-orm-sql-base 1.1.1 → 1.3.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.
@@ -39,6 +39,32 @@ class SQLConnectionBase extends ConnectionBase {
39
39
  return literal;
40
40
  }
41
41
 
42
+ getLockMode(options) {
43
+ if (!options)
44
+ return { lock: false, read: false, write: false };
45
+
46
+ const throwError = () => {
47
+ throw new Error(`${this.constructor.name}::getLockMode: "lock" must be the name of a model (lock: "ModelName"), or an object specifying the model and the lock mode (lock: { modelName: "ModelName", read: true, write: true, dependents: true, noWait: false }).`);
48
+ };
49
+
50
+ if (Nife.instanceOf(options, 'string')) {
51
+ let Model = this.getModel(options);
52
+ if (!Model)
53
+ throwError();
54
+
55
+ return { lock: true, modelName: options, read: true, write: true };
56
+ } else if (Nife.instanceOf(options, 'object')) {
57
+ let modelName = options.modelName;
58
+ let Model = this.getModel(modelName);
59
+ if (!Model)
60
+ throwError();
61
+
62
+ return Object.assign({ lock: true, read: true, write: true }, options);
63
+ } else {
64
+ throwError();
65
+ }
66
+ }
67
+
42
68
  prepareArrayValuesForSQL(_array) {
43
69
  let array = Nife.arrayFlatten(_array);
44
70
 
@@ -426,7 +452,7 @@ class SQLConnectionBase extends ConnectionBase {
426
452
  // Operation handler
427
453
  async (Model, preparedModels, options, queryGenerator) => {
428
454
  let sqlStr = queryGenerator.generateInsertStatement(Model, preparedModels, options);
429
- let results = await this.query(sqlStr, { logger: options.logger });
455
+ let results = await this.query(sqlStr, options);
430
456
 
431
457
  this.updateModelsFromResults(Model, preparedModels.models, results);
432
458
  },
@@ -439,7 +465,7 @@ class SQLConnectionBase extends ConnectionBase {
439
465
  for (let dirtyModel of dirtyModels) {
440
466
  let Model = dirtyModel.getModel();
441
467
  let sqlStr = queryGenerator.generateUpdateStatement(Model, dirtyModel, null, options);
442
- let results = await this.query(sqlStr, { logger: options.logger });
468
+ let results = await this.query(sqlStr, options);
443
469
 
444
470
  this.updateModelsFromResults(Model, [ dirtyModel ], results);
445
471
  }
@@ -449,7 +475,7 @@ class SQLConnectionBase extends ConnectionBase {
449
475
 
450
476
  // eslint-disable-next-line no-unused-vars
451
477
  async upsert(Model, models, _options) {
452
- throw new Error(`${this.constructor.name}::upsert: This connection type does not support "upsert" operations.`);
478
+ throw new Error(`${this.constructor.name}::upsert: This operation is not supported for this connection type.`);
453
479
  }
454
480
 
455
481
  async update(Model, models, _options) {
@@ -484,7 +510,7 @@ class SQLConnectionBase extends ConnectionBase {
484
510
  if (!sqlStr)
485
511
  continue;
486
512
 
487
- let results = await this.query(sqlStr, { logger: options.logger });
513
+ let results = await this.query(sqlStr, options);
488
514
  this.updateModelsFromResults(Model, [ model ], results);
489
515
  }
490
516
  },
@@ -510,7 +536,7 @@ class SQLConnectionBase extends ConnectionBase {
510
536
 
511
537
  // TODO: Use "RETURNING" to return pks of of updated rows
512
538
 
513
- return await this.query(sqlStr, { logger: options.logger });
539
+ return await this.query(sqlStr, options);
514
540
  }
515
541
 
516
542
  async destroyModels(Model, _models, _options) {
@@ -522,7 +548,7 @@ class SQLConnectionBase extends ConnectionBase {
522
548
  let queryGenerator = this.getQueryGenerator();
523
549
  let sqlStr = queryGenerator.generateDeleteStatement(Model, Model.where.unscoped(), options);
524
550
 
525
- return await this.query(sqlStr, { logger: options.logger });
551
+ return await this.query(sqlStr, options);
526
552
  }
527
553
 
528
554
  let models = Nife.toArray(_models).filter(Boolean);
@@ -560,7 +586,7 @@ class SQLConnectionBase extends ConnectionBase {
560
586
  if (!sqlStr)
561
587
  return;
562
588
 
563
- await this.query(sqlStr, { logger: options.logger });
589
+ await this.query(sqlStr, options);
564
590
  },
565
591
  );
566
592
  }
@@ -588,7 +614,7 @@ class SQLConnectionBase extends ConnectionBase {
588
614
  let options = modelsOrOptions || {};
589
615
  let queryGenerator = this.getQueryGenerator();
590
616
  let sqlStr = queryGenerator.generateDeleteStatement(rootModel, queryEngine, options);
591
- return await this.query(sqlStr, { logger: options.logger });
617
+ return await this.query(sqlStr, options);
592
618
  }
593
619
 
594
620
  async *select(_queryEngine, _options) {
@@ -612,7 +638,7 @@ class SQLConnectionBase extends ConnectionBase {
612
638
  while (true) {
613
639
  let query = queryEngine.clone().LIMIT(batchSize).OFFSET(startIndex);
614
640
  let sqlStatement = queryGenerator.generateSelectStatement(query, options);
615
- let result = await this.query(sqlStatement, { logger: options.logger });
641
+ let result = await this.query(sqlStatement, options);
616
642
 
617
643
  if (!result.rows || result.rows.length === 0)
618
644
  break;
@@ -830,6 +856,50 @@ class SQLConnectionBase extends ConnectionBase {
830
856
  async enableForeignKeyConstraints(enable) {
831
857
  throw new Error(`${this.constructor.name}::enableForeignKeyConstraints: This operation is not supported for this connection type.`);
832
858
  }
859
+
860
+ // Define operations
861
+
862
+ async defineTable() {
863
+ throw new Error(`${this.constructor.name}::defineTable: This operation is not supported for this connection type.`);
864
+ }
865
+
866
+ async defineConstraints() {
867
+ throw new Error(`${this.constructor.name}::defineConstraints: This operation is not supported for this connection type.`);
868
+ }
869
+
870
+ async defineIndexes() {
871
+ throw new Error(`${this.constructor.name}::defineIndexes: This operation is not supported for this connection type.`);
872
+ }
873
+
874
+ // Alter operations
875
+
876
+ async renameTable() {
877
+ throw new Error(`${this.constructor.name}::renameTable: This operation is not supported for this connection type.`);
878
+ }
879
+
880
+ async renameColumn() {
881
+ throw new Error(`${this.constructor.name}::renameColumn: This operation is not supported for this connection type.`);
882
+ }
883
+
884
+ async dropColumn() {
885
+ throw new Error(`${this.constructor.name}::dropColumn: This operation is not supported for this connection type.`);
886
+ }
887
+
888
+ async alterColumn() {
889
+ throw new Error(`${this.constructor.name}::alterColumn: This operation is not supported for this connection type.`);
890
+ }
891
+
892
+ async addColumn() {
893
+ throw new Error(`${this.constructor.name}::addColumn: This operation is not supported for this connection type.`);
894
+ }
895
+
896
+ async addConstraint() {
897
+ throw new Error(`${this.constructor.name}::addConstraint: This operation is not supported for this connection type.`);
898
+ }
899
+
900
+ async addIndex() {
901
+ throw new Error(`${this.constructor.name}::addIndex: This operation is not supported for this connection type.`);
902
+ }
833
903
  }
834
904
 
835
905
  module.exports = SQLConnectionBase;
@@ -117,7 +117,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
117
117
  }
118
118
 
119
119
  // eslint-disable-next-line no-unused-vars
120
- generateSelectQueryOperatorFromQueryEngineOperator(operator, value, valueIsReference, options) {
120
+ generateSelectQueryOperatorFromQueryEngineOperator(queryPart, operator, value, valueIsReference, options) {
121
121
  if (LiteralBase.isLiteral(operator))
122
122
  return operator.toString(this.connection);
123
123
 
@@ -148,11 +148,36 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
148
148
  return '<';
149
149
  case 'LTE':
150
150
  return '<=';
151
+ case 'LIKE':
152
+ if (valueIsReference)
153
+ throw new TypeError(`${this.constructor.name}::generateSelectQueryOperatorFromQueryEngineOperator: The "LIKE" operator can not be used for table joins.`);
154
+
155
+ if (!Nife.instanceOf(value, 'string'))
156
+ throw new TypeError(`${this.constructor.name}::generateSelectQueryOperatorFromQueryEngineOperator: The "LIKE" operator requires a string for a value.`);
157
+
158
+ return 'LIKE';
159
+ case 'NOT_LIKE':
160
+ if (valueIsReference)
161
+ throw new TypeError(`${this.constructor.name}::generateSelectQueryOperatorFromQueryEngineOperator: The "NOT LIKE" operator can not be used for table joins.`);
162
+
163
+ if (!Nife.instanceOf(value, 'string'))
164
+ throw new TypeError(`${this.constructor.name}::generateSelectQueryOperatorFromQueryEngineOperator: The "NOT LIKE" operator requires a string for a value.`);
165
+
166
+ return 'NOT LIKE';
151
167
  default:
152
168
  throw new Error(`${this.constructor.name}::generateSelectQueryOperatorFromQueryEngineOperator: Unknown operator "${operator}".`);
153
169
  }
154
170
  }
155
171
 
172
+ formatLikeValue({ value }) {
173
+ return value;
174
+ }
175
+
176
+ // eslint-disable-next-line no-unused-vars
177
+ generateConditionPostfix(context) {
178
+ return '';
179
+ }
180
+
156
181
  generateSelectQueryCondition(queryPart, _value, options) {
157
182
  let value = _value;
158
183
  let field = queryPart.Field;
@@ -162,6 +187,9 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
162
187
  // If the value is an array, then handle the
163
188
  // special "IN" case for an array
164
189
  if (Array.isArray(value)) {
190
+ if (operator !== 'EQ' && operator !== 'NEQ')
191
+ throw new Error(`${this.constructor.name}::generateSelectQueryCondition: Invalid value provided to operator "${operator}": `, value);
192
+
165
193
  // Flatten array, filter down to
166
194
  // only unique items, and remove
167
195
  // anything that we can't match on
@@ -200,7 +228,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
200
228
 
201
229
  let escapedTableName = this.escapeID(this.getTableNameFromQueryPart(queryPart));
202
230
  let escapedColumnName = this.escapeID(field.columnName);
203
- let sqlOperator = this.generateSelectQueryOperatorFromQueryEngineOperator(operator, value, false, options);
231
+ let sqlOperator = this.generateSelectQueryOperatorFromQueryEngineOperator(queryPart, operator, value, false, options);
204
232
 
205
233
  if (QueryEngine.isQuery(value)) {
206
234
  if (!this.queryHasConditions(value._getRawQuery()))
@@ -214,7 +242,13 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
214
242
  return `${escapedTableName}.${escapedColumnName} ${sqlOperator} (${this.generateSelectStatement(value, this.stackAssign(options, { isSubQuery: true }))})`;
215
243
  }
216
244
 
217
- return `${escapedTableName}.${escapedColumnName} ${sqlOperator} ${this.escape(field, value)}`;
245
+ let context = { queryPart, field, sqlOperator, operator, value };
246
+ if (sqlOperator === 'LIKE' || sqlOperator === 'NOT LIKE')
247
+ value = this.formatLikeValue(context);
248
+
249
+ let conditionPostfix = this.generateConditionPostfix(context);
250
+
251
+ return `${escapedTableName}.${escapedColumnName} ${sqlOperator} ${this.escape(field, value)}${(conditionPostfix) ? ` ${conditionPostfix}` : ''}`;
218
252
  }
219
253
 
220
254
  // eslint-disable-next-line no-unused-vars
@@ -231,7 +265,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
231
265
  let leftSideEscapedColumnName = this.escapeID(leftField.columnName);
232
266
  let rightSideEscapedTableName = this.escapeID(this.getTableNameFromQueryPart(rightQueryPart));
233
267
  let rightSideEscapedColumnName = this.escapeID(rightField.columnName);
234
- let sqlOperator = this.generateSelectQueryOperatorFromQueryEngineOperator(operator, undefined, true, options);
268
+ let sqlOperator = this.generateSelectQueryOperatorFromQueryEngineOperator(leftQueryPart, operator, undefined, true, options);
235
269
 
236
270
  return `${leftSideEscapedTableName}.${leftSideEscapedColumnName} ${sqlOperator} ${rightSideEscapedTableName}.${rightSideEscapedColumnName}`;
237
271
  }
@@ -1112,6 +1146,10 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
1112
1146
 
1113
1147
  return `RETURNING ${returnFields.join(',')}`;
1114
1148
  }
1149
+
1150
+ toConnectionString(queryEngine, options) {
1151
+ return this.generateSelectStatement(queryEngine, options);
1152
+ }
1115
1153
  }
1116
1154
 
1117
1155
  module.exports = SQLQueryGeneratorBase;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mythix-orm-sql-base",
3
- "version": "1.1.1",
3
+ "version": "1.3.0",
4
4
  "description": "SQL base support for Mythix ORM",
5
5
  "main": "lib/index.js",
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.3.0"
36
+ "mythix-orm": "^1.4.4"
37
37
  },
38
38
  "dependencies": {
39
39
  "nife": "^1.11.3",