mythix-orm 1.8.3 → 1.11.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.
- package/lib/connection/connection-base.d.ts +1 -0
- package/lib/connection/connection-base.js +71 -20
- package/lib/connection/literals/literal-base.js +20 -1
- package/lib/connection/query-generator-base.d.ts +1 -15
- package/lib/connection/query-generator-base.js +56 -584
- package/lib/field.js +9 -2
- package/lib/model.d.ts +17 -2
- package/lib/model.js +63 -71
- package/lib/query-engine/field-scope.js +58 -25
- package/lib/query-engine/model-scope.js +168 -35
- package/lib/query-engine/query-engine-base.js +153 -47
- package/lib/query-engine/query-engine.d.ts +37 -28
- package/lib/query-engine/query-engine.js +75 -71
- package/lib/types/concrete/datetime-type.js +1 -1
- package/lib/types/concrete/serialized-type.js +2 -2
- package/lib/types/virtual/model-type.js +3 -3
- package/lib/types/virtual/models-type.js +1 -1
- package/lib/types/virtual/relational-type-base.js +26 -26
- package/lib/utils/index.js +2 -2
- package/lib/utils/misc-utils.d.ts +0 -1
- package/lib/utils/misc-utils.js +0 -24
- package/lib/utils/model-utils.js +20 -19
- package/lib/utils/query-utils.d.ts +7 -0
- package/lib/utils/query-utils.js +175 -4
- package/package.json +1 -1
|
@@ -6,22 +6,22 @@ import Field from '../field';
|
|
|
6
6
|
|
|
7
7
|
export declare interface QueryEngineOptions {
|
|
8
8
|
connection: ConnectionBase;
|
|
9
|
-
[
|
|
9
|
+
[key: string]: any;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export declare type QueryEngineClass = typeof QueryEngine;
|
|
13
13
|
|
|
14
14
|
export declare interface CallableInterface {
|
|
15
15
|
(...args: Array<any>): QueryEngine;
|
|
16
|
-
[
|
|
16
|
+
[key: string]: QueryEngine;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export declare class QueryEngine<T = ConnectionBase> {
|
|
20
20
|
// QueryEngineBase
|
|
21
21
|
static generateID(): number;
|
|
22
|
-
static
|
|
22
|
+
static isQueryOperationContext(value: any): boolean;
|
|
23
23
|
static isQuery(value: any): boolean;
|
|
24
|
-
static
|
|
24
|
+
static queryOperationInfo(queryContext: GenericObject): { hasCondition: boolean; hasField: boolean; hasModel: boolean; };
|
|
25
25
|
|
|
26
26
|
public getModelScopeClass(): QueryEngine;
|
|
27
27
|
public getFieldScopeClass(): QueryEngine;
|
|
@@ -31,33 +31,38 @@ export declare class QueryEngine<T = ConnectionBase> {
|
|
|
31
31
|
public _newModelScope(Model: ModelClass): QueryEngine;
|
|
32
32
|
public _newFieldScope(Field: Field): QueryEngine;
|
|
33
33
|
public constructor(context: QueryEngineOptions);
|
|
34
|
-
public
|
|
35
|
-
public
|
|
36
|
-
public
|
|
37
|
-
public
|
|
38
|
-
public
|
|
39
|
-
public
|
|
40
|
-
public
|
|
41
|
-
public
|
|
42
|
-
public
|
|
34
|
+
public getQueryID(): number;
|
|
35
|
+
public getOperationContext(): GenericObject;
|
|
36
|
+
public getOperationStack(): Array<GenericObject>;
|
|
37
|
+
public isLastOperationControl(): boolean;
|
|
38
|
+
public isLastOperationCondition(): boolean;
|
|
39
|
+
public queryHasConditions(): boolean;
|
|
40
|
+
public queryHasJoins(): boolean;
|
|
41
|
+
public logQueryOperations(): void;
|
|
42
|
+
public _pushOperationOntoStack(queryPart: GenericObject, context: GenericObject): void;
|
|
43
43
|
public getConnection(): ConnectionBase;
|
|
44
44
|
public getModel(modelName: string): ModelClass | undefined;
|
|
45
45
|
public getQueryEngineScope(): QueryEngine;
|
|
46
46
|
public getQueryEngineClass(): QueryEngineClass;
|
|
47
47
|
public clone(): QueryEngine;
|
|
48
|
+
public filter(callback: (operation: GenericObject, index: number, operations: Array<GenericObject>, query: QueryEngine) => GenericObject): QueryEngine;
|
|
49
|
+
public map(callback: (operation: GenericObject, index: number, operations: Array<GenericObject>, query: QueryEngine) => GenericObject): QueryEngine;
|
|
50
|
+
public walk(callback: (query: QueryEngine, parent: GenericObject | null, contextKey: string, depth: number) => GenericObject, checkContextKeys?: Array<string>): void;
|
|
51
|
+
public getAllModelsUsedInQuery(): Array<ModelClass>;
|
|
48
52
|
|
|
49
53
|
// QueryEngine
|
|
50
54
|
public getModelScopeClass(): QueryEngineClass;
|
|
51
55
|
public getFieldScopeClass(): QueryEngineClass;
|
|
56
|
+
public getQueryEngineScopeClass(): QueryEngineClass;
|
|
52
57
|
public Model(modelName: string): QueryEngine;
|
|
53
58
|
public unscoped(context?: GenericObject): QueryEngine;
|
|
54
59
|
public toString(options?: GenericObject): string;
|
|
55
60
|
public MERGE(queryEngine: QueryEngine): QueryEngine;
|
|
56
61
|
public all<T extends Model = Model>(options?: GenericObject): Promise<Array<T>>;
|
|
57
|
-
public
|
|
62
|
+
public cursor<T extends Model = Model>(options?: GenericObject): AsyncGenerator<T>;
|
|
58
63
|
public first<T extends Model = Model>(limit?: number | null | undefined, options?: GenericObject): Promise<T | undefined>;
|
|
59
64
|
public last<T extends Model = Model>(limit?: number | null | undefined, options?: GenericObject): Promise<T | undefined>;
|
|
60
|
-
public
|
|
65
|
+
public updateAll<T extends Model = Model>(attributes: T | GenericObject, options?: GenericObject): Promise<number>;
|
|
61
66
|
public destroy(options?: GenericObject): Promise<number>;
|
|
62
67
|
public average(field: Field | string, options?: GenericObject): Promise<number>;
|
|
63
68
|
public count(field: Field | string, options?: GenericObject): Promise<number>;
|
|
@@ -66,6 +71,7 @@ export declare class QueryEngine<T = ConnectionBase> {
|
|
|
66
71
|
public sum(field: Field | string, options?: GenericObject): Promise<number>;
|
|
67
72
|
public pluck(fields: string | Array<string>, options?: GenericObject): Promise<Array<any>>;
|
|
68
73
|
public exists(options?: GenericObject): Promise<boolean>;
|
|
74
|
+
public finalizeQuery(operation: string, options: GenericObject): Promise<QueryEngine>;
|
|
69
75
|
|
|
70
76
|
// ModelScope
|
|
71
77
|
public _getField(fieldName: string): Field | undefined;
|
|
@@ -73,77 +79,80 @@ export declare class QueryEngine<T = ConnectionBase> {
|
|
|
73
79
|
public Field(fieldName: string): QueryEngine;
|
|
74
80
|
public LIMIT(value: number): QueryEngine;
|
|
75
81
|
public OFFSET(value: number): QueryEngine;
|
|
76
|
-
public ORDER(...args: Array<string | Array<string>>): QueryEngine;
|
|
77
|
-
public
|
|
82
|
+
public ORDER(...args: Array<LiteralBase | Field | string | Array<LiteralBase | Field | string>>): QueryEngine;
|
|
83
|
+
public GROUP_BY(...args: Array<LiteralBase | Field | string | Array<LiteralBase | Field | string>>): QueryEngine;
|
|
84
|
+
public HAVING(query: QueryEngine): QueryEngine;
|
|
85
|
+
public EXISTS(query: QueryEngine): QueryEngine;
|
|
86
|
+
public PROJECT(...args: Array<string | ModelClass | LiteralBase | Field | Array<string | ModelClass | LiteralBase | Field>>): QueryEngine;
|
|
78
87
|
|
|
79
88
|
declare public NOT: {
|
|
80
89
|
(): QueryEngine;
|
|
81
90
|
|
|
82
91
|
name: QueryEngine;
|
|
83
|
-
[
|
|
92
|
+
[key: string]: QueryEngine;
|
|
84
93
|
};
|
|
85
94
|
|
|
86
95
|
declare public AND: {
|
|
87
96
|
(query: QueryEngine): QueryEngine;
|
|
88
97
|
|
|
89
98
|
name: QueryEngine;
|
|
90
|
-
[
|
|
99
|
+
[key: string]: QueryEngine;
|
|
91
100
|
};
|
|
92
101
|
|
|
93
102
|
declare public OR: {
|
|
94
103
|
(query: QueryEngine): QueryEngine;
|
|
95
104
|
|
|
96
105
|
name: QueryEngine;
|
|
97
|
-
[
|
|
106
|
+
[key: string]: QueryEngine;
|
|
98
107
|
};
|
|
99
108
|
|
|
100
109
|
declare public DISTINCT: {
|
|
101
110
|
(fullyQualifiedName: string | Field): QueryEngine;
|
|
102
111
|
|
|
103
112
|
name: QueryEngine;
|
|
104
|
-
[
|
|
113
|
+
[key: string]: QueryEngine;
|
|
105
114
|
};
|
|
106
115
|
|
|
107
116
|
declare public INNER_JOIN: {
|
|
108
117
|
(): QueryEngine;
|
|
109
118
|
|
|
110
119
|
name: QueryEngine;
|
|
111
|
-
[
|
|
120
|
+
[key: string]: QueryEngine;
|
|
112
121
|
};
|
|
113
122
|
|
|
114
123
|
declare public LEFT_JOIN: {
|
|
115
124
|
(): QueryEngine;
|
|
116
125
|
|
|
117
126
|
name: QueryEngine;
|
|
118
|
-
[
|
|
127
|
+
[key: string]: QueryEngine;
|
|
119
128
|
};
|
|
120
129
|
|
|
121
130
|
declare public RIGHT_JOIN: {
|
|
122
131
|
(): QueryEngine;
|
|
123
132
|
|
|
124
133
|
name: QueryEngine;
|
|
125
|
-
[
|
|
134
|
+
[key: string]: QueryEngine;
|
|
126
135
|
};
|
|
127
136
|
|
|
128
137
|
declare public FULL_JOIN: {
|
|
129
138
|
(): QueryEngine;
|
|
130
139
|
|
|
131
140
|
name: QueryEngine;
|
|
132
|
-
[
|
|
141
|
+
[key: string]: QueryEngine;
|
|
133
142
|
};
|
|
134
143
|
|
|
135
144
|
declare public CROSS_JOIN: {
|
|
136
145
|
(): QueryEngine;
|
|
137
146
|
|
|
138
147
|
name: QueryEngine;
|
|
139
|
-
[
|
|
148
|
+
[key: string]: QueryEngine;
|
|
140
149
|
};
|
|
141
150
|
|
|
142
151
|
declare public JOIN: {
|
|
143
152
|
(type: string | LiteralBase): QueryEngine;
|
|
144
153
|
|
|
145
154
|
name: QueryEngine;
|
|
146
|
-
[
|
|
155
|
+
[key: string]: QueryEngine;
|
|
147
156
|
};
|
|
148
157
|
|
|
149
158
|
// FieldScope
|
|
@@ -158,7 +167,7 @@ export declare class QueryEngine<T = ConnectionBase> {
|
|
|
158
167
|
public NOT_LIKE(value: string, options?: { caseSensitive: boolean }): QueryEngine;
|
|
159
168
|
|
|
160
169
|
name: QueryEngine;
|
|
161
|
-
[
|
|
170
|
+
[key: string]: any;
|
|
162
171
|
}
|
|
163
172
|
|
|
164
173
|
export class ModelScope extends QueryEngine { }
|
|
@@ -20,9 +20,9 @@ class QueryEngine extends QueryEngineBase {
|
|
|
20
20
|
let context = Object.assign(
|
|
21
21
|
Object.create(_context || {}),
|
|
22
22
|
{
|
|
23
|
-
currentScopeName:
|
|
24
|
-
|
|
25
|
-
contextID:
|
|
23
|
+
currentScopeName: 'queryEngine',
|
|
24
|
+
isQueryOperationContext: true,
|
|
25
|
+
contextID: QueryEngineBase.generateID(),
|
|
26
26
|
},
|
|
27
27
|
);
|
|
28
28
|
|
|
@@ -39,15 +39,15 @@ class QueryEngine extends QueryEngineBase {
|
|
|
39
39
|
return this._newModelScope(model);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
unscoped(
|
|
42
|
+
unscoped() {
|
|
43
|
+
let context = this.getOperationContext();
|
|
43
44
|
let QueryEngineClass = this.constructor;
|
|
44
|
-
let currentContext = context || this.currentContext;
|
|
45
45
|
let queryEngine = new QueryEngineClass({
|
|
46
|
-
connection:
|
|
46
|
+
connection: this.getConnection(),
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
if (
|
|
50
|
-
queryEngine = queryEngine[
|
|
49
|
+
if (context.rootModelName)
|
|
50
|
+
queryEngine = queryEngine[context.rootModelName];
|
|
51
51
|
|
|
52
52
|
return queryEngine;
|
|
53
53
|
}
|
|
@@ -59,35 +59,23 @@ class QueryEngine extends QueryEngineBase {
|
|
|
59
59
|
return queryGenerator.toConnectionString(this, ...args);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
MERGE(
|
|
63
|
-
let
|
|
64
|
-
if (!
|
|
62
|
+
MERGE(_incomingQueryEngine, _options) {
|
|
63
|
+
let incomingQueryEngine = _incomingQueryEngine;
|
|
64
|
+
if (!incomingQueryEngine)
|
|
65
65
|
return this;
|
|
66
66
|
|
|
67
|
-
let
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
let
|
|
73
|
-
let
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
// as they are provided by the
|
|
80
|
-
// parent queryEngine
|
|
81
|
-
'connection',
|
|
82
|
-
'fieldContext',
|
|
83
|
-
'isQueryContext',
|
|
84
|
-
'modelContext',
|
|
85
|
-
'queryEngineScope',
|
|
86
|
-
'queryRoot',
|
|
87
|
-
'rootContext',
|
|
88
|
-
'rootModel',
|
|
89
|
-
'rootModelName',
|
|
90
|
-
]);
|
|
67
|
+
let options = _options || {};
|
|
68
|
+
let thisQueryContext = this.getOperationContext();
|
|
69
|
+
if (!QueryEngine.isQuery(incomingQueryEngine) && Nife.instanceOf(incomingQueryEngine, 'array', 'object', 'map', 'set'))
|
|
70
|
+
incomingQueryEngine = Utils.generateQueryFromFilter(this.getConnection(options.connection), thisQueryContext.rootModel, incomingQueryEngine);
|
|
71
|
+
|
|
72
|
+
let incomingOperationStack = incomingQueryEngine.getOperationStack();
|
|
73
|
+
let skippingLogical = true;
|
|
74
|
+
let logicalOperatorEncountered = false;
|
|
75
|
+
let queryEngine = this.clone();
|
|
76
|
+
|
|
77
|
+
for (let i = 0, il = incomingOperationStack.length; i < il; i++) {
|
|
78
|
+
let queryPart = incomingOperationStack[i];
|
|
91
79
|
|
|
92
80
|
// For merges, we want to skip the first logical operators
|
|
93
81
|
// found before any other operation.
|
|
@@ -97,51 +85,59 @@ class QueryEngine extends QueryEngineBase {
|
|
|
97
85
|
// Since the result we want here is OR merge, not AND merge
|
|
98
86
|
// we skip the first "AND" we encounter, leaving the "OR" as
|
|
99
87
|
// the current logical operator.
|
|
100
|
-
|
|
101
|
-
|
|
88
|
+
// Logical operators do not always come first in the query,
|
|
89
|
+
// so we need to rely on "logicalOperatorEncountered" to
|
|
90
|
+
// ensure we skip only the first one (or first few in a sequence).
|
|
91
|
+
if (skippingLogical && Object.prototype.hasOwnProperty.call(queryPart, 'logical') && queryPart.logical) {
|
|
92
|
+
if (queryPart.value == null && (queryPart.operator === 'AND' || queryPart.operator === 'OR')) {
|
|
93
|
+
logicalOperatorEncountered = true;
|
|
102
94
|
continue;
|
|
95
|
+
}
|
|
103
96
|
}
|
|
104
97
|
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
if (mergeContext.operator === 'MODEL') {
|
|
108
|
-
if (mergeContext.Model === currentModel)
|
|
109
|
-
continue;
|
|
98
|
+
if (logicalOperatorEncountered)
|
|
99
|
+
skippingLogical = false;
|
|
110
100
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
101
|
+
let value = queryPart.value;
|
|
102
|
+
if (Object.prototype.hasOwnProperty.call(queryPart, 'control') && queryPart.control === true) {
|
|
103
|
+
if (queryPart.operator === 'PROJECT' && options.projections !== true)
|
|
104
|
+
continue;
|
|
105
|
+
|
|
106
|
+
if (queryPart.operator === 'ORDER' && options.orders === false)
|
|
107
|
+
continue;
|
|
108
|
+
|
|
109
|
+
if (queryPart.operator === 'GROUP_BY' && options.groupBys === false)
|
|
110
|
+
continue;
|
|
111
|
+
|
|
112
|
+
if (queryPart.operator === 'PROJECT' || queryPart.operator === 'ORDER' || queryPart.operator === 'GROUP_BY')
|
|
113
|
+
value = [ '+' ].concat(value);
|
|
115
114
|
}
|
|
116
115
|
|
|
117
|
-
|
|
118
|
-
Model: queryPart.Model,
|
|
119
|
-
modelName: queryPart.modelName,
|
|
120
|
-
Field: queryPart.Field,
|
|
121
|
-
fieldName: queryPart.fieldName,
|
|
122
|
-
}, mergeContext));
|
|
116
|
+
queryEngine = queryEngine[queryPart.queryProp](value, ...(queryPart.queryExtraArgs || []));
|
|
123
117
|
}
|
|
124
118
|
|
|
125
|
-
return
|
|
119
|
+
return queryEngine;
|
|
126
120
|
}
|
|
127
121
|
|
|
128
|
-
all(options) {
|
|
122
|
+
async all(options) {
|
|
129
123
|
let connection = this.getConnection(options && options.connection);
|
|
130
124
|
|
|
131
125
|
if (options && options.stream)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
126
|
+
throw new TypeError('QueryEngine::all: "stream" option set to true. For streaming, please use the "cursor" method instead.');
|
|
127
|
+
|
|
128
|
+
return await Utils.collect(connection.select(await this.finalizeQuery('read', options), options));
|
|
135
129
|
}
|
|
136
130
|
|
|
137
|
-
|
|
138
|
-
|
|
131
|
+
async *cursor(_options) {
|
|
132
|
+
let options = _options || {};
|
|
133
|
+
let connection = this.getConnection(options && options.connection);
|
|
134
|
+
return yield *connection.select(await this.finalizeQuery('read', options), { ...options, stream: true });
|
|
139
135
|
}
|
|
140
136
|
|
|
141
137
|
async first(_limit, options) {
|
|
142
138
|
let limit = (_limit == null) ? 1 : _limit;
|
|
143
139
|
let connection = this.getConnection(options && options.connection);
|
|
144
|
-
let query = this.clone().LIMIT(limit);
|
|
140
|
+
let query = (await this.finalizeQuery('read', options)).clone().LIMIT(limit);
|
|
145
141
|
|
|
146
142
|
let result = await Utils.collect(connection.select(query, options));
|
|
147
143
|
return (_limit == null) ? result[0] : result;
|
|
@@ -150,55 +146,63 @@ class QueryEngine extends QueryEngineBase {
|
|
|
150
146
|
async last(_limit, options) {
|
|
151
147
|
let limit = (_limit == null) ? 1 : _limit;
|
|
152
148
|
let connection = this.getConnection(options && options.connection);
|
|
153
|
-
let query = this.clone().LIMIT(limit);
|
|
149
|
+
let query = (await this.finalizeQuery('read', options)).clone().LIMIT(limit);
|
|
154
150
|
|
|
155
151
|
let result = await Utils.collect(connection.select(query, Object.assign({}, options || {}, { reverseOrder: true })));
|
|
156
152
|
return (_limit == null) ? result[0] : result.reverse();
|
|
157
153
|
}
|
|
158
154
|
|
|
159
|
-
async
|
|
155
|
+
async updateAll(attributes, options) {
|
|
160
156
|
let connection = this.getConnection(options && options.connection);
|
|
161
|
-
return await connection.updateAll(this, attributes, options);
|
|
157
|
+
return await connection.updateAll(await this.finalizeQuery('update', options), attributes, options);
|
|
162
158
|
}
|
|
163
159
|
|
|
164
160
|
async destroy(options) {
|
|
165
161
|
let connection = this.getConnection(options && options.connection);
|
|
166
|
-
return await connection.destroy(this, options);
|
|
162
|
+
return await connection.destroy(await this.finalizeQuery('delete', options), options);
|
|
167
163
|
}
|
|
168
164
|
|
|
169
165
|
async average(field, options) {
|
|
170
166
|
let connection = this.getConnection(options && options.connection);
|
|
171
|
-
return await connection.average(this, field, options);
|
|
167
|
+
return await connection.average(await this.finalizeQuery('read', options), field, options);
|
|
172
168
|
}
|
|
173
169
|
|
|
174
170
|
async count(field, options) {
|
|
175
171
|
let connection = this.getConnection(options && options.connection);
|
|
176
|
-
return await connection.count(this, field, options);
|
|
172
|
+
return await connection.count(await this.finalizeQuery('read', options), field, options);
|
|
177
173
|
}
|
|
178
174
|
|
|
179
175
|
async min(field, options) {
|
|
180
176
|
let connection = this.getConnection(options && options.connection);
|
|
181
|
-
return await connection.min(this, field, options);
|
|
177
|
+
return await connection.min(await this.finalizeQuery('read', options), field, options);
|
|
182
178
|
}
|
|
183
179
|
|
|
184
180
|
async max(field, options) {
|
|
185
181
|
let connection = this.getConnection(options && options.connection);
|
|
186
|
-
return await connection.max(this, field, options);
|
|
182
|
+
return await connection.max(await this.finalizeQuery('read', options), field, options);
|
|
187
183
|
}
|
|
188
184
|
|
|
189
185
|
async sum(field, options) {
|
|
190
186
|
let connection = this.getConnection(options && options.connection);
|
|
191
|
-
return await connection.sum(this, field, options);
|
|
187
|
+
return await connection.sum(await this.finalizeQuery('read', options), field, options);
|
|
192
188
|
}
|
|
193
189
|
|
|
194
190
|
async pluck(fields, options) {
|
|
195
191
|
let connection = this.getConnection(options && options.connection);
|
|
196
|
-
return await connection.pluck(this, fields, options);
|
|
192
|
+
return await connection.pluck(await this.finalizeQuery('read', options), fields, options);
|
|
197
193
|
}
|
|
198
194
|
|
|
199
195
|
async exists(options) {
|
|
200
196
|
let connection = this.getConnection(options && options.connection);
|
|
201
|
-
return await connection.exists(this, options);
|
|
197
|
+
return await connection.exists(await this.finalizeQuery('read', options), options);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async finalizeQuery(crudOperation, options) {
|
|
201
|
+
let connection = this.getConnection();
|
|
202
|
+
if (connection && typeof connection.finalizeQuery === 'function')
|
|
203
|
+
return await connection.finalizeQuery(crudOperation, this, options);
|
|
204
|
+
|
|
205
|
+
return this;
|
|
202
206
|
}
|
|
203
207
|
|
|
204
208
|
[ProxyClass.MISSING](target, prop) {
|
|
@@ -110,13 +110,13 @@ class SerializedType extends Type {
|
|
|
110
110
|
options = { type: options };
|
|
111
111
|
|
|
112
112
|
options = {
|
|
113
|
-
serialize:
|
|
113
|
+
serialize: ({ value }) => {
|
|
114
114
|
if (value == null)
|
|
115
115
|
return value;
|
|
116
116
|
|
|
117
117
|
return JSON.stringify(value);
|
|
118
118
|
},
|
|
119
|
-
deserialize:
|
|
119
|
+
deserialize: ({ value }) => {
|
|
120
120
|
if (value == null)
|
|
121
121
|
return value;
|
|
122
122
|
|
|
@@ -72,12 +72,12 @@ const TYPE_OPERATIONS = {
|
|
|
72
72
|
if (!model.isDirty())
|
|
73
73
|
return model;
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
await connection.update(model.getModel(), [ model ], options);
|
|
76
76
|
|
|
77
77
|
// Update this model to reflect the update
|
|
78
|
-
ModelUtils.setRelationalValues(connection, this.getModel(), this,
|
|
78
|
+
ModelUtils.setRelationalValues(connection, this.getModel(), this, model.getModel(), model);
|
|
79
79
|
|
|
80
|
-
return
|
|
80
|
+
return model;
|
|
81
81
|
}, options);
|
|
82
82
|
|
|
83
83
|
// Save needs to go outside of the transaction
|
|
@@ -125,7 +125,7 @@ const TYPE_OPERATIONS = {
|
|
|
125
125
|
'get': function({ field, type }, userQuery, options, ...args) {
|
|
126
126
|
const doGet = async function*() {
|
|
127
127
|
let query = await type.prepareQuery({ connection: null, self: this, field, options }, [ userQuery ].concat(args));
|
|
128
|
-
let results = query.
|
|
128
|
+
let results = query.cursor(options);
|
|
129
129
|
let primaryModelRelationalArray = [];
|
|
130
130
|
|
|
131
131
|
this[field.fieldName] = primaryModelRelationalArray;
|
|
@@ -140,17 +140,17 @@ class RelationalTypeBase extends Type {
|
|
|
140
140
|
};
|
|
141
141
|
|
|
142
142
|
let target = {
|
|
143
|
-
Model:
|
|
144
|
-
modelName:
|
|
145
|
-
field:
|
|
146
|
-
fieldName:
|
|
143
|
+
Model: leftContext.Model,
|
|
144
|
+
modelName: leftContext.modelName,
|
|
145
|
+
field: leftContext.Field,
|
|
146
|
+
fieldName: leftContext.fieldName,
|
|
147
147
|
};
|
|
148
148
|
|
|
149
149
|
let source = {
|
|
150
|
-
Model:
|
|
151
|
-
modelName:
|
|
152
|
-
field:
|
|
153
|
-
fieldName:
|
|
150
|
+
Model: rightContext.Model,
|
|
151
|
+
modelName: rightContext.modelName,
|
|
152
|
+
field: rightContext.Field,
|
|
153
|
+
fieldName: rightContext.fieldName,
|
|
154
154
|
};
|
|
155
155
|
|
|
156
156
|
// The primary model is always the target
|
|
@@ -170,7 +170,7 @@ class RelationalTypeBase extends Type {
|
|
|
170
170
|
let PrimaryModel = (context.self && context.self.getModel());
|
|
171
171
|
let primaryModelName = PrimaryModel.getModelName();
|
|
172
172
|
let query = await this.prepareQuery(Object.assign({ connection }, context), args);
|
|
173
|
-
let queryParts = query.
|
|
173
|
+
let queryParts = query.getOperationStack();
|
|
174
174
|
let queryContext = (queryParts[queryParts.length - 1] || {});
|
|
175
175
|
let TargetModel = queryContext.rootModel;
|
|
176
176
|
let TargetField = queryContext.rootField;
|
|
@@ -186,7 +186,7 @@ class RelationalTypeBase extends Type {
|
|
|
186
186
|
let rightQueryContext = null;
|
|
187
187
|
|
|
188
188
|
if (QueryEngine.isQuery(conditionValue)) {
|
|
189
|
-
rightQueryContext = conditionValue.
|
|
189
|
+
rightQueryContext = conditionValue.getOperationContext();
|
|
190
190
|
if (rightQueryContext.condition)
|
|
191
191
|
continue;
|
|
192
192
|
} else {
|
|
@@ -205,10 +205,10 @@ class RelationalTypeBase extends Type {
|
|
|
205
205
|
let targetField = fkField.getTargetField(connection);
|
|
206
206
|
let targetFieldName = fkField.getTargetFieldName(connection);
|
|
207
207
|
let fkContext = {
|
|
208
|
-
Model:
|
|
209
|
-
modelName:
|
|
210
|
-
field:
|
|
211
|
-
fieldName:
|
|
208
|
+
Model: targetModel,
|
|
209
|
+
modelName: targetModelName,
|
|
210
|
+
field: targetField,
|
|
211
|
+
fieldName: targetFieldName,
|
|
212
212
|
};
|
|
213
213
|
|
|
214
214
|
if (!isAlreadyVisited(fkContext, rightQueryContext))
|
|
@@ -222,10 +222,10 @@ class RelationalTypeBase extends Type {
|
|
|
222
222
|
let targetField = fkField.getTargetField(connection);
|
|
223
223
|
let targetFieldName = fkField.getTargetFieldName(connection);
|
|
224
224
|
let fkContext = {
|
|
225
|
-
Model:
|
|
226
|
-
modelName:
|
|
227
|
-
field:
|
|
228
|
-
fieldName:
|
|
225
|
+
Model: targetModel,
|
|
226
|
+
modelName: targetModelName,
|
|
227
|
+
field: targetField,
|
|
228
|
+
fieldName: targetFieldName,
|
|
229
229
|
};
|
|
230
230
|
|
|
231
231
|
if (!isAlreadyVisited(leftQueryContext, fkContext))
|
|
@@ -245,16 +245,16 @@ class RelationalTypeBase extends Type {
|
|
|
245
245
|
// be copying field values from
|
|
246
246
|
let targetModelName = TargetModel.getModelName();
|
|
247
247
|
let source = {
|
|
248
|
-
Model:
|
|
249
|
-
modelName:
|
|
250
|
-
Field:
|
|
251
|
-
fieldName:
|
|
248
|
+
Model: TargetModel,
|
|
249
|
+
modelName: targetModelName,
|
|
250
|
+
Field: TargetField,
|
|
251
|
+
fieldName: TargetField.fieldName,
|
|
252
252
|
};
|
|
253
253
|
let target = {
|
|
254
|
-
Model:
|
|
255
|
-
modelName:
|
|
256
|
-
Field:
|
|
257
|
-
fieldName:
|
|
254
|
+
Model: PrimaryModel,
|
|
255
|
+
modelName: PrimaryModel.getModelName(),
|
|
256
|
+
Field: context.field,
|
|
257
|
+
fieldName: context.field.fieldName,
|
|
258
258
|
};
|
|
259
259
|
|
|
260
260
|
if (!isAlreadyVisited(source, target))
|
package/lib/utils/index.js
CHANGED
|
@@ -7,7 +7,6 @@ const AsyncStore = require('./async-store');
|
|
|
7
7
|
|
|
8
8
|
const {
|
|
9
9
|
collect,
|
|
10
|
-
objectAssignSpecial,
|
|
11
10
|
valueToDateTime,
|
|
12
11
|
} = MiscUtils;
|
|
13
12
|
|
|
@@ -31,6 +30,7 @@ const {
|
|
|
31
30
|
const {
|
|
32
31
|
parseFilterFieldAndOperator,
|
|
33
32
|
generateQueryFromFilter,
|
|
33
|
+
margeFields,
|
|
34
34
|
} = QueryUtils;
|
|
35
35
|
|
|
36
36
|
const {
|
|
@@ -48,7 +48,6 @@ module.exports = {
|
|
|
48
48
|
|
|
49
49
|
// MiscUtils
|
|
50
50
|
collect,
|
|
51
|
-
objectAssignSpecial,
|
|
52
51
|
valueToDateTime,
|
|
53
52
|
|
|
54
53
|
// ModelUtils
|
|
@@ -70,6 +69,7 @@ module.exports = {
|
|
|
70
69
|
// QueryUtils
|
|
71
70
|
parseFilterFieldAndOperator,
|
|
72
71
|
generateQueryFromFilter,
|
|
72
|
+
margeFields,
|
|
73
73
|
|
|
74
74
|
// AsyncStore
|
|
75
75
|
getContextStore,
|
|
@@ -2,5 +2,4 @@ import { DateTime } from 'luxon';
|
|
|
2
2
|
import { GenericObject } from '../interfaces/common';
|
|
3
3
|
|
|
4
4
|
declare function collect(iterator: AsyncIterator<any>): Promise<Array<any>>;
|
|
5
|
-
declare function objectAssignSpecial(obj: GenericObject, proto?: GenericObject | null, skipKeys?: Array<string> | GenericObject): GenericObject;
|
|
6
5
|
declare function valueToDateTime(value: DateTime | Date | number | BigInt | string, format?: string): DateTime;
|
package/lib/utils/misc-utils.js
CHANGED
|
@@ -12,29 +12,6 @@ async function collect(iterator) {
|
|
|
12
12
|
return items;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
function objectAssignSpecial(obj, proto, skipKeys) {
|
|
16
|
-
const isKeySkipped = (key) => {
|
|
17
|
-
if (Array.isArray(skipKeys))
|
|
18
|
-
return (skipKeys.indexOf(key) >= 0);
|
|
19
|
-
|
|
20
|
-
return Object.prototype.hasOwnProperty.call(skipKeys, key);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
let newObj = Object.create(proto || {});
|
|
24
|
-
let keys = Object.keys(obj);
|
|
25
|
-
|
|
26
|
-
// eslint-disable-next-line guard-for-in
|
|
27
|
-
for (let i = 0, il = keys.length; i < il; i++) {
|
|
28
|
-
let key = keys[i];
|
|
29
|
-
if (skipKeys && isKeySkipped(key))
|
|
30
|
-
continue;
|
|
31
|
-
|
|
32
|
-
newObj[key] = obj[key];
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return newObj;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
15
|
function valueToDateTime(value, format) {
|
|
39
16
|
if (DateTime.isDateTime(value)) {
|
|
40
17
|
return value;
|
|
@@ -59,6 +36,5 @@ function valueToDateTime(value, format) {
|
|
|
59
36
|
|
|
60
37
|
module.exports = {
|
|
61
38
|
collect,
|
|
62
|
-
objectAssignSpecial,
|
|
63
39
|
valueToDateTime,
|
|
64
40
|
};
|