mythix-orm 1.11.6 → 1.12.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/README.md +100 -9
- package/lib/connection/connection-base.js +173 -39
- package/lib/connection/literals/average-literal.js +67 -0
- package/lib/connection/literals/count-literal.js +80 -0
- package/lib/connection/literals/distinct-literal.js +71 -0
- package/lib/connection/literals/field-literal.js +54 -0
- package/lib/connection/literals/literal-base.d.ts +1 -0
- package/lib/connection/literals/literal-base.js +137 -2
- package/lib/connection/literals/literal-field-base.js +50 -0
- package/lib/connection/literals/literal.js +15 -0
- package/lib/connection/literals/max-literal.js +67 -0
- package/lib/connection/literals/min-literal.js +67 -0
- package/lib/connection/literals/sum-literal.js +67 -0
- package/lib/connection/query-generator-base.js +273 -0
- package/lib/field.js +1 -1
- package/lib/model.js +54 -2
- package/lib/proxy-class/proxy-class.js +156 -21
- package/lib/query-engine/field-scope.js +401 -9
- package/lib/query-engine/model-scope.js +572 -13
- package/lib/query-engine/query-engine-base.js +590 -30
- package/lib/query-engine/query-engine.d.ts +13 -2
- package/lib/query-engine/query-engine.js +525 -18
- package/lib/types/helpers/default-helpers.js +124 -0
- package/lib/types/type.js +297 -3
- package/lib/utils/async-store.js +80 -3
- package/package.json +1 -2
|
@@ -2,11 +2,78 @@
|
|
|
2
2
|
|
|
3
3
|
const LiteralFieldBase = require('./literal-field-base');
|
|
4
4
|
|
|
5
|
+
/// Define an "average" literal for the underlying database.
|
|
6
|
+
///
|
|
7
|
+
/// Literals are special types in Mythix ORM that are used to
|
|
8
|
+
/// define "literal values" for the underlying database.
|
|
9
|
+
///
|
|
10
|
+
/// This literal defines an "average" operation across a single
|
|
11
|
+
/// column. It is used by <see>Connection.average</see> to get
|
|
12
|
+
/// the average across all rows for a single column in the underlying
|
|
13
|
+
/// database. When serialized using the <see>QueryGenerator</see>
|
|
14
|
+
/// for the connection, it will turn into a database method that
|
|
15
|
+
/// is appropriate for the underlying database. For example, with
|
|
16
|
+
/// SQL type databases this would turn into `SUM(column)`. This is
|
|
17
|
+
/// often used by the projection engine, to project it as a column
|
|
18
|
+
/// to be selected. For example `SELECT SUM(column) ...`. It can
|
|
19
|
+
/// be used in other places in the query however, such as `ORDER`,
|
|
20
|
+
/// `GROUP BY`, and `HAVING` clauses.
|
|
21
|
+
///
|
|
22
|
+
/// There are two primary ways to access literals in Mythix ORM. The
|
|
23
|
+
/// first is to simply import them. The second way literals can be
|
|
24
|
+
/// accessed is via the connection class itself. All Mythix ORM connection
|
|
25
|
+
/// classes export all literals on the `static Literals` attribute of
|
|
26
|
+
/// the class. So for example, you could access literals like `SQLiteConnection.Literals.SumLiteral`.
|
|
27
|
+
///
|
|
28
|
+
/// All built-in Mythix ORM literals--except `Literal` and `LiteralBase`--accept a field
|
|
29
|
+
/// as their first argument. This field can be a fully qualified field name, an actual
|
|
30
|
+
/// <see>Field</see> instance, or another literal. The second argument to all literal constructors
|
|
31
|
+
/// is an `options` object, that generally contains connection-specific (and operation-specific) options...
|
|
32
|
+
/// however, there are common options that can be supplied, such as `as: string;` which allows you to
|
|
33
|
+
/// define an alias for the defined field, and `noProjectionAliases: boolean;`, which allows you to disable
|
|
34
|
+
/// the column alias entirely.
|
|
35
|
+
///
|
|
36
|
+
/// Example:
|
|
37
|
+
/// const { Literals } = require('mythix-orm');
|
|
38
|
+
/// const { SQLiteConnection } = require('mythix-orm-sqlite');
|
|
39
|
+
/// let literal1 = new Literals.SumLiteral('User:age');
|
|
40
|
+
/// let literal2 = new SQLiteConnection.Literals.SumLiteral('User:age');
|
|
41
|
+
///
|
|
42
|
+
/// See: LiteralFieldBase
|
|
43
|
+
///
|
|
44
|
+
/// See: LiteralBase
|
|
5
45
|
class SumLiteral extends LiteralFieldBase {
|
|
46
|
+
/// Return `true`, letting the caller know that
|
|
47
|
+
/// this is an "aggregating literal".
|
|
48
|
+
///
|
|
49
|
+
/// Return: boolean
|
|
50
|
+
/// Return `true`, informing the caller that this literal is used for aggregate operations.
|
|
6
51
|
static isAggregate() {
|
|
7
52
|
return true;
|
|
8
53
|
}
|
|
9
54
|
|
|
55
|
+
/// Convert this literal to a string to be used in a database query.
|
|
56
|
+
///
|
|
57
|
+
/// This method proxies the conversion of this literal to the connection
|
|
58
|
+
/// by calling <see>Connection.literalToString</see>. If no connection
|
|
59
|
+
/// is provided when this is called, then the literal will be converted
|
|
60
|
+
/// to a string representing it for debugging, i.e. `'SumLiteral {}'`.
|
|
61
|
+
///
|
|
62
|
+
/// Note:
|
|
63
|
+
/// Ultimately, for most connections, this will end up calling
|
|
64
|
+
/// <see>QueryGenerator._sumLiteralToString</see>.
|
|
65
|
+
///
|
|
66
|
+
/// Arguments:
|
|
67
|
+
/// connection?: <see>Connection</see>
|
|
68
|
+
/// The connection to use to stringify this literal. If none is provided,
|
|
69
|
+
/// then a string representing this object will be returned instead.
|
|
70
|
+
/// options?: object
|
|
71
|
+
/// A connection and operation specific set of options that can be provided.
|
|
72
|
+
/// This might for example be `{ as: 'name' }` to provided a field alias, or
|
|
73
|
+
/// `{ isProjection: true }` to define that this is being stringified for use
|
|
74
|
+
/// as a field in the query projection. Normally the end-user won't care about
|
|
75
|
+
/// any literal options, except `as`, which is commonly used to give your literal
|
|
76
|
+
/// an alias.
|
|
10
77
|
toString(connection, options) {
|
|
11
78
|
if (!connection)
|
|
12
79
|
return `${this.constructor.name} {}`;
|
|
@@ -2,8 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
/// The base query generator class.
|
|
4
4
|
///
|
|
5
|
+
/// A "query generator" is an interface that will take
|
|
6
|
+
/// parameters (usually a <see>QueryEngine</see> or a
|
|
7
|
+
/// <see>Model</see>) and generate database query statements
|
|
8
|
+
/// from the input. For SQL type databases this would mean
|
|
9
|
+
/// generating `SELECT`, `INSERT`, `UPDATE`, and `DELETE`
|
|
10
|
+
/// statements, as well as generators for creating and altering
|
|
11
|
+
/// tables, among other things.
|
|
12
|
+
///
|
|
13
|
+
/// The methods of this class are generally many, with the
|
|
14
|
+
/// design pattern for most generators being that nearly
|
|
15
|
+
/// all methods are split apart and added to the class, allowing
|
|
16
|
+
/// by deliberate design much finer control when using overloaded
|
|
17
|
+
/// methods, to modify or replace any parts of the generator.
|
|
18
|
+
///
|
|
19
|
+
/// Any connection can be provided a custom query generator
|
|
20
|
+
/// interface via the `queryGenerator` option that can be
|
|
21
|
+
/// used when instantiating a connection. Most connections
|
|
22
|
+
/// will supply their own by default.
|
|
23
|
+
///
|
|
24
|
+
/// A connection should always be bound to a query generator
|
|
25
|
+
/// instance. If not when first created, then at least when
|
|
26
|
+
/// provided to a connection. The connection is a required
|
|
27
|
+
/// part of the generator interface, and will do things, such
|
|
28
|
+
/// as for example, escaping values and ids using the connection
|
|
29
|
+
/// itself. The connection may be used for other operations as
|
|
30
|
+
/// well.
|
|
31
|
+
///
|
|
32
|
+
/// Note:
|
|
33
|
+
/// Some database drivers may not have a generator at all. Though
|
|
34
|
+
/// database drivers commonly do have a database statement generator,
|
|
35
|
+
/// a connection isn't required to have one.
|
|
36
|
+
///
|
|
5
37
|
/// Alias: QueryGenerator
|
|
6
38
|
class QueryGeneratorBase {
|
|
39
|
+
/// Construct a new query generator
|
|
40
|
+
///
|
|
41
|
+
/// Arguments:
|
|
42
|
+
/// connection?: <see>Connection</see>
|
|
43
|
+
/// The connection that this interface is for. Sometimes the connection
|
|
44
|
+
/// isn't yet available when creating the query generator, so this argument
|
|
45
|
+
/// is optional. When provided to a <see>Connection</see>, the connection
|
|
46
|
+
/// will call <see>QueryGenerator.setConnection</see> with itself to set
|
|
47
|
+
/// the connection for the query generator.
|
|
7
48
|
constructor(connection) {
|
|
8
49
|
Object.defineProperties(this, {
|
|
9
50
|
'connection': {
|
|
@@ -15,57 +56,289 @@ class QueryGeneratorBase {
|
|
|
15
56
|
});
|
|
16
57
|
}
|
|
17
58
|
|
|
59
|
+
/// Get the <see>Connection</see> bound to this
|
|
60
|
+
/// query generator.
|
|
61
|
+
///
|
|
62
|
+
/// Return: <see>Connection</see>
|
|
63
|
+
/// The connection bound to this query generator. A connection
|
|
64
|
+
/// should always be bound before any generating methods of
|
|
65
|
+
/// the class are called.
|
|
66
|
+
getConnection() {
|
|
67
|
+
return this.connection;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/// Set the <see>Connection</see> bound to this
|
|
71
|
+
/// query generator.
|
|
72
|
+
///
|
|
73
|
+
/// Arguments:
|
|
74
|
+
/// connection: <see>Connection</see>
|
|
75
|
+
/// The connection to bind to this query generator.
|
|
76
|
+
///
|
|
77
|
+
/// Return: <see>QueryGenerator</see>
|
|
78
|
+
/// Return `this` to allow for chaining.
|
|
79
|
+
setConnection(connection) {
|
|
80
|
+
this.connection = connection;
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/// This call proxies to <see>Connection.stackAssign</see>.
|
|
85
|
+
/// Refer to the documentation of that method for more information.
|
|
86
|
+
///
|
|
87
|
+
/// See: Connection.stackAssign
|
|
18
88
|
stackAssign(obj, ...args) {
|
|
19
89
|
return this.connection.stackAssign(obj, ...args);
|
|
20
90
|
}
|
|
21
91
|
|
|
92
|
+
/// This call proxies to <see>Connection.escape</see>.
|
|
93
|
+
/// Refer to the documentation of that method for more information.
|
|
94
|
+
///
|
|
95
|
+
/// See: Connection.escape
|
|
22
96
|
escape(...args) {
|
|
23
97
|
return this.connection.escape(...args);
|
|
24
98
|
}
|
|
25
99
|
|
|
100
|
+
/// This call proxies to <see>Connection.escapeID</see>.
|
|
101
|
+
/// Refer to the documentation of that method for more information.
|
|
102
|
+
///
|
|
103
|
+
/// See: Connection.escapeID
|
|
26
104
|
escapeID(...args) {
|
|
27
105
|
return this.connection.escapeID(...args);
|
|
28
106
|
}
|
|
29
107
|
|
|
108
|
+
/// Convert an <see>AverageLiteral</see> into a
|
|
109
|
+
/// string representation for the underlying database.
|
|
110
|
+
///
|
|
111
|
+
/// It is expected that each database driver will implement
|
|
112
|
+
/// this method. By default it will simply throw an
|
|
113
|
+
/// "unsupported" error.
|
|
114
|
+
///
|
|
115
|
+
/// Refer to the specific documentation for your database
|
|
116
|
+
/// driver for more information.
|
|
117
|
+
///
|
|
118
|
+
/// Arguments:
|
|
119
|
+
/// literal: <see>AverageLiteral</see>
|
|
120
|
+
/// The literal to stringify for the underlying database.
|
|
121
|
+
/// options?: object
|
|
122
|
+
/// Options for the stringify process. These are often database
|
|
123
|
+
/// driver specific. However, one common option is the `as`
|
|
124
|
+
/// option, which will allow you to give your literal an alias.
|
|
125
|
+
///
|
|
126
|
+
/// Return: string
|
|
127
|
+
/// The literal, converted into the proper string for the underlying
|
|
128
|
+
/// database.
|
|
30
129
|
// eslint-disable-next-line no-unused-vars
|
|
31
130
|
_averageLiteralToString(literal, options) {
|
|
32
131
|
throw new Error(`${this.constructor.name}::_averageLiteralToString: This operation is not supported for this connection type.`);
|
|
33
132
|
}
|
|
34
133
|
|
|
134
|
+
/// Convert an <see>CountLiteral</see> into a
|
|
135
|
+
/// string representation for the underlying database.
|
|
136
|
+
///
|
|
137
|
+
/// It is expected that each database driver will implement
|
|
138
|
+
/// this method. By default it will simply throw an
|
|
139
|
+
/// "unsupported" error.
|
|
140
|
+
///
|
|
141
|
+
/// Refer to the specific documentation for your database
|
|
142
|
+
/// driver for more information.
|
|
143
|
+
///
|
|
144
|
+
/// Arguments:
|
|
145
|
+
/// literal: <see>CountLiteral</see>
|
|
146
|
+
/// The literal to stringify for the underlying database.
|
|
147
|
+
/// options?: object
|
|
148
|
+
/// Options for the stringify process. These are often database
|
|
149
|
+
/// driver specific. However, one common option is the `as`
|
|
150
|
+
/// option, which will allow you to give your literal an alias.
|
|
151
|
+
///
|
|
152
|
+
/// Return: string
|
|
153
|
+
/// The literal, converted into the proper string for the underlying
|
|
154
|
+
/// database.
|
|
35
155
|
// eslint-disable-next-line no-unused-vars
|
|
36
156
|
_countLiteralToString(literal, options) {
|
|
37
157
|
throw new Error(`${this.constructor.name}::_countLiteralToString: This operation is not supported for this connection type.`);
|
|
38
158
|
}
|
|
39
159
|
|
|
160
|
+
/// Convert an <see>DistinctLiteral</see> into a
|
|
161
|
+
/// string representation for the underlying database.
|
|
162
|
+
///
|
|
163
|
+
/// It is expected that each database driver will implement
|
|
164
|
+
/// this method. By default it will simply throw an
|
|
165
|
+
/// "unsupported" error.
|
|
166
|
+
///
|
|
167
|
+
/// Refer to the specific documentation for your database
|
|
168
|
+
/// driver for more information.
|
|
169
|
+
///
|
|
170
|
+
/// Arguments:
|
|
171
|
+
/// literal: <see>DistinctLiteral</see>
|
|
172
|
+
/// The literal to stringify for the underlying database.
|
|
173
|
+
/// options?: object
|
|
174
|
+
/// Options for the stringify process. These are often database
|
|
175
|
+
/// driver specific. However, one common option is the `as`
|
|
176
|
+
/// option, which will allow you to give your literal an alias.
|
|
177
|
+
///
|
|
178
|
+
/// Return: string
|
|
179
|
+
/// The literal, converted into the proper string for the underlying
|
|
180
|
+
/// database.
|
|
40
181
|
// eslint-disable-next-line no-unused-vars
|
|
41
182
|
_distinctLiteralToString(literal, options) {
|
|
42
183
|
throw new Error(`${this.constructor.name}::_distinctLiteralToString: This operation is not supported for this connection type.`);
|
|
43
184
|
}
|
|
44
185
|
|
|
186
|
+
/// Convert an <see>FieldLiteral</see> into a
|
|
187
|
+
/// string representation for the underlying database.
|
|
188
|
+
///
|
|
189
|
+
/// It is expected that each database driver will implement
|
|
190
|
+
/// this method. By default it will simply throw an
|
|
191
|
+
/// "unsupported" error.
|
|
192
|
+
///
|
|
193
|
+
/// Refer to the specific documentation for your database
|
|
194
|
+
/// driver for more information.
|
|
195
|
+
///
|
|
196
|
+
/// Arguments:
|
|
197
|
+
/// literal: <see>FieldLiteral</see>
|
|
198
|
+
/// The literal to stringify for the underlying database.
|
|
199
|
+
/// options?: object
|
|
200
|
+
/// Options for the stringify process. These are often database
|
|
201
|
+
/// driver specific. However, one common option is the `as`
|
|
202
|
+
/// option, which will allow you to give your literal an alias.
|
|
203
|
+
///
|
|
204
|
+
/// Return: string
|
|
205
|
+
/// The literal, converted into the proper string for the underlying
|
|
206
|
+
/// database.
|
|
45
207
|
// eslint-disable-next-line no-unused-vars
|
|
46
208
|
_fieldLiteralToString(literal, options) {
|
|
47
209
|
throw new Error(`${this.constructor.name}::_fieldLiteralToString: This operation is not supported for this connection type.`);
|
|
48
210
|
}
|
|
49
211
|
|
|
212
|
+
/// Convert an <see>MaxLiteral</see> into a
|
|
213
|
+
/// string representation for the underlying database.
|
|
214
|
+
///
|
|
215
|
+
/// It is expected that each database driver will implement
|
|
216
|
+
/// this method. By default it will simply throw an
|
|
217
|
+
/// "unsupported" error.
|
|
218
|
+
///
|
|
219
|
+
/// Refer to the specific documentation for your database
|
|
220
|
+
/// driver for more information.
|
|
221
|
+
///
|
|
222
|
+
/// Arguments:
|
|
223
|
+
/// literal: <see>MaxLiteral</see>
|
|
224
|
+
/// The literal to stringify for the underlying database.
|
|
225
|
+
/// options?: object
|
|
226
|
+
/// Options for the stringify process. These are often database
|
|
227
|
+
/// driver specific. However, one common option is the `as`
|
|
228
|
+
/// option, which will allow you to give your literal an alias.
|
|
229
|
+
///
|
|
230
|
+
/// Return: string
|
|
231
|
+
/// The literal, converted into the proper string for the underlying
|
|
232
|
+
/// database.
|
|
50
233
|
// eslint-disable-next-line no-unused-vars
|
|
51
234
|
_maxLiteralToString(literal, options) {
|
|
52
235
|
throw new Error(`${this.constructor.name}::_maxLiteralToString: This operation is not supported for this connection type.`);
|
|
53
236
|
}
|
|
54
237
|
|
|
238
|
+
/// Convert an <see>MinLiteral</see> into a
|
|
239
|
+
/// string representation for the underlying database.
|
|
240
|
+
///
|
|
241
|
+
/// It is expected that each database driver will implement
|
|
242
|
+
/// this method. By default it will simply throw an
|
|
243
|
+
/// "unsupported" error.
|
|
244
|
+
///
|
|
245
|
+
/// Refer to the specific documentation for your database
|
|
246
|
+
/// driver for more information.
|
|
247
|
+
///
|
|
248
|
+
/// Arguments:
|
|
249
|
+
/// literal: <see>MinLiteral</see>
|
|
250
|
+
/// The literal to stringify for the underlying database.
|
|
251
|
+
/// options?: object
|
|
252
|
+
/// Options for the stringify process. These are often database
|
|
253
|
+
/// driver specific. However, one common option is the `as`
|
|
254
|
+
/// option, which will allow you to give your literal an alias.
|
|
255
|
+
///
|
|
256
|
+
/// Return: string
|
|
257
|
+
/// The literal, converted into the proper string for the underlying
|
|
258
|
+
/// database.
|
|
55
259
|
// eslint-disable-next-line no-unused-vars
|
|
56
260
|
_minLiteralToString(literal, options) {
|
|
57
261
|
throw new Error(`${this.constructor.name}::_minLiteralToString: This operation is not supported for this connection type.`);
|
|
58
262
|
}
|
|
59
263
|
|
|
264
|
+
/// Convert an <see>SumLiteral</see> into a
|
|
265
|
+
/// string representation for the underlying database.
|
|
266
|
+
///
|
|
267
|
+
/// It is expected that each database driver will implement
|
|
268
|
+
/// this method. By default it will simply throw an
|
|
269
|
+
/// "unsupported" error.
|
|
270
|
+
///
|
|
271
|
+
/// Refer to the specific documentation for your database
|
|
272
|
+
/// driver for more information.
|
|
273
|
+
///
|
|
274
|
+
/// Arguments:
|
|
275
|
+
/// literal: <see>SumLiteral</see>
|
|
276
|
+
/// The literal to stringify for the underlying database.
|
|
277
|
+
/// options?: object
|
|
278
|
+
/// Options for the stringify process. These are often database
|
|
279
|
+
/// driver specific. However, one common option is the `as`
|
|
280
|
+
/// option, which will allow you to give your literal an alias.
|
|
281
|
+
///
|
|
282
|
+
/// Return: string
|
|
283
|
+
/// The literal, converted into the proper string for the underlying
|
|
284
|
+
/// database.
|
|
60
285
|
// eslint-disable-next-line no-unused-vars
|
|
61
286
|
_sumLiteralToString(literal, options) {
|
|
62
287
|
throw new Error(`${this.constructor.name}::_sumLiteralToString: This operation is not supported for this connection type.`);
|
|
63
288
|
}
|
|
64
289
|
|
|
290
|
+
/// Take a <see>QueryEngine</see> instance and
|
|
291
|
+
/// convert it into a query. For SQL type databases
|
|
292
|
+
/// this would turn a <see>QueryEngine</see> into a
|
|
293
|
+
/// `SELECT` statement. For other types of databases,
|
|
294
|
+
/// this should return a "fetch" query--or string representation
|
|
295
|
+
/// of such a query--in the database's native query language.
|
|
296
|
+
///
|
|
297
|
+
/// Arguments:
|
|
298
|
+
/// queryEngine: <see>QueryEngine</see>
|
|
299
|
+
/// The query engine instance to stringify.
|
|
300
|
+
/// options?: object
|
|
301
|
+
/// Connection and operation specific options. These
|
|
302
|
+
/// generally aren't needed, but are provided in case
|
|
303
|
+
/// the underlying connection needs them.
|
|
304
|
+
///
|
|
305
|
+
/// Return: string
|
|
306
|
+
/// A "fetch" query in the databases native query language,
|
|
307
|
+
/// generated from the provided `queryEngine`.
|
|
65
308
|
// eslint-disable-next-line no-unused-vars
|
|
66
309
|
toConnectionString(queryEngine, options) {
|
|
67
310
|
return '<not supported by connection>';
|
|
68
311
|
}
|
|
312
|
+
|
|
313
|
+
/// Get the "default value" for the given field
|
|
314
|
+
/// for the underlying database. This is used
|
|
315
|
+
/// primarily for "CREATE TABLE" statements.
|
|
316
|
+
///
|
|
317
|
+
/// By default, the implementation of this method
|
|
318
|
+
/// is empty. It is expected that each database driver
|
|
319
|
+
/// will implement their own version of this method.
|
|
320
|
+
///
|
|
321
|
+
/// Arguments:
|
|
322
|
+
/// field: <see>Field</see>
|
|
323
|
+
/// The field instance we are getting a "default value"
|
|
324
|
+
/// from.
|
|
325
|
+
/// fieldName: string
|
|
326
|
+
/// The name of the field that we are getting the "default value"
|
|
327
|
+
/// from. This should always be the same as `field.fieldName`.
|
|
328
|
+
/// options?: object
|
|
329
|
+
/// Options for the operation. These will likely be connection
|
|
330
|
+
/// specific. Please refer to the documentation of your specific
|
|
331
|
+
/// connection for more details.
|
|
332
|
+
///
|
|
333
|
+
/// Return: any
|
|
334
|
+
/// Though in most cases this method will return a string for
|
|
335
|
+
/// most database drivers in most situations, it may return other
|
|
336
|
+
/// types as well, such as literals, or other raw values.
|
|
337
|
+
/// Please refer to the documentation of your specific
|
|
338
|
+
/// connection for more details.
|
|
339
|
+
// eslint-disable-next-line no-unused-vars
|
|
340
|
+
getFieldDefaultValue(field, fieldName, _options) {
|
|
341
|
+
}
|
|
69
342
|
}
|
|
70
343
|
|
|
71
344
|
module.exports = QueryGeneratorBase;
|
package/lib/field.js
CHANGED
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
/// it is a function, it will be called when the model is initialized
|
|
134
134
|
/// if no value for the field was provided to the model during instantiation.
|
|
135
135
|
/// As a method, it can have numerous different "flags" set on it, via
|
|
136
|
-
/// the <see>
|
|
136
|
+
/// the <see>Helpers.defaultValueFlags</see> factory. Reference this
|
|
137
137
|
/// methods documentation for a better understanding of what default value
|
|
138
138
|
/// flags are, and what they do.
|
|
139
139
|
/// get: Function(context: GetSetContext)
|
package/lib/model.js
CHANGED
|
@@ -345,7 +345,7 @@ class Model {
|
|
|
345
345
|
/// Just be cautious if you set a `connection` property, as you might overwrite any
|
|
346
346
|
/// connection currently set on the context. Any properties you set here will be available
|
|
347
347
|
/// in any child function calls (inside this context scope), and can be accessed via a
|
|
348
|
-
/// call to <see>Model.getModelContext</see>.
|
|
348
|
+
/// call to <see>Model.static getModelContext</see>.
|
|
349
349
|
///
|
|
350
350
|
/// Note:
|
|
351
351
|
/// An `AsyncLocalStorage` context might not exist when this call is made,
|
|
@@ -381,7 +381,7 @@ class Model {
|
|
|
381
381
|
/// This method will return a connection in the following
|
|
382
382
|
/// order: 1) The provided `connection` argument, if supplied,
|
|
383
383
|
/// 2) The `connection` property on the "model context" from
|
|
384
|
-
/// <see>Model.getModelContext</see> from `AsyncLocalStorage`,
|
|
384
|
+
/// <see>Model.static getModelContext</see> from `AsyncLocalStorage`,
|
|
385
385
|
/// if one is available, and 3) Finally the bound connection, if
|
|
386
386
|
/// available, which is found by searching the `static Model._mythixBoundConnection`
|
|
387
387
|
/// property of the class.
|
|
@@ -677,6 +677,58 @@ class Model {
|
|
|
677
677
|
return this.constructor.defaultScope(queryEngine);
|
|
678
678
|
}
|
|
679
679
|
|
|
680
|
+
/// Finalize a query before using it for database operations.
|
|
681
|
+
///
|
|
682
|
+
/// `finalizeQuery` is called on **every** query immediately
|
|
683
|
+
/// before it is used for a database operation. Its only purpose
|
|
684
|
+
/// is to potentially modify the query before the database operation
|
|
685
|
+
/// occurs. This can be extremely useful for things like "row level permissions",
|
|
686
|
+
/// or ensuring that a certain type of query always has certain conditions.
|
|
687
|
+
///
|
|
688
|
+
/// Because it is asynchronous by design, it is possible to finalize the
|
|
689
|
+
/// query using other asynchronous operations; for example validating
|
|
690
|
+
/// authentication tokens, or fetching user roles from the database.
|
|
691
|
+
///
|
|
692
|
+
/// This is called by <see>Connection.finalizeQuery</see> for each unique
|
|
693
|
+
/// model found in the query.
|
|
694
|
+
///
|
|
695
|
+
/// Interface:
|
|
696
|
+
/// interface FinalizeQueryContext {
|
|
697
|
+
/// type: 'create' | 'read' | 'updated' | 'delete'; // The operation type that is about to happen in the underlying database.
|
|
698
|
+
/// query: QueryEngine; // The query being operated upon. Modify and return this.
|
|
699
|
+
/// queryDepth: number; // The depth we are at while walking the query. Will be 0 for root level, 1 for first sub-query, etc...
|
|
700
|
+
/// operationIndex: number; // The "operation stack" index we are at
|
|
701
|
+
/// operation: object; // The "operation" on the query operation stack we are working on
|
|
702
|
+
/// operations: Array<object>; // The query "operation stack"
|
|
703
|
+
/// parent: object | null; // The parent "operation"
|
|
704
|
+
/// contextKey: string; // The name of the key that this query is a value of for this "operation" object. This is usually "value" for most operations, but it could be something else.
|
|
705
|
+
/// options: object; // The options passed into the operation by the user
|
|
706
|
+
/// }
|
|
707
|
+
///
|
|
708
|
+
///
|
|
709
|
+
/// Note:
|
|
710
|
+
/// "With great power comes great responsibility." Use `finalizeQuery` intelligently. It can
|
|
711
|
+
/// cause a noticeable performance hit, and can really make things hard to debug and
|
|
712
|
+
/// understand if you don't clearly document.
|
|
713
|
+
///
|
|
714
|
+
/// Note:
|
|
715
|
+
/// `'create'` isn't actually currently supported, since no queries are
|
|
716
|
+
/// ever used in an `INSERT` operation. It is reserved for future use.
|
|
717
|
+
///
|
|
718
|
+
/// Arguments:
|
|
719
|
+
/// context: FinalizeQueryContext
|
|
720
|
+
/// All provided values in a single context. You will want to modify `query`
|
|
721
|
+
/// and return it... or if you don't modify it, simply return it. The `contextKey`
|
|
722
|
+
/// might be a little confusing. It is the name of the key the query is a value on.
|
|
723
|
+
/// For example, in an `EQ` operation, this would be "value".
|
|
724
|
+
/// i.e. an `EQ` operation looks something like the following on the operation stack:
|
|
725
|
+
/// `{ operator: 'EQ', value: query }`. The reason it is provided is if you need to
|
|
726
|
+
//// directly get or set a value on the operation frame (`operation`).
|
|
727
|
+
///
|
|
728
|
+
/// Return: <see>QueryEngine</see>
|
|
729
|
+
/// The query provided, possibly altered.
|
|
730
|
+
///
|
|
731
|
+
/// See: Connection.finalizeQuery
|
|
680
732
|
// eslint-disable-next-line no-unused-vars
|
|
681
733
|
static finalizeQuery({ type, query, queryDepth, operationIndex, operation, operations, parent, contextKey, options }) {
|
|
682
734
|
return query;
|