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.
@@ -57,20 +57,80 @@ function wrapAnyAll(func) {
57
57
  return func;
58
58
  }
59
59
 
60
+ /// `FieldScope` is the "field level" of a query.
61
+ /// It manages conditions, such as things like `EQ`, `NEQ`,
62
+ /// `GT`, `LT`, etc...
63
+ ///
64
+ /// Any operator completed on this "field scope" will return
65
+ /// the previous `ModelScope` so the user can continue chaining
66
+ /// operations on the query. All operators at this level (except
67
+ /// `NOT`, `AND`, and `OR`) must be called and provided a value.
68
+ ///
69
+ /// See: QueryEngineBase
70
+ ///
71
+ /// See: QueryEngine
72
+ ///
73
+ /// See: ModelScope
74
+ ///
75
+ /// Note:
76
+ /// `FieldScope` is a sub-part of the `QueryEngine`, and so is generally referred to
77
+ /// simply as the `QueryEngine` as a whole. This is also the case for <see>QueryEngineBase</see>,
78
+ /// and <see>ModelScope</see>, which also make up the `QueryEngine` as sub-parts,
79
+ /// and so are also often referred to simply as "the query engine".
60
80
  class FieldScope extends QueryEngineBase {
81
+ /// Invert the logic of the following operator.
82
+ ///
83
+ /// This method does not need to be called.
84
+ ///
85
+ /// Unlike `AND` and `OR` operators, this is not a permanent toggle.
86
+ /// As soon as a following operator is encountered, the `NOT` operation
87
+ /// will be "turned off". `NOT` will invert any operation, so for example
88
+ /// if you did a `User.where.id.NOT.EQ('test')` then this is the same as
89
+ /// `User.where.id.NEQ('test')`--selecting everything NOT EQUAL TO `'test'`.
90
+ /// `NOT` can also be used in combination with `EXISTS`, `ANY`, `ALL`, `IN`,
91
+ /// etc... inverting any operator following `NOT`.
92
+ ///
93
+ /// Note:
94
+ /// `NOT` is only ever used once, and then it is toggled back off. For example,
95
+ /// if we did: `User.where.id.NOT.EQ('test').AND.lastName.EQ('Smith')`, then
96
+ /// we would have a query where `id != 'test' AND lastName = 'Smith'`. As you
97
+ /// can see, the `NOT` doesn't apply to the second `lastName` operator, as it
98
+ /// was turned off as soon as the first `EQ` operator was encountered on the `id`
99
+ /// field.
100
+ ///
101
+ /// SyntaxType: FunctionDeclaration
61
102
  NOT = ProxyClass.autoCall(function() {
62
- this._pushOperationOntoStack({ logical: true, operator: 'NOT', queryProp: 'NOT', not: !this.currentContext.not });
103
+ this._pushOperationOntoStack({ logical: true, operator: 'NOT', queryProp: 'NOT', not: !this.getOperationContext().not });
63
104
  return this[ProxyClass.PROXY];
64
105
  });
65
106
 
66
- unscoped() {
67
- return this.currentContext.queryEngineScope.unscoped(this.currentContext);
68
- }
69
-
70
- toString(...args) {
71
- return this.currentContext.queryEngineScope.toString(...args);
72
- }
73
-
107
+ /// This method assists in conversion of provided values to conditions.
108
+ ///
109
+ /// For example, if you provide a conditional operator (i.e. `EQ`) with
110
+ /// a model, i.e. `Role.where.userID.EQ(User)`, then this method will
111
+ /// look up the primary key field of the model, and use that to create
112
+ /// a table-join.
113
+ ///
114
+ /// If instead you provided a model *instance* as a value, then the primary
115
+ /// key field of that model will be looked up, and the resulting value from
116
+ /// the instance will be used as the value. For example: `Role.where.userID.EQ(userInstance)`
117
+ /// is equivalent to `Role.where.userID.EQ(userInstance.id)`.
118
+ ///
119
+ /// Aside from these two exceptions (model classes, and model instances)
120
+ /// this method will simply return the value it was provided.
121
+ ///
122
+ /// This method is called on **every** value provided to **every** call
123
+ /// to a conditional operator. It can be overloaded if you want to mutate
124
+ /// specific values going into conditional operations.
125
+ ///
126
+ /// Arguments:
127
+ /// value: any
128
+ /// The value being provided to a conditional operator.
129
+ ///
130
+ /// Return: any
131
+ /// If `value` is a model class, then return a table-join query with that model. If
132
+ /// `value` is a model instance, then return the value of the model's primary key field.
133
+ /// Otherwise, return the `value` provided.
74
134
  _fetchOperatorValue(_value) {
75
135
  let value = _value;
76
136
  if (!value)
@@ -98,35 +158,363 @@ class FieldScope extends QueryEngineBase {
98
158
  return value;
99
159
  }
100
160
 
161
+ /// "equals" condition.
162
+ ///
163
+ /// This will check equality with the value(s) provided.
164
+ ///
165
+ /// If `null`, `true`, or `false` are provided as a value,
166
+ /// then the underlying database driver will convert it to
167
+ /// the proper query. For example, given a SQL-type database
168
+ /// driver, these values would be generated in the query as
169
+ /// `"table"."column" IS NULL`, `"table"."column" IS TRUE`, or `"table"."column" IS FALSE`.
170
+ ///
171
+ /// If an array is provided as the value, then this stops being an "equals",
172
+ /// and instead will turn into an `IN` operator (in SQL-type databases).
173
+ /// For example, given the following query: `User.where.id.EQ([ 1, 2, 3, 4 ])`,
174
+ /// the resulting SQL query would be `... WHERE "users"."id" IN(1,2,3,4)`. If a `null`,
175
+ /// `true`, or `false` value is encountered in the array, then the condition
176
+ /// will be grouped, and these values will be split out and handled separately.
177
+ /// For example: `User.where.id.EQ([ 1, 2, 3, null, true, false ])` would result
178
+ /// in the following SQL: `("users"."id" IS NULL OR "users"."id" IS TRUE OR "users"."id" IS FALSE OR "users"."id" IN(1,2,3))`.
179
+ /// If the array provided is empty, than an exception will be thrown. This is for safety reasons.
180
+ /// For example, if one were to do `User.where.id.EQ([]).destroy()`, then the result
181
+ /// would be `DELETE FROM USERS`... truncating your entire table. This is obviously not
182
+ /// at all ideal... so Mythix ORM will throw an exception if an empty array is encountered,
183
+ /// requiring that the user be explicit.
184
+ ///
185
+ /// This condition also has two other variants, `EQ.ALL`, and `EQ.ANY` to check
186
+ /// equality with a sub-query. For example, a `User.where.firstName.EQ.ANY(User.where.age.GTE(18).PROJECT('firstName'))`
187
+ /// would generate the following SQL query: `... WHERE "users"."firstName" = ANY(SELECT "users"."firstName" FROM "users" WHERE "users"."age" >= 18)`,
188
+ /// checking if the users first name matches any of the adult user names in the database.
189
+ /// `ALL` is identical in how it functions, except it uses the `ALL` SQL operator instead of the `ANY` operator.
190
+ /// `ANY` will check to see if any of the resulting rows match, `ALL` (for this conditional only) will also check
191
+ /// if any of the resulting rows of the sub-query match. `ALL` behaves differently than `ANY` for `GT`, `GTE`, `LT`, or `LTE` operators.
192
+ /// For `EQ` and `NEQ` operators, `ANY` and `ALL` behave identically.
193
+ ///
194
+ /// If a sub-query is provided as a value, then one of two things will happen:
195
+ /// 1) If the sub-query has no conditions, then a table-join operation will be the result.
196
+ /// 2) If the sub-query has conditions, then a sub-query will be executed using an `IN` operator.
197
+ /// For example, given the following query: `User.where.id.EQ(User.where.firstName.EQ('Bob').PROJECT('id'))`,
198
+ /// the sub-query **does have conditions** (`EQ('Bob')`), so the following SQL query that would be generated
199
+ /// would be `... WHERE "users"."id" IN (SELECT "users"."id" FROM "users" WHERE "users"."firstName" = 'Bob')`.
200
+ /// If instead a sub-query is provided as a value that **does not have conditions**, such as
201
+ /// `User.where.id.EQ(Role.where.userID)`, then this is specifying a table join, joining on the `"roles"` table
202
+ /// where `"users"."id" = "roles"."userID"`.
203
+ ///
204
+ /// Note:
205
+ /// Mythix ORM has no `IN` operator built into the query engine by design. It is expected
206
+ /// that you will use `EQ` or `NEQ` in combination with an array to get `IN` and `NOT IN`
207
+ /// functionality.
208
+ ///
209
+ /// Arguments:
210
+ /// value: any
211
+ /// The value to check against for equality. If an array is provided, then this operator will
212
+ /// turn into an `IN` operator instead. `null`, `true`, and `false` values are treated separately.
213
+ /// options?: object
214
+ /// Options to supply to the operation. This is not used by Mythix ORM, but is provided should
215
+ /// the user or underlying database driver need options.
216
+ ///
217
+ /// Return: <see>ModelScope</see>
218
+ /// Return a <see>ModelScope</see> to allow the user to continue chaining operations on the query.
219
+ ///
220
+ /// SyntaxType: FunctionDeclaration
101
221
  EQ = wrapAnyAll.call(this, (value, options) => {
102
222
  return addOperatorToQuery.call(this, 'EQ', 'NEQ', value, options);
103
223
  });
104
224
 
225
+ /// "not equals" condition.
226
+ ///
227
+ /// This will check inverse (not) equality with the value(s) provided.
228
+ ///
229
+ /// If `null`, `true`, or `false` are provided as a value,
230
+ /// then the underlying database driver will convert it to
231
+ /// the proper query. For example, given a SQL-type database
232
+ /// driver, these values would be generated in the query as
233
+ /// `"table"."column" IS NOT NULL`, `"table"."column" IS NOT TRUE`, or `"table"."column" IS NOT FALSE`.
234
+ ///
235
+ /// If an array is provided as the value, then this stops being a "not equals",
236
+ /// and instead will turn into a `NOT IN` operator (in SQL-type databases).
237
+ /// For example, given the following query: `User.where.id.NEQ([ 1, 2, 3, 4 ])`,
238
+ /// the resulting SQL query would be `... WHERE "users"."id" NOT IN(1,2,3,4)`. If a `null`,
239
+ /// `true`, or `false` value is encountered in the array, then the condition
240
+ /// will be grouped, and these values will be split out and handled separately.
241
+ /// For example: `User.where.id.NEQ([ 1, 2, 3, null, true, false ])` would result
242
+ /// in the following SQL: `("users"."id" IS NOT NULL AND "users"."id" IS NOT TRUE AND "users"."id" IS NOT FALSE AND "users"."id" NOT IN(1,2,3))`.
243
+ /// If the array provided is empty, than an exception will be thrown. This is for safety reasons.
244
+ /// For example, if one were to do `User.where.id.NEQ([]).destroy()`, then the result
245
+ /// would be `DELETE FROM USERS`... truncating your entire table. This is obviously not
246
+ /// at all ideal... so Mythix ORM will throw an exception if an empty array is encountered,
247
+ /// requiring that the user be explicit.
248
+ ///
249
+ /// This condition also has two other variants, `NEQ.ALL`, and `NEQ.ANY` to check
250
+ /// equality with a sub-query. For example, a `User.where.firstName.NEQ.ANY(User.where.age.GTE(18).PROJECT('firstName'))`
251
+ /// would generate the following SQL query: `... WHERE "users"."firstName" != ANY(SELECT "users"."firstName" FROM "users" WHERE "users"."age" >= 18)`,
252
+ /// checking if the users first name does not match any of the adult user names in the database.
253
+ /// `ALL` is identical in how it functions, except it uses the `ALL` SQL operator instead of the `ANY` operator.
254
+ /// `ANY` will check to see if any of the resulting rows do not match, `ALL` (for this conditional only) will also check
255
+ /// if any of the resulting rows of the sub-query do not match. `ALL` behaves differently than `ANY` for `GT`, `GTE`, `LT`, or `LTE` operators.
256
+ /// For `EQ` and `NEQ` operators, `ANY` and `ALL` behave identically.
257
+ ///
258
+ /// If a sub-query is provided as a value, then one of two things will happen:
259
+ /// 1) If the sub-query has no conditions, then a table-join operation will be the result.
260
+ /// 2) If the sub-query has conditions, then a sub-query will be executed using an `IN` operator.
261
+ /// For example, given the following query: `User.where.id.NEQ(User.where.firstName.EQ('Bob').PROJECT('id'))`,
262
+ /// the sub-query **does have conditions** (`EQ('Bob')`), so the following SQL query that would be generated
263
+ /// would be `... WHERE "users"."id" NOT IN (SELECT "users"."id" FROM "users" WHERE "users"."firstName" = 'Bob')`.
264
+ /// If instead a sub-query is provided as a value that **does not have conditions**, such as
265
+ /// `User.where.id.NEQ(Role.where.userID)`, then this is specifying a table join, joining on the `"roles"` table
266
+ /// where `"users"."id" != "roles"."userID"`.
267
+ ///
268
+ /// Note:
269
+ /// Mythix ORM has no `IN` operator built into the query engine by design. It is expected
270
+ /// that you will use `EQ` or `NEQ` in combination with an array to get `IN` and `NOT IN`
271
+ /// functionality.
272
+ ///
273
+ /// Arguments:
274
+ /// value: any
275
+ /// The value to check against for inverse (not) equality. If an array is provided, then this operator will
276
+ /// turn into an `NOT IN` operator instead. `null`, `true`, and `false` values are treated separately.
277
+ /// options?: object
278
+ /// Options to supply to the operation. This is not used by Mythix ORM, but is provided should
279
+ /// the user or underlying database driver need options.
280
+ ///
281
+ /// Return: <see>ModelScope</see>
282
+ /// Return a <see>ModelScope</see> to allow the user to continue chaining operations on the query.
283
+ ///
284
+ /// SyntaxType: FunctionDeclaration
105
285
  NEQ = wrapAnyAll.call(this, (value, options) => {
106
286
  return addOperatorToQuery.call(this, 'NEQ', 'EQ', value, options);
107
287
  });
108
288
 
289
+ /// "greater than" condition.
290
+ ///
291
+ /// This will check if values in the database are greater than the value provided.
292
+ ///
293
+ /// This condition also has two other variants, `GT.ALL`, and `GT.ANY` to compare
294
+ /// with a sub-query. For example, a `User.where.age.GT.ANY(User.where.age.GTE(18).PROJECT('age'))`
295
+ /// would generate the following SQL query: `... WHERE "users"."age" > ANY(SELECT "users"."age" FROM "users" WHERE "users"."age" >= 18)`,
296
+ /// checking if the users age is greater than any of the adult aged users in the database.
297
+ /// `ALL` is identical in how it functions, except it uses the `ALL` SQL operator instead of the `ANY` operator.
298
+ /// `ANY` will check to see if any of the resulting rows of the sub-query match the condition. `ALL` will compare all returned rows
299
+ /// from the sub-query, and check to see if the value provided is greater than the *largest value* across all
300
+ /// rows of the sub-query.
301
+ ///
302
+ /// If a sub-query is provided as a value, then one of two things will happen:
303
+ /// 1) If the sub-query has no conditions, then a table-join operation will be the result.
304
+ /// 2) If the sub-query has conditions, then any exception will be thrown.
305
+ /// For example, if a sub-query is provided as a value that **does not have conditions**, such as
306
+ /// `User.where.createdAt.GT(Role.where.createdAt)`, then this is specifying a table join, joining on the `"roles"` table
307
+ /// where `"users"."createdAt" > "roles"."createdAt"`.
308
+ ///
309
+ /// Note:
310
+ /// If you want to compare "greater than" on a sub-query, use `GT.ANY`, or `GT.ALL`.
311
+ ///
312
+ /// Arguments:
313
+ /// value: any
314
+ /// The value to compare against for a "greater than" operation. Providing an array, a `null`, a `true`, or
315
+ /// a `false` value will generally throw an exception... unless this means something to the underlying database driver.
316
+ /// options?: object
317
+ /// Options to supply to the operation. This is not used by Mythix ORM, but is provided should
318
+ /// the user or underlying database driver need options.
319
+ ///
320
+ /// Return: <see>ModelScope</see>
321
+ /// Return a <see>ModelScope</see> to allow the user to continue chaining operations on the query.
322
+ ///
323
+ /// SyntaxType: FunctionDeclaration
109
324
  GT = wrapAnyAll.call(this, (value, options) => {
110
325
  return addOperatorToQuery.call(this, 'GT', 'LTE', value, options);
111
326
  });
112
327
 
328
+ /// "greater than or equals to" condition.
329
+ ///
330
+ /// This will check if values in the database are greater than or equal to the value provided.
331
+ ///
332
+ /// This condition also has two other variants, `GTE.ALL`, and `GTE.ANY` to compare
333
+ /// with a sub-query. For example, a `User.where.age.GTE.ANY(User.where.age.GTE(18).PROJECT('age'))`
334
+ /// would generate the following SQL query: `... WHERE "users"."age" >= ANY(SELECT "users"."age" FROM "users" WHERE "users"."age" >= 18)`,
335
+ /// checking if the users age is greater than or equal to any of the adult aged users in the database.
336
+ /// `ALL` is identical in how it functions, except it uses the `ALL` SQL operator instead of the `ANY` operator.
337
+ /// `ANY` will check to see if any of the resulting rows of the sub-query match the condition. `ALL` will compare all returned rows
338
+ /// from the sub-query, and check to see if the value provided is greater than or equal to the *largest value* across all
339
+ /// rows of the sub-query.
340
+ ///
341
+ /// If a sub-query is provided as a value, then one of two things will happen:
342
+ /// 1) If the sub-query has no conditions, then a table-join operation will be the result.
343
+ /// 2) If the sub-query has conditions, then any exception will be thrown.
344
+ /// For example, if a sub-query is provided as a value that **does not have conditions**, such as
345
+ /// `User.where.createdAt.GTE(Role.where.createdAt)`, then this is specifying a table join, joining on the `"roles"` table
346
+ /// where `"users"."createdAt" >= "roles"."createdAt"`.
347
+ ///
348
+ /// Note:
349
+ /// If you want to compare "greater than or equal to" on a sub-query, use `GTE.ANY`, or `GTE.ALL`.
350
+ ///
351
+ /// Arguments:
352
+ /// value: any
353
+ /// The value to compare against for a "greater than or equal to" operation. Providing an array, a `null`, a `true`, or
354
+ /// a `false` value will generally throw an exception... unless this means something to the underlying database driver.
355
+ /// options?: object
356
+ /// Options to supply to the operation. This is not used by Mythix ORM, but is provided should
357
+ /// the user or underlying database driver need options.
358
+ ///
359
+ /// Return: <see>ModelScope</see>
360
+ /// Return a <see>ModelScope</see> to allow the user to continue chaining operations on the query.
361
+ ///
362
+ /// SyntaxType: FunctionDeclaration
113
363
  GTE = wrapAnyAll.call(this, (value, options) => {
114
364
  return addOperatorToQuery.call(this, 'GTE', 'LT', value, options);
115
365
  });
116
366
 
367
+ /// "less than" condition.
368
+ ///
369
+ /// This will check if values in the database are less than the value provided.
370
+ ///
371
+ /// This condition also has two other variants, `LT.ALL`, and `LT.ANY` to compare
372
+ /// with a sub-query. For example, a `User.where.age.LT.ANY(User.where.age.GTE(18).PROJECT('age'))`
373
+ /// would generate the following SQL query: `... WHERE "users"."age" < ANY(SELECT "users"."age" FROM "users" WHERE "users"."age" >= 18)`,
374
+ /// checking if the users age is less than any of the adult aged users in the database.
375
+ /// `ALL` is identical in how it functions, except it uses the `ALL` SQL operator instead of the `ANY` operator.
376
+ /// `ANY` will check to see if any of the resulting rows of the sub-query match the condition. `ALL` will compare all returned rows
377
+ /// from the sub-query, and check to see if the value provided is less than the *smallest value* across all
378
+ /// rows of the sub-query.
379
+ ///
380
+ /// If a sub-query is provided as a value, then one of two things will happen:
381
+ /// 1) If the sub-query has no conditions, then a table-join operation will be the result.
382
+ /// 2) If the sub-query has conditions, then any exception will be thrown.
383
+ /// For example, if a sub-query is provided as a value that **does not have conditions**, such as
384
+ /// `User.where.createdAt.LT(Role.where.createdAt)`, then this is specifying a table join, joining on the `"roles"` table
385
+ /// where `"users"."createdAt" < "roles"."createdAt"`.
386
+ ///
387
+ /// Note:
388
+ /// If you want to compare "less than" on a sub-query, use `LT.ANY`, or `LT.ALL`.
389
+ ///
390
+ /// Arguments:
391
+ /// value: any
392
+ /// The value to compare against for a "less than" operation. Providing an array, a `null`, a `true`, or
393
+ /// a `false` value will generally throw an exception... unless this means something to the underlying database driver.
394
+ /// options?: object
395
+ /// Options to supply to the operation. This is not used by Mythix ORM, but is provided should
396
+ /// the user or underlying database driver need options.
397
+ ///
398
+ /// Return: <see>ModelScope</see>
399
+ /// Return a <see>ModelScope</see> to allow the user to continue chaining operations on the query.
400
+ ///
401
+ /// SyntaxType: FunctionDeclaration
117
402
  LT = wrapAnyAll.call(this, (value, options) => {
118
403
  return addOperatorToQuery.call(this, 'LT', 'GTE', value, options);
119
404
  });
120
405
 
406
+ /// "less than or equals to" condition.
407
+ ///
408
+ /// This will check if values in the database are less than or equal to the value provided.
409
+ ///
410
+ /// This condition also has two other variants, `LTE.ALL`, and `LTE.ANY` to compare
411
+ /// with a sub-query. For example, a `User.where.age.LTE.ANY(User.where.age.GTE(18).PROJECT('age'))`
412
+ /// would generate the following SQL query: `... WHERE "users"."age" <= ANY(SELECT "users"."age" FROM "users" WHERE "users"."age" >= 18)`,
413
+ /// checking if the users age is less than or equal to any of the adult aged users in the database.
414
+ /// `ALL` is identical in how it functions, except it uses the `ALL` SQL operator instead of the `ANY` operator.
415
+ /// `ANY` will check to see if any of the resulting rows of the sub-query match the condition. `ALL` will compare all returned rows
416
+ /// from the sub-query, and check to see if the value provided is less than or equal to the *smallest value* across all
417
+ /// rows of the sub-query.
418
+ ///
419
+ /// If a sub-query is provided as a value, then one of two things will happen:
420
+ /// 1) If the sub-query has no conditions, then a table-join operation will be the result.
421
+ /// 2) If the sub-query has conditions, then any exception will be thrown.
422
+ /// For example, if a sub-query is provided as a value that **does not have conditions**, such as
423
+ /// `User.where.createdAt.LTE(Role.where.createdAt)`, then this is specifying a table join, joining on the `"roles"` table
424
+ /// where `"users"."createdAt" <= "roles"."createdAt"`.
425
+ ///
426
+ /// Note:
427
+ /// If you want to compare "less than or equal to" on a sub-query, use `LTE.ANY`, or `LTE.ALL`.
428
+ ///
429
+ /// Arguments:
430
+ /// value: any
431
+ /// The value to compare against for a "less than or equal to" operation. Providing an array, a `null`, a `true`, or
432
+ /// a `false` value will generally throw an exception... unless this means something to the underlying database driver.
433
+ /// options?: object
434
+ /// Options to supply to the operation. This is not used by Mythix ORM, but is provided should
435
+ /// the user or underlying database driver need options.
436
+ ///
437
+ /// Return: <see>ModelScope</see>
438
+ /// Return a <see>ModelScope</see> to allow the user to continue chaining operations on the query.
439
+ ///
440
+ /// SyntaxType: FunctionDeclaration
121
441
  LTE = wrapAnyAll.call(this, (value, options) => {
122
442
  return addOperatorToQuery.call(this, 'LTE', 'GT', value, options);
123
443
  });
124
444
 
445
+ /// A "like" wildcard condition.
446
+ ///
447
+ /// This will check if values in the database are "like" the value provided, using wildcards and pattern matching.
448
+ ///
449
+ /// The `LIKE` operator in Mythix ORM follows PostgreSQL design, using `%` for a "zero or more" match, and an `_`
450
+ /// for a "single character" match. All database engines are required to follow this pattern, even if the underlying
451
+ /// database uses a different syntax. If that is the case, then the underlying database driver is required to behave
452
+ /// correctly by translating the value to the input it expects. In short, the interface here in Mythix ORM is unified,
453
+ /// and it is up to the underlying database driver to carry out the operation correctly.
454
+ ///
455
+ /// The "escape character" for this operation is always set to a backslash `\` for all database drivers. So if you
456
+ /// need to match against a literal `%` or `_` character, you would do so by using the escape character, i.e. `LIKE('100\\%')`.
457
+ /// Two escape characters are needed, because Javascript also interprets `\` as an escape character, so a double backslash
458
+ /// `'\\'` will "escape" to a single backslash in Javascript.
459
+ ///
460
+ /// For all databases, the Mythix ORM `LIKE` is case-insensitive. For databases like PostgreSQL, a standard Mythix ORM `LIKE` operation
461
+ /// is actually carried out as an `ILIKE` operation to follow this convention of case-insensitivity. There is
462
+ /// a boolean `options` that can be supplied to this operator, named `caseSensitive`. If supplied, for example
463
+ /// `LIKE('%something%', { caseSensitive: true })`, then the operation will be case-sensitive... but only if the underlying database
464
+ /// supports case-sensitivity for `LIKE`... and not all databases do. `LIKE` operations in most SQL databases are case-insensitive by default.
465
+ ///
466
+ /// Arguments:
467
+ /// value: any
468
+ /// The value to compare against for a "LIKE" operation. Providing any non-string value will
469
+ /// likely throw an exception... unless the underlying database driver supports other pattern
470
+ /// formats (i.e. `RegExp` is supported in Mongo).
471
+ /// options?: object
472
+ /// Options to supply to the operation. The only option supported for this operator is the boolean
473
+ /// option `caseSensitive`. If `true`, then the database driver will attempt to carry out a case-sensitive
474
+ /// operation. If not supported by the database, then the database driver should throw an exception.
475
+ /// If a `RegExp` value is used (for databases that support it), then this option will be ignored.
476
+ ///
477
+ /// Return: <see>ModelScope</see>
478
+ /// Return a <see>ModelScope</see> to allow the user to continue chaining operations on the query.
125
479
  LIKE(value, options) {
126
480
  let caseSensitive = ((options && options.caseSensitive) === true);
127
481
  return addOperatorToQuery.call(this, 'LIKE', 'NOT_LIKE', value, { caseSensitive });
128
482
  }
129
483
 
484
+ /// A "not like" wildcard condition.
485
+ ///
486
+ /// This will check if values in the database are "not like" the value provided, using wildcards and pattern matching.
487
+ ///
488
+ /// The `LIKE` operator in Mythix ORM follows PostgreSQL design, using `%` for a "zero or more" match, and an `_`
489
+ /// for a "single character" match. All database engines are required to follow this pattern, even if the underlying
490
+ /// database uses a different syntax. If that is the case, then the underlying database driver is required to behave
491
+ /// correctly by translating the value to the input it expects. In short, the interface here in Mythix ORM is unified,
492
+ /// and it is up to the underlying database driver to carry out the operation correctly.
493
+ ///
494
+ /// The "escape character" for this operation is always set to a backslash `\` for all database drivers. So if you
495
+ /// need to match against a literal `%` or `_` character, you would do so by using the escape character, i.e. `NOT LIKE('100\\%')`.
496
+ /// Two escape characters are needed, because Javascript also interprets `\` as an escape character, so a double backslash
497
+ /// `'\\'` will "escape" to a single backslash in Javascript.
498
+ ///
499
+ /// For all databases, the Mythix ORM `NOT_LIKE` is case-insensitive. For databases like PostgreSQL, a standard Mythix ORM `NOT_LIKE` operation
500
+ /// is actually carried out as an `NOT ILIKE` operation to follow this convention of case-insensitivity. There is
501
+ /// a boolean `options` that can be supplied to this operator, named `caseSensitive`. If supplied, for example
502
+ /// `NOT_LIKE('%something%', { caseSensitive: true })`, then the operation will be case-sensitive... but only if the underlying database
503
+ /// supports case-sensitivity for `NOT LIKE`... and not all databases do. `NOT LIKE` operations in most SQL databases are case-insensitive by default.
504
+ ///
505
+ /// Arguments:
506
+ /// value: any
507
+ /// The value to compare against for a "NOT LIKE" operation. Providing any non-string value will
508
+ /// likely throw an exception... unless the underlying database driver supports other pattern
509
+ /// formats (i.e. `RegExp` is supported in Mongo).
510
+ /// options?: object
511
+ /// Options to supply to the operation. The only option supported for this operator is the boolean
512
+ /// option `caseSensitive`. If `true`, then the database driver will attempt to carry out a case-sensitive
513
+ /// operation. If not supported by the database, then the database driver should throw an exception.
514
+ /// If a `RegExp` value is used (for databases that support it), then this option will be ignored.
515
+ ///
516
+ /// Return: <see>ModelScope</see>
517
+ /// Return a <see>ModelScope</see> to allow the user to continue chaining operations on the query.
130
518
  NOT_LIKE(value, options) {
131
519
  let caseSensitive = ((options && options.caseSensitive) === true);
132
520
  return addOperatorToQuery.call(this, 'NOT_LIKE', 'LIKE', value, { caseSensitive });
@@ -136,6 +524,10 @@ class FieldScope extends QueryEngineBase {
136
524
  let lowerScope = this._fetchScope('model');
137
525
  return lowerScope[prop];
138
526
  }
527
+
528
+ toString(...args) {
529
+ return this.getOperationContext().queryEngineScope.toString(...args);
530
+ }
139
531
  }
140
532
 
141
533
  module.exports = FieldScope;