mythix-orm-sql-base 1.2.0 → 1.3.2

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.
@@ -70,10 +70,6 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
70
70
  return `${modelName}:${fieldName}`;
71
71
  };
72
72
 
73
- isFieldProjection(str) {
74
- return (/^"[^"]+"."[^"]+"|"\w+:[\w.]+"/i).test(str);
75
- }
76
-
77
73
  parseFieldProjectionToFieldMap(selectStatement) {
78
74
  let firstPart = selectStatement.replace(/[\r\n]/g, ' ').split(/\s+FROM\s+/i)[0].replace(/^SELECT\s+/i, '').trim();
79
75
  let fieldParts = firstPart.split(',');
@@ -89,7 +85,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
89
85
  projectionFieldMap.set(field, field);
90
86
 
91
87
  // If this isn't a field, then add it
92
- if (!this.isFieldProjection(fieldPart))
88
+ if (!this.isFieldIdentifier(fieldPart))
93
89
  projectionFieldMap.set(fieldPart, fieldPart);
94
90
  }
95
91
 
@@ -117,7 +113,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
117
113
  }
118
114
 
119
115
  // eslint-disable-next-line no-unused-vars
120
- generateSelectQueryOperatorFromQueryEngineOperator(operator, value, valueIsReference, options) {
116
+ generateSelectQueryOperatorFromQueryEngineOperator(queryPart, operator, value, valueIsReference, options) {
121
117
  if (LiteralBase.isLiteral(operator))
122
118
  return operator.toString(this.connection);
123
119
 
@@ -148,11 +144,36 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
148
144
  return '<';
149
145
  case 'LTE':
150
146
  return '<=';
147
+ case 'LIKE':
148
+ if (valueIsReference)
149
+ throw new TypeError(`${this.constructor.name}::generateSelectQueryOperatorFromQueryEngineOperator: The "LIKE" operator can not be used for table joins.`);
150
+
151
+ if (!Nife.instanceOf(value, 'string'))
152
+ throw new TypeError(`${this.constructor.name}::generateSelectQueryOperatorFromQueryEngineOperator: The "LIKE" operator requires a string for a value.`);
153
+
154
+ return 'LIKE';
155
+ case 'NOT_LIKE':
156
+ if (valueIsReference)
157
+ throw new TypeError(`${this.constructor.name}::generateSelectQueryOperatorFromQueryEngineOperator: The "NOT LIKE" operator can not be used for table joins.`);
158
+
159
+ if (!Nife.instanceOf(value, 'string'))
160
+ throw new TypeError(`${this.constructor.name}::generateSelectQueryOperatorFromQueryEngineOperator: The "NOT LIKE" operator requires a string for a value.`);
161
+
162
+ return 'NOT LIKE';
151
163
  default:
152
164
  throw new Error(`${this.constructor.name}::generateSelectQueryOperatorFromQueryEngineOperator: Unknown operator "${operator}".`);
153
165
  }
154
166
  }
155
167
 
168
+ formatLikeValue({ value }) {
169
+ return value;
170
+ }
171
+
172
+ // eslint-disable-next-line no-unused-vars
173
+ generateConditionPostfix(context) {
174
+ return '';
175
+ }
176
+
156
177
  generateSelectQueryCondition(queryPart, _value, options) {
157
178
  let value = _value;
158
179
  let field = queryPart.Field;
@@ -162,6 +183,9 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
162
183
  // If the value is an array, then handle the
163
184
  // special "IN" case for an array
164
185
  if (Array.isArray(value)) {
186
+ if (operator !== 'EQ' && operator !== 'NEQ')
187
+ throw new Error(`${this.constructor.name}::generateSelectQueryCondition: Invalid value provided to operator "${operator}": `, value);
188
+
165
189
  // Flatten array, filter down to
166
190
  // only unique items, and remove
167
191
  // anything that we can't match on
@@ -200,7 +224,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
200
224
 
201
225
  let escapedTableName = this.escapeID(this.getTableNameFromQueryPart(queryPart));
202
226
  let escapedColumnName = this.escapeID(field.columnName);
203
- let sqlOperator = this.generateSelectQueryOperatorFromQueryEngineOperator(operator, value, false, options);
227
+ let sqlOperator = this.generateSelectQueryOperatorFromQueryEngineOperator(queryPart, operator, value, false, options);
204
228
 
205
229
  if (QueryEngine.isQuery(value)) {
206
230
  if (!this.queryHasConditions(value._getRawQuery()))
@@ -214,7 +238,13 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
214
238
  return `${escapedTableName}.${escapedColumnName} ${sqlOperator} (${this.generateSelectStatement(value, this.stackAssign(options, { isSubQuery: true }))})`;
215
239
  }
216
240
 
217
- return `${escapedTableName}.${escapedColumnName} ${sqlOperator} ${this.escape(field, value)}`;
241
+ let context = { queryPart, field, sqlOperator, operator, value };
242
+ if (sqlOperator === 'LIKE' || sqlOperator === 'NOT LIKE')
243
+ value = this.formatLikeValue(context);
244
+
245
+ let conditionPostfix = this.generateConditionPostfix(context);
246
+
247
+ return `${escapedTableName}.${escapedColumnName} ${sqlOperator} ${this.escape(field, value)}${(conditionPostfix) ? ` ${conditionPostfix}` : ''}`;
218
248
  }
219
249
 
220
250
  // eslint-disable-next-line no-unused-vars
@@ -231,7 +261,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
231
261
  let leftSideEscapedColumnName = this.escapeID(leftField.columnName);
232
262
  let rightSideEscapedTableName = this.escapeID(this.getTableNameFromQueryPart(rightQueryPart));
233
263
  let rightSideEscapedColumnName = this.escapeID(rightField.columnName);
234
- let sqlOperator = this.generateSelectQueryOperatorFromQueryEngineOperator(operator, undefined, true, options);
264
+ let sqlOperator = this.generateSelectQueryOperatorFromQueryEngineOperator(leftQueryPart, operator, undefined, true, options);
235
265
 
236
266
  return `${leftSideEscapedTableName}.${leftSideEscapedColumnName} ${sqlOperator} ${rightSideEscapedTableName}.${rightSideEscapedColumnName}`;
237
267
  }
@@ -420,6 +450,11 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
420
450
  return sqlParts.join(' ');
421
451
  }
422
452
 
453
+ // eslint-disable-next-line no-unused-vars
454
+ allowOrderFieldWhenNotProjected(orderField, options) {
455
+ return true;
456
+ }
457
+
423
458
  // eslint-disable-next-line no-unused-vars
424
459
  generateOrderClause(_orders, _options) {
425
460
  if (LiteralBase.isLiteral(_orders))
@@ -445,7 +480,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
445
480
  let fieldName = orderField.Field.fieldName;
446
481
  let fqFieldName = `${modelName}:${fieldName}`;
447
482
 
448
- if (!options.projectionFields.has(fqFieldName))
483
+ if (!options.projectionFields.has(fqFieldName) && !this.allowOrderFieldWhenNotProjected(orderField, options))
449
484
  continue;
450
485
  }
451
486
 
@@ -1021,6 +1056,8 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
1021
1056
  queryEngine = Utils.buildQueryFromModelsAttributes(Model, models);
1022
1057
  if (!queryEngine)
1023
1058
  throw new Error(`${this.constructor.name}::generateDeleteStatement: Data provided for "${Model.getModelName()}" model is insufficient to complete operation.`);
1059
+ } else {
1060
+ queryEngine = queryEngine.clone();
1024
1061
  }
1025
1062
  }
1026
1063
 
@@ -1031,9 +1068,9 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
1031
1068
 
1032
1069
  if (where && pkField) {
1033
1070
  if (pkField)
1034
- queryEngine = queryEngine.clone().PROJECT(`${Model.getModelName()}:${pkField.fieldName}`);
1071
+ queryEngine = queryEngine.PROJECT(`${Model.getModelName()}:${pkField.fieldName}`);
1035
1072
 
1036
- let innerSelect = this.generateSelectStatement(queryEngine, this.stackAssign(options, { noProjectionAliases: true }));
1073
+ let innerSelect = this.generateSelectStatement(queryEngine, this.stackAssign(options, { isSubQuery: true, noProjectionAliases: true }));
1037
1074
  let escapedColumnName = this.getEscapedColumnName(Model, pkField, options);
1038
1075
 
1039
1076
  return `DELETE FROM ${escapedTableName} WHERE ${escapedColumnName} IN (${innerSelect})`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mythix-orm-sql-base",
3
- "version": "1.2.0",
3
+ "version": "1.3.2",
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.4.3"
36
+ "mythix-orm": "^1.4.6"
37
37
  },
38
38
  "dependencies": {
39
39
  "nife": "^1.11.3",