mythix-orm 1.11.3 → 1.11.5
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/connection/connection-base.js +21 -1
- package/lib/connection/literals/average-literal.js +4 -0
- package/lib/connection/literals/count-literal.js +4 -0
- package/lib/connection/literals/literal-base.js +15 -0
- package/lib/connection/literals/literal-field-base.js +6 -0
- package/lib/connection/literals/max-literal.js +4 -0
- package/lib/connection/literals/min-literal.js +4 -0
- package/lib/connection/literals/sum-literal.js +4 -0
- package/lib/connection/query-generator-base.d.ts +1 -80
- package/lib/connection/query-generator-base.js +15 -317
- package/lib/model.js +6 -4
- package/lib/query-engine/model-scope.js +2 -0
- package/package.json +1 -1
|
@@ -229,7 +229,7 @@ class ConnectionBase extends EventEmitter {
|
|
|
229
229
|
}, _options || {});
|
|
230
230
|
|
|
231
231
|
if (!options.queryGenerator)
|
|
232
|
-
options.queryGenerator =
|
|
232
|
+
options.queryGenerator = this.createQueryGenerator(options);
|
|
233
233
|
|
|
234
234
|
Object.defineProperties(this, {
|
|
235
235
|
'dialect': {
|
|
@@ -270,6 +270,26 @@ class ConnectionBase extends EventEmitter {
|
|
|
270
270
|
this.registerModels(options.models);
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
+
/// This method will create the default query generator
|
|
274
|
+
|
|
275
|
+
// eslint-disable-next-line no-unused-vars
|
|
276
|
+
createQueryGenerator(options) {
|
|
277
|
+
if (this.constructor.DefaultQueryGenerator)
|
|
278
|
+
return new this.constructor.DefaultQueryGenerator(this);
|
|
279
|
+
|
|
280
|
+
return new QueryGeneratorBase(this);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
stackAssign(obj, ..._args) {
|
|
284
|
+
let newObj = Object.create(obj || {});
|
|
285
|
+
let args = _args.filter(Boolean);
|
|
286
|
+
|
|
287
|
+
if (args.length > 0)
|
|
288
|
+
Object.assign(newObj, ...args);
|
|
289
|
+
|
|
290
|
+
return newObj;
|
|
291
|
+
}
|
|
292
|
+
|
|
273
293
|
/// This method is an internal method that parses
|
|
274
294
|
/// the "lock mode" options passed to a call to
|
|
275
295
|
/// <see>Connection.transaction</see>.
|
|
@@ -43,6 +43,14 @@ class LiteralBase {
|
|
|
43
43
|
return (this.isLiteral(value) && value.constructor && value.constructor.name === this.name);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
static isAggregate() {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
isAggregate() {
|
|
51
|
+
return this.constructor.isAggregate();
|
|
52
|
+
}
|
|
53
|
+
|
|
46
54
|
constructor(literal, options) {
|
|
47
55
|
Object.defineProperties(this, {
|
|
48
56
|
'literal': {
|
|
@@ -87,6 +95,9 @@ class LiteralBase {
|
|
|
87
95
|
if (LiteralBase.isLiteral(definition))
|
|
88
96
|
return definition;
|
|
89
97
|
|
|
98
|
+
if (!definition.fieldNames)
|
|
99
|
+
return definition;
|
|
100
|
+
|
|
90
101
|
let field = connection.getField(definition.fieldNames[0], definition.modelName);
|
|
91
102
|
if (!field) {
|
|
92
103
|
if (definition.fieldNames[0] && definition.modelName) {
|
|
@@ -109,6 +120,10 @@ class LiteralBase {
|
|
|
109
120
|
toString() {
|
|
110
121
|
return this.literal;
|
|
111
122
|
}
|
|
123
|
+
|
|
124
|
+
valueOf() {
|
|
125
|
+
return this.literal;
|
|
126
|
+
}
|
|
112
127
|
}
|
|
113
128
|
|
|
114
129
|
module.exports = LiteralBase;
|
|
@@ -20,6 +20,8 @@ class LiteralFieldBase extends LiteralBase {
|
|
|
20
20
|
} catch (error) {
|
|
21
21
|
if (isRequired)
|
|
22
22
|
throw error;
|
|
23
|
+
|
|
24
|
+
definition = fullyQualifiedName;
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -47,6 +49,10 @@ class LiteralFieldBase extends LiteralBase {
|
|
|
47
49
|
|
|
48
50
|
return this.definitionToField(connection, this.definition);
|
|
49
51
|
}
|
|
52
|
+
|
|
53
|
+
valueOf() {
|
|
54
|
+
return this.definition;
|
|
55
|
+
}
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
module.exports = LiteralFieldBase;
|
|
@@ -1,97 +1,18 @@
|
|
|
1
1
|
import Field from '../field';
|
|
2
2
|
import { GenericObject } from '../interfaces/common';
|
|
3
|
-
import { ModelClass } from '../model';
|
|
4
3
|
import { QueryEngine } from '../query-engine';
|
|
5
4
|
import ConnectionBase from './connection-base';
|
|
6
5
|
import { AverageLiteral, CountLiteral, DistinctLiteral, FieldLiteral, MaxLiteral, MinLiteral, SumLiteral } from './literals';
|
|
7
6
|
import LiteralBase from './literals/literal-base';
|
|
8
7
|
|
|
9
|
-
export declare interface GetEscapedFieldNameOptions {
|
|
10
|
-
fieldNameOnly?: boolean;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export declare interface GetEscapedTableNameNameOptions {
|
|
14
|
-
tableNamePrefix?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export declare interface GetEscapedColumnNameOptions extends GetEscapedTableNameNameOptions {
|
|
18
|
-
columnNamePrefix?: string
|
|
19
|
-
columnNameOnly?: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export declare interface GetEscapedProjectionNameOptions extends GetEscapedColumnNameOptions, GetEscapedFieldNameOptions {
|
|
23
|
-
noProjectionAliases?: boolean;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export declare interface GetEscapedModelFieldsOptions extends GetEscapedProjectionNameOptions {
|
|
27
|
-
asProjection?: boolean;
|
|
28
|
-
asColumn?: boolean;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export declare interface ProjectedFieldInfo {
|
|
32
|
-
projectedName: string;
|
|
33
|
-
Model: ModelClass;
|
|
34
|
-
modelName: string;
|
|
35
|
-
Field: Field;
|
|
36
|
-
fieldName: string;
|
|
37
|
-
direction: string;
|
|
38
|
-
fullFieldName: string;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export declare interface JoinTableInfo {
|
|
42
|
-
operator: string;
|
|
43
|
-
joinType: string | LiteralBase;
|
|
44
|
-
rootModelName: string;
|
|
45
|
-
joinModel: ModelClass;
|
|
46
|
-
joinModelName: string;
|
|
47
|
-
leftSideModel: ModelClass;
|
|
48
|
-
leftSideModelName: string;
|
|
49
|
-
leftQueryContext: GenericObject;
|
|
50
|
-
leftSideField: Field;
|
|
51
|
-
rightSideModel: ModelClass;
|
|
52
|
-
rightSideModelName: string;
|
|
53
|
-
rightQueryContext: GenericObject;
|
|
54
|
-
rightSideField: Field;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export declare interface FieldDirectionInfo {
|
|
58
|
-
hasDirection: boolean;
|
|
59
|
-
direction: string;
|
|
60
|
-
fieldName: string;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export declare interface FieldOrderInfo {
|
|
64
|
-
Model: ModelClass;
|
|
65
|
-
Field: Field;
|
|
66
|
-
direction: string;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
8
|
declare class QueryGeneratorBase {
|
|
70
9
|
public constructor(connection);
|
|
71
10
|
public stackAssign(obj: GenericObject, ...args: Array<GenericObject>): GenericObject;
|
|
72
11
|
public setOptionsCache(options: GenericObject, keyPath: string, value: any): void;
|
|
73
12
|
public escape(field: Field, value: any, options?: GenericObject): string;
|
|
74
13
|
public escapeID(value: LiteralBase | string, options?: GenericObject): string;
|
|
75
|
-
public getEscapedFieldName(Model: ModelClass | null | undefined, field: Field, options?: GetEscapedFieldNameOptions): string;
|
|
76
|
-
public getEscapedColumnName(Model: ModelClass | null | undefined, field: Field, options?: GetEscapedColumnNameOptions): string;
|
|
77
|
-
public getEscapedTableName(modelOrField: ModelClass | Field, options?: GetEscapedTableNameNameOptions): string;
|
|
78
|
-
public getEscapedProjectionName(Model: ModelClass | null | undefined, field: Field, options?: GetEscapedProjectionNameOptions): string;
|
|
79
|
-
public getEscapedModelFields(Model: ModelClass, options?: GetEscapedModelFieldsOptions): { [key: string]: string };
|
|
80
|
-
public isFieldIdentifier(value: string): boolean;
|
|
81
|
-
public getProjectedFields(queryEngine: QueryEngine, options?: GenericObject, asMap?: false | undefined): Array<string>;
|
|
82
|
-
public getProjectedFields(queryEngine: QueryEngine, options?: GenericObject, asMap?: true): Map<string, string>;
|
|
83
|
-
|
|
84
|
-
public getJoinTableInfoFromQueryContexts(
|
|
85
|
-
leftQueryContext: GenericObject,
|
|
86
|
-
rightQueryContext: GenericObject,
|
|
87
|
-
joinType: string | LiteralBase,
|
|
88
|
-
options?: GenericObject
|
|
89
|
-
): JoinTableInfo;
|
|
90
|
-
|
|
91
|
-
public getFieldDirectionSpecifier(order: LiteralBase): LiteralBase;
|
|
92
|
-
public getFieldDirectionSpecifier(order: string | Field): FieldDirectionInfo;
|
|
93
14
|
|
|
94
|
-
public
|
|
15
|
+
public _getLiteralAlias(literal: LiteralBase, options?: GenericObject);
|
|
95
16
|
public _averageLiteralToString(literal: AverageLiteral, options?: GenericObject): string;
|
|
96
17
|
public _countLiteralToString(literal: CountLiteral, options?: GenericObject): string;
|
|
97
18
|
public _distinctLiteralToString(literal: DistinctLiteral, options?: GenericObject): string;
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const Nife = require('nife');
|
|
4
|
-
const Literals = require('./literals');
|
|
5
|
-
const LiteralBase = Literals.LiteralBase;
|
|
6
|
-
|
|
7
3
|
/// The base query generator class.
|
|
8
4
|
///
|
|
9
5
|
/// Alias: QueryGenerator
|
|
@@ -19,14 +15,8 @@ class QueryGeneratorBase {
|
|
|
19
15
|
});
|
|
20
16
|
}
|
|
21
17
|
|
|
22
|
-
stackAssign(obj, ...
|
|
23
|
-
|
|
24
|
-
let args = _args.filter(Boolean);
|
|
25
|
-
|
|
26
|
-
if (args.length > 0)
|
|
27
|
-
Object.assign(newObj, ...args);
|
|
28
|
-
|
|
29
|
-
return newObj;
|
|
18
|
+
stackAssign(obj, ...args) {
|
|
19
|
+
return this.connection.stackAssign(obj, ...args);
|
|
30
20
|
}
|
|
31
21
|
|
|
32
22
|
escape(...args) {
|
|
@@ -37,331 +27,39 @@ class QueryGeneratorBase {
|
|
|
37
27
|
return this.connection.escapeID(...args);
|
|
38
28
|
}
|
|
39
29
|
|
|
40
|
-
getEscapedFieldName(_Model, field, options) {
|
|
41
|
-
let isString = Nife.instanceOf(field, 'string');
|
|
42
|
-
let fieldName = (isString) ? field : field.fieldName;
|
|
43
|
-
let Model = _Model;
|
|
44
|
-
|
|
45
|
-
if (!Model && field && !isString)
|
|
46
|
-
Model = field.Model;
|
|
47
|
-
|
|
48
|
-
if (!Model || (options && options.fieldNameOnly === true))
|
|
49
|
-
return this.escapeID(fieldName);
|
|
50
|
-
else
|
|
51
|
-
return `"${field.Model.getModelName()}:${fieldName}"`;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
getEscapedColumnName(_Model, field, options) {
|
|
55
|
-
let isString = Nife.instanceOf(field, 'string');
|
|
56
|
-
let columnName = (isString) ? field : (field.columnName || field.fieldName);
|
|
57
|
-
let Model = _Model;
|
|
58
|
-
|
|
59
|
-
if (!Model && field && !isString)
|
|
60
|
-
Model = field.Model;
|
|
61
|
-
|
|
62
|
-
if (options && options.columnNamePrefix)
|
|
63
|
-
columnName = `${options.columnNamePrefix}${columnName}`;
|
|
64
|
-
|
|
65
|
-
if (!Model || (options && options.columnNameOnly === true))
|
|
66
|
-
return this.escapeID(columnName);
|
|
67
|
-
else
|
|
68
|
-
return `${this.getEscapedTableName(Model)}.${this.escapeID(columnName)}`;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
getEscapedTableName(_modelOrField, options) {
|
|
72
|
-
let Model = (_modelOrField.Model) ? _modelOrField.Model : _modelOrField;
|
|
73
|
-
let tableName = Model.getTableName(this.connection);
|
|
74
|
-
|
|
75
|
-
if (options && options.tableNamePrefix)
|
|
76
|
-
tableName = `${options.tableNamePrefix}${tableName}`;
|
|
77
|
-
|
|
78
|
-
return this.escapeID(tableName);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// eslint-disable-next-line no-unused-vars
|
|
82
|
-
getEscapedProjectionName(Model, field, options) {
|
|
83
|
-
if (options && options.noProjectionAliases)
|
|
84
|
-
return this.getEscapedColumnName(Model, field, options);
|
|
85
|
-
else
|
|
86
|
-
return `${this.getEscapedColumnName(Model, field, options)} AS ${(options && options.as) ? this.escapeID(options.as) : this.getEscapedFieldName(Model, field, options)}`;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// eslint-disable-next-line no-unused-vars
|
|
90
|
-
getEscapedModelFields(Model, options) {
|
|
91
|
-
let fields = {};
|
|
92
|
-
let modelName = Model.getModelName();
|
|
93
|
-
|
|
94
|
-
Model.iterateFields(({ field, fieldName }) => {
|
|
95
|
-
if (field.type.isVirtual())
|
|
96
|
-
return;
|
|
97
|
-
|
|
98
|
-
let result;
|
|
99
|
-
|
|
100
|
-
if (options && options.asProjection)
|
|
101
|
-
result = this.getEscapedProjectionName(Model, field, options);
|
|
102
|
-
else if (options && options.asColumn)
|
|
103
|
-
result = this.getEscapedColumnName(Model, field, options);
|
|
104
|
-
else
|
|
105
|
-
result = this.getEscapedFieldName(Model, field, options);
|
|
106
|
-
|
|
107
|
-
fields[`${modelName}:${fieldName}`] = result;
|
|
108
|
-
}, (options && options.fields));
|
|
109
|
-
|
|
110
|
-
return fields;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
isFieldIdentifier(str) {
|
|
114
|
-
return (/^"[^"]+"."[^"]+"|"\w+:[\w.]+"/i).test(str);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
getQueryEngineOrder(queryEngine, _options) {
|
|
118
|
-
let options = _options || {};
|
|
119
|
-
let context = queryEngine.getOperationContext();
|
|
120
|
-
let order = context.order;
|
|
121
|
-
|
|
122
|
-
return (order && order.size) ? order : this.connection.getDefaultOrder(context.rootModel, options);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
getProjectedFields(queryEngine, _options, asMap) {
|
|
126
|
-
let options = this.stackAssign(_options || {}, { isProjection: true });
|
|
127
|
-
let context = queryEngine.getOperationContext();
|
|
128
|
-
let queryProjection = new Map(context.projection);
|
|
129
|
-
let order = this.getQueryEngineOrder(queryEngine, options);
|
|
130
|
-
let allProjectionFields = new Map();
|
|
131
|
-
let allModelsUsedInQuery = queryEngine.getAllModelsUsedInQuery();
|
|
132
|
-
|
|
133
|
-
if (!options.isSubQuery && order && order.size) {
|
|
134
|
-
let contextOrderSupport = this.connection.isOrderSupportedInContext(options);
|
|
135
|
-
if (contextOrderSupport) {
|
|
136
|
-
for (let [ fullyQualifiedFieldName, orderScope ] of order) {
|
|
137
|
-
if (!queryProjection.has(fullyQualifiedFieldName))
|
|
138
|
-
queryProjection.set(fullyQualifiedFieldName, orderScope);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
for (let [ fullyQualifiedName, projectedScope ] of queryProjection) {
|
|
144
|
-
let { value } = projectedScope;
|
|
145
|
-
|
|
146
|
-
if (Nife.instanceOf(value, 'string')) {
|
|
147
|
-
// Raw string is treated as a literal
|
|
148
|
-
allProjectionFields.set(fullyQualifiedName, value);
|
|
149
|
-
continue;
|
|
150
|
-
} else if (LiteralBase.isLiteral(value)) {
|
|
151
|
-
let result = value.toString(this.connection, options);
|
|
152
|
-
allProjectionFields.set(result || fullyQualifiedName, result || fullyQualifiedName);
|
|
153
|
-
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (allModelsUsedInQuery.indexOf(value.Model) < 0)
|
|
158
|
-
continue;
|
|
159
|
-
|
|
160
|
-
let escapedFieldName = this.getEscapedProjectionName(value.Model, value, options);
|
|
161
|
-
allProjectionFields.set(`${value.Model.getModelName()}:${value.fieldName}`, escapedFieldName);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (asMap === true)
|
|
165
|
-
return allProjectionFields;
|
|
166
|
-
else
|
|
167
|
-
return Array.from(allProjectionFields.values());
|
|
168
|
-
}
|
|
169
|
-
|
|
170
30
|
// eslint-disable-next-line no-unused-vars
|
|
171
|
-
getJoinTableInfoFromQueryContexts(leftQueryContext, rightQueryContext, joinType, options) {
|
|
172
|
-
let rootModel = leftQueryContext.rootModel;
|
|
173
|
-
let rootModelName = rootModel.getModelName();
|
|
174
|
-
let leftSideModel = leftQueryContext.Model;
|
|
175
|
-
let leftSideModelName = leftQueryContext.modelName;
|
|
176
|
-
if (!leftSideModel)
|
|
177
|
-
throw new Error(`${this.constructor.name}::getJoinTableInfoFromQueryEngine: Invalid operation: No model found for left-side of join statement.`);
|
|
178
|
-
|
|
179
|
-
let leftSideField = leftQueryContext.Field;
|
|
180
|
-
if (!leftSideField)
|
|
181
|
-
throw new Error(`${this.constructor.name}::getJoinTableInfoFromQueryEngine: Invalid operation: No left-side field found to match on for table join statement.`);
|
|
182
|
-
|
|
183
|
-
let isNot = leftQueryContext.not;
|
|
184
|
-
let operator = (isNot) ? leftQueryContext.inverseOperator : leftQueryContext.operator;
|
|
185
|
-
let rightSideModel = rightQueryContext.Model;
|
|
186
|
-
let rightSideModelName = rightQueryContext.modelName;
|
|
187
|
-
if (!rightSideModel)
|
|
188
|
-
throw new Error(`${this.constructor.name}::getJoinTableInfoFromQueryEngine: Invalid operation: No model found for right-side of join statement.`);
|
|
189
|
-
|
|
190
|
-
let rightSideField = rightQueryContext.Field;
|
|
191
|
-
if (!rightSideField)
|
|
192
|
-
throw new Error(`${this.constructor.name}::getJoinTableInfoFromQueryEngine: Invalid operation: No right-side field found to match on for table join statement.`);
|
|
193
|
-
|
|
194
|
-
let swapJoinRelation = (rightSideModelName === rootModelName);
|
|
195
|
-
let joinModel = (swapJoinRelation) ? leftSideModel : rightSideModel;
|
|
196
|
-
let joinModelName = (swapJoinRelation) ? leftSideModelName : rightSideModelName;
|
|
197
|
-
|
|
198
|
-
return {
|
|
199
|
-
operator,
|
|
200
|
-
joinType,
|
|
201
|
-
rootModelName,
|
|
202
|
-
|
|
203
|
-
joinModel,
|
|
204
|
-
joinModelName,
|
|
205
|
-
|
|
206
|
-
leftSideModel,
|
|
207
|
-
leftSideModelName,
|
|
208
|
-
leftQueryContext,
|
|
209
|
-
leftSideField,
|
|
210
|
-
|
|
211
|
-
rightSideModel,
|
|
212
|
-
rightSideModelName,
|
|
213
|
-
rightQueryContext,
|
|
214
|
-
rightSideField,
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
getFieldDirectionSpecifier(order) {
|
|
219
|
-
if (!order)
|
|
220
|
-
return order;
|
|
221
|
-
|
|
222
|
-
if (LiteralBase.isLiteral(order))
|
|
223
|
-
return order;
|
|
224
|
-
|
|
225
|
-
// Is this a field?
|
|
226
|
-
if (order && order.Model && order.fieldName) {
|
|
227
|
-
return {
|
|
228
|
-
hasDirection: false,
|
|
229
|
-
direction: '+',
|
|
230
|
-
fieldName: order.fieldName,
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
let sign;
|
|
235
|
-
|
|
236
|
-
let fieldName = ('' + order).replace(/^[+-]+/, (m) => {
|
|
237
|
-
sign = m.charAt(0);
|
|
238
|
-
return '';
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
return {
|
|
242
|
-
hasDirection: !!sign,
|
|
243
|
-
direction: (sign === '-') ? '-' : '+',
|
|
244
|
-
fieldName,
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
getQuerySliceFromQueryPart(queryPart) {
|
|
249
|
-
let operationStack = queryPart.operationStack;
|
|
250
|
-
let index = operationStack.indexOf(queryPart);
|
|
251
|
-
|
|
252
|
-
return operationStack.slice(index);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
_getLiteralAlias(literal, options) {
|
|
256
|
-
let as = (literal.options && literal.options.as) || (options && options.as);
|
|
257
|
-
if (Nife.isEmpty(as))
|
|
258
|
-
return '';
|
|
259
|
-
|
|
260
|
-
return ` AS ${this.escapeID(as)}`;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
31
|
_averageLiteralToString(literal, options) {
|
|
264
|
-
|
|
265
|
-
return;
|
|
266
|
-
|
|
267
|
-
let field = literal.getField(this.connection);
|
|
268
|
-
let escapedFieldName;
|
|
269
|
-
|
|
270
|
-
if (LiteralBase.isLiteral(field))
|
|
271
|
-
escapedFieldName = field.toString(this.connection, options);
|
|
272
|
-
else
|
|
273
|
-
escapedFieldName = this.getEscapedColumnName(field.Model, field, this.stackAssign(options, literal.options));
|
|
274
|
-
|
|
275
|
-
return `AVG(${escapedFieldName})${this._getLiteralAlias(literal, options)}`;
|
|
32
|
+
throw new Error(`${this.constructor.name}::_averageLiteralToString: This operation is not supported for this connection type.`);
|
|
276
33
|
}
|
|
277
34
|
|
|
35
|
+
// eslint-disable-next-line no-unused-vars
|
|
278
36
|
_countLiteralToString(literal, options) {
|
|
279
|
-
|
|
280
|
-
return;
|
|
281
|
-
|
|
282
|
-
let field = literal.getField(this.connection);
|
|
283
|
-
let escapedFieldName;
|
|
284
|
-
|
|
285
|
-
if (field) {
|
|
286
|
-
if (LiteralBase.isLiteral(field))
|
|
287
|
-
escapedFieldName = field.toString(this.connection, options);
|
|
288
|
-
else
|
|
289
|
-
escapedFieldName = this.getEscapedColumnName(field.Model, field, this.stackAssign(options, literal.options));
|
|
290
|
-
} else {
|
|
291
|
-
escapedFieldName = '*';
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
return `COUNT(${escapedFieldName})${this._getLiteralAlias(literal, options)}`;
|
|
37
|
+
throw new Error(`${this.constructor.name}::_countLiteralToString: This operation is not supported for this connection type.`);
|
|
295
38
|
}
|
|
296
39
|
|
|
40
|
+
// eslint-disable-next-line no-unused-vars
|
|
297
41
|
_distinctLiteralToString(literal, options) {
|
|
298
|
-
|
|
299
|
-
return;
|
|
300
|
-
|
|
301
|
-
let field = literal.getField(this.connection);
|
|
302
|
-
if (!field)
|
|
303
|
-
return 'DISTINCT';
|
|
304
|
-
|
|
305
|
-
if (LiteralBase.isLiteral(field))
|
|
306
|
-
return `DISTINCT ON(${field.toString(this.connection, this.stackAssign(options, { noProjectionAliases: true }))})`;
|
|
307
|
-
|
|
308
|
-
return `DISTINCT ON(${this.getEscapedColumnName(field.Model, field, this.stackAssign(options, literal.options, { noProjectionAliases: true }))})`;
|
|
42
|
+
throw new Error(`${this.constructor.name}::_distinctLiteralToString: This operation is not supported for this connection type.`);
|
|
309
43
|
}
|
|
310
44
|
|
|
45
|
+
// eslint-disable-next-line no-unused-vars
|
|
311
46
|
_fieldLiteralToString(literal, options) {
|
|
312
|
-
|
|
313
|
-
return;
|
|
314
|
-
|
|
315
|
-
let field = literal.getField(this.connection);
|
|
316
|
-
if (LiteralBase.isLiteral(field))
|
|
317
|
-
return field.toString(this.connection, options);
|
|
318
|
-
|
|
319
|
-
return this.getEscapedProjectionName(field.Model, field, this.stackAssign(options, { noProjectionAliases: (options && !options.isProjection) }, literal.options));
|
|
47
|
+
throw new Error(`${this.constructor.name}::_fieldLiteralToString: This operation is not supported for this connection type.`);
|
|
320
48
|
}
|
|
321
49
|
|
|
50
|
+
// eslint-disable-next-line no-unused-vars
|
|
322
51
|
_maxLiteralToString(literal, options) {
|
|
323
|
-
|
|
324
|
-
return;
|
|
325
|
-
|
|
326
|
-
let field = literal.getField(this.connection);
|
|
327
|
-
let escapedFieldName;
|
|
328
|
-
|
|
329
|
-
if (LiteralBase.isLiteral(field))
|
|
330
|
-
escapedFieldName = field.toString(this.connection, options);
|
|
331
|
-
else
|
|
332
|
-
escapedFieldName = this.getEscapedColumnName(field.Model, field, this.stackAssign(options, literal.options));
|
|
333
|
-
|
|
334
|
-
return `MAX(${escapedFieldName})${this._getLiteralAlias(literal, options)}`;
|
|
52
|
+
throw new Error(`${this.constructor.name}::_maxLiteralToString: This operation is not supported for this connection type.`);
|
|
335
53
|
}
|
|
336
54
|
|
|
55
|
+
// eslint-disable-next-line no-unused-vars
|
|
337
56
|
_minLiteralToString(literal, options) {
|
|
338
|
-
|
|
339
|
-
return;
|
|
340
|
-
|
|
341
|
-
let field = literal.getField(this.connection);
|
|
342
|
-
let escapedFieldName;
|
|
343
|
-
|
|
344
|
-
if (LiteralBase.isLiteral(field))
|
|
345
|
-
escapedFieldName = field.toString(this.connection, options);
|
|
346
|
-
else
|
|
347
|
-
escapedFieldName = this.getEscapedColumnName(field.Model, field, this.stackAssign(options, literal.options));
|
|
348
|
-
|
|
349
|
-
return `MIN(${escapedFieldName})${this._getLiteralAlias(literal, options)}`;
|
|
57
|
+
throw new Error(`${this.constructor.name}::_minLiteralToString: This operation is not supported for this connection type.`);
|
|
350
58
|
}
|
|
351
59
|
|
|
60
|
+
// eslint-disable-next-line no-unused-vars
|
|
352
61
|
_sumLiteralToString(literal, options) {
|
|
353
|
-
|
|
354
|
-
return;
|
|
355
|
-
|
|
356
|
-
let field = literal.getField(this.connection);
|
|
357
|
-
let escapedFieldName;
|
|
358
|
-
|
|
359
|
-
if (LiteralBase.isLiteral(field))
|
|
360
|
-
escapedFieldName = field.toString(this.connection, options);
|
|
361
|
-
else
|
|
362
|
-
escapedFieldName = this.getEscapedColumnName(field.Model, field, this.stackAssign(options, literal.options));
|
|
363
|
-
|
|
364
|
-
return `SUM(${escapedFieldName})${this._getLiteralAlias(literal, options)}`;
|
|
62
|
+
throw new Error(`${this.constructor.name}::_sumLiteralToString: This operation is not supported for this connection type.`);
|
|
365
63
|
}
|
|
366
64
|
|
|
367
65
|
// eslint-disable-next-line no-unused-vars
|
package/lib/model.js
CHANGED
|
@@ -450,14 +450,16 @@ class Model {
|
|
|
450
450
|
/// a connection to your models. This will allow you to provide a
|
|
451
451
|
/// connection directly when you create the model, which can make
|
|
452
452
|
/// interacting with the model less tiresome. i.e. `new Model(null, { connection })`.
|
|
453
|
-
_getConnection(
|
|
453
|
+
_getConnection(_connection) {
|
|
454
|
+
let connection = _connection;
|
|
454
455
|
if (connection)
|
|
455
456
|
return connection;
|
|
456
457
|
|
|
457
|
-
|
|
458
|
-
|
|
458
|
+
connection = this.constructor._getConnection();
|
|
459
|
+
if (connection)
|
|
460
|
+
return connection;
|
|
459
461
|
|
|
460
|
-
return this.
|
|
462
|
+
return this._connection;
|
|
461
463
|
}
|
|
462
464
|
|
|
463
465
|
static getConnection(_connection) {
|
|
@@ -353,6 +353,8 @@ class ModelScope extends QueryEngineBase {
|
|
|
353
353
|
distinctValue = new DistinctLiteral(`${fullyQualifiedName.Model.getModelName()}:${fullyQualifiedName.fieldName}`);
|
|
354
354
|
} else if (LiteralBase.isLiteral(fullyQualifiedName)) {
|
|
355
355
|
distinctValue = new DistinctLiteral(fullyQualifiedName);
|
|
356
|
+
} else if (!fullyQualifiedName) {
|
|
357
|
+
distinctValue = null;
|
|
356
358
|
} else {
|
|
357
359
|
throw new TypeError(`QueryEngine::ModelScope::DISTINCT: Invalid value provided [${(fullyQualifiedName) ? fullyQualifiedName.toString() : fullyQualifiedName}]. All values provided must be strings, fields, or literals.`);
|
|
358
360
|
}
|