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.
@@ -229,7 +229,7 @@ class ConnectionBase extends EventEmitter {
229
229
  }, _options || {});
230
230
 
231
231
  if (!options.queryGenerator)
232
- options.queryGenerator = new QueryGeneratorBase(this);
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>.
@@ -3,6 +3,10 @@
3
3
  const LiteralFieldBase = require('./literal-field-base');
4
4
 
5
5
  class AverageLiteral extends LiteralFieldBase {
6
+ static isAggregate() {
7
+ return true;
8
+ }
9
+
6
10
  toString(connection, options) {
7
11
  if (!connection)
8
12
  return `${this.constructor.name} {}`;
@@ -7,6 +7,10 @@ class CountLiteral extends LiteralFieldBase {
7
7
  return false;
8
8
  }
9
9
 
10
+ static isAggregate() {
11
+ return true;
12
+ }
13
+
10
14
  toString(connection, options) {
11
15
  if (!connection)
12
16
  return `${this.constructor.name} {}`;
@@ -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;
@@ -3,6 +3,10 @@
3
3
  const LiteralFieldBase = require('./literal-field-base');
4
4
 
5
5
  class MaxLiteral extends LiteralFieldBase {
6
+ static isAggregate() {
7
+ return true;
8
+ }
9
+
6
10
  toString(connection, options) {
7
11
  if (!connection)
8
12
  return `${this.constructor.name} {}`;
@@ -3,6 +3,10 @@
3
3
  const LiteralFieldBase = require('./literal-field-base');
4
4
 
5
5
  class MinLiteral extends LiteralFieldBase {
6
+ static isAggregate() {
7
+ return true;
8
+ }
9
+
6
10
  toString(connection, options) {
7
11
  if (!connection)
8
12
  return `${this.constructor.name} {}`;
@@ -3,6 +3,10 @@
3
3
  const LiteralFieldBase = require('./literal-field-base');
4
4
 
5
5
  class SumLiteral extends LiteralFieldBase {
6
+ static isAggregate() {
7
+ return true;
8
+ }
9
+
6
10
  toString(connection, options) {
7
11
  if (!connection)
8
12
  return `${this.constructor.name} {}`;
@@ -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 getQuerySliceFromQueryPart(queryPart: GenericObject): Array<GenericObject>;
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, ..._args) {
23
- let newObj = Object.create(obj || {});
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
- if (!literal || !LiteralBase.isLiteral(literal))
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
- if (!literal || !LiteralBase.isLiteral(literal))
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
- if (!literal || !LiteralBase.isLiteral(literal))
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
- if (!literal || !LiteralBase.isLiteral(literal))
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
- if (!literal || !LiteralBase.isLiteral(literal))
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
- if (!literal || !LiteralBase.isLiteral(literal))
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
- if (!literal || !LiteralBase.isLiteral(literal))
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(connection) {
453
+ _getConnection(_connection) {
454
+ let connection = _connection;
454
455
  if (connection)
455
456
  return connection;
456
457
 
457
- if (this._connection)
458
- return this._connection;
458
+ connection = this.constructor._getConnection();
459
+ if (connection)
460
+ return connection;
459
461
 
460
- return this.constructor._getConnection();
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mythix-orm",
3
- "version": "1.11.3",
3
+ "version": "1.11.5",
4
4
  "description": "ORM for Mythix framework",
5
5
  "main": "lib/index",
6
6
  "type": "commonjs",