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.
- package/lib/sql-query-generator-base.js +49 -12
- package/package.json +2 -2
|
@@ -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.
|
|
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
|
-
|
|
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.
|
|
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
|
|
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.
|
|
36
|
+
"mythix-orm": "^1.4.6"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"nife": "^1.11.3",
|