mythix-orm 1.11.6 → 1.11.7

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 CHANGED
@@ -1,15 +1,106 @@
1
1
  # mythix-orm
2
2
 
3
- ORM for Mythix framework
3
+ Mythix ORM aims to replace Sequelize and the few other terrible solutions that the poor destitute Node community has to work with. Mythix ORM has been designed to replace all current ORMs for Node, with a focus on what is lacking in the community, namely good engineering, good documentation, and ease of use.
4
4
 
5
- Mythix ORM aims to replace Sequelize and the few other terrible solutions that the poor destitute Node community has to work with. Mythix ORM is not yet quite ready for prime time however, so please check back soon!
6
-
7
- What to expect while you are waiting:
8
- 1. Advanced, seamless, and powerful (yet simple) query engine that is easy to use, and works across database drivers, even for No-SQL databases. Here is a simple example to fetch users and their roles: `let users = await User.where.id.EQ(Role.where.userID).firstName.EQ('Mythix').lastName.EQ('ORM').Roles.name.EQ('superuser').PROJECT('User', 'Role').all();`
5
+ Mythix ORMs feature set includes:
6
+ 1. An advanced, seamless, and powerful (yet simple) query engine that is easy to use, and works across database drivers, even for No-SQL databases.
9
7
  2. Powerful model classes and helpers that don't violate good design patterns, stay out of your face, and have no undocumented auto-magic built in. The model system is also designed to work seamlessly across different databases, including No-SQL databases.
10
8
  3. Simple, clean, and slim... Mythix ORM isn't intended to be a sledge hammer, nor a 'batteries included' framework. Instead, it is designed to be a useful tool, and was designed to be easily extended. It can be used for large enterprise applications, or it can be used as a simple slim layer to interact with different databases in a human-friendly way.
11
- 4. Mythix ORM is modular by design. Instead of being a large bloated library that attempts to handle every database and every type of operation, it instead only provides exactly what you need. Mythix ORM is itself just a base connection, a query engine, and a model and type system. That is all. To interact with databases you can choose between any number of drivers for Mythix ORM, and can use community built plugins for adding features (or simply write your own!).
12
- 5. Mythix ORM is designed from the ground-up to be extended/modified. Want to change the nature of the Query Engine? Just extend from it and away you go! Want to change the way models behave? No problem! Want to make your own connection? Go for it! Want to add your own custom data types for models? Super easy. Every part of Mythix ORM is designed to be swapped out in a non-global way so that its feature set can be extended and added onto.
13
- 6. Has complete feature parity (and soon greater functionality) then all existing ORMs for Node. Model validation, hooks, model attributes and data types, model relations, support for multiple databases, an advanced query engine, transactions, transactions inside transactions, useful utility methods, an extensible type system, virtual types, an extensible query generator, support for older Node versions, support for multiple connections and multiplex connections (at the same time), and more!
9
+ 4. A modular design. Instead of being a large bloated library that attempts to handle every database and every type of operation, it instead only provides exactly what you need. Mythix ORM is itself just a base connection, a query engine, and a model and type system. That is all. To interact with databases you can choose between any number of drivers for Mythix ORM (coming soon!), and can use community-built plugins for adding features (or simply write your own!).
10
+ 5. A deliberate design to be extended and added onto. Easily modify the Query Engine to add more features, create your own database driver, modify how models behave, or add your own custom data types. The sky is the limit!
11
+ 6. Complete feature parity (and soon greater functionality) then all existing ORMs for Node. Model validation, hooks, model attributes and data types, model relations, support for multiple databases, an advanced query engine, transactions, transactions inside transactions, useful utility methods, an extensible type system, virtual types, an extensible query generator, support for older Node versions, support for multiple connections and multiplex connections (at the same time), and more!
12
+
13
+ Mythix ORM is still in its very early stages, and is looking for users! It is stable, and currently has native support for SQLite and PostgreSQL. A mongo driver will be added next, and after that MySQL. If you want to help then drop me a line! All help is welcome.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm i --save mythix-orm mythix-orm-sqlite
19
+ ```
20
+
21
+ ## Documentation
22
+
23
+ Check out the [WIKI](https://github.com/th317erd/mythix-orm/wiki) for documentation.
24
+
25
+ ## Getting started
26
+
27
+ Just start creating models!
28
+
29
+ ```javascript
30
+ const { Model, Types } = require('mythix-orm');
31
+ const SQLiteConnection = require('mythix-orm-sqlite');
32
+
33
+ class User extends Model {
34
+ static fields = {
35
+ id: {
36
+ type: Types.XID(),
37
+ defaultValue: Types.XID.Defaults.XID,
38
+ allowNull: false,
39
+ primaryKey: true,
40
+ },
41
+ email: {
42
+ type: Types.STRING(128),
43
+ allowNull: false,
44
+ index: true,
45
+ unique: true,
46
+ },
47
+ firstName: {
48
+ type: Types.STRING(64),
49
+ allowNull: false,
50
+ index: true,
51
+ },
52
+ lastName: {
53
+ type: Types.STRING(64),
54
+ allowNull: false,
55
+ index: true,
56
+ },
57
+ };
58
+ }
59
+
60
+ // Entry point
61
+ (async function() {
62
+ // Define a connection, and "bind" our models to it
63
+ let connection = new SQLiteConnection({
64
+ models: [
65
+ User,
66
+ ],
67
+ });
68
+
69
+ // Fire up our connection
70
+ await connection.start();
71
+
72
+ // Create our tables needed for our User
73
+ // model in SQLite
74
+ await connection.createTables([ User ]);
75
+
76
+ // Now we can store and load a user
77
+ let user = new User({
78
+ email: 'test@example.com',
79
+ firstName: 'Test',
80
+ lastName: 'User',
81
+ });
82
+
83
+ // Store user
84
+ await user.save();
85
+
86
+ // Reload user by querying on the
87
+ // user's email address
88
+ user = await User.where.email.EQ('test@example.com').first();
89
+
90
+ // Serialize to JSON
91
+ console.log('My user: ', JSON.stringify(user, undefined, 2));
92
+
93
+ // Shutdown our connection
94
+ await connection.stop();
95
+ })();
96
+ ```
97
+
98
+ ## Notes
99
+
100
+ 1. The [WIKI](https://github.com/th317erd/mythix-orm/wiki) is still being worked on. Most of the documentation is complete, but there is still a lot more to write. Documentation is the main focus right now. There is a lot more to write. If you have any questions, feel free to drop a line, or open an issue! We will be happy to answer any questions. We aren't "done" until our documentation is pristine.
101
+ 2. Right now there are only database drivers for [SQLite](https://www.npmjs.com/package/mythix-orm-sqlite) and [PostgreSQL](https://www.npmjs.com/package/mythix-orm-postgresql). More are planned, with a Mongo driver likely to land next, followed by MySQL. Help wanted!
102
+ 3. Check out the [Mythix](https://www.npmjs.com/package/mythix) web-app framework. It is also still in active development, and the documentation is poor (to say the least), but it is up and coming, and will soon have fantastic documentation, and even though still in active development is fully functional. To get started try `npx mythix-cli create 'Test App'`
103
+
104
+ ## Goals
14
105
 
15
- Stay tuned! Mythix ORM should be released and fully documented by Q1 of 2023!
106
+ The `Mythix` suite of technologies are being developed to give a rock-solid full-stack to build web-apps on Node. I got tired of the piecemeal garbage that currently exist in the Node ecosystem for building apps. My end goal is to have `Mythix` technologies take the Node community by storm, providing top-notch technologies for developers to create amazing things. Get involved with me, and let's change the world for the better!
@@ -280,6 +280,39 @@ class ConnectionBase extends EventEmitter {
280
280
  return new QueryGeneratorBase(this);
281
281
  }
282
282
 
283
+ /// An `Object.assign` type of operation... with a twist.
284
+ ///
285
+ /// `stackAssign` works kinda like `Object.assign`. It has
286
+ /// the same interface, and accomplishes the same result.
287
+ /// What it does differently however is that it uses
288
+ /// `Object.create` on the first argument to create a new
289
+ /// object, using the first argument as a prototype. It then
290
+ /// merges all remaining `object` arguments into this newly
291
+ /// created object.
292
+ ///
293
+ /// This is used quite heavily in the underlying Mythix ORM engine.
294
+ /// It's purpose is to modify `options` arguments as they pass through
295
+ /// the engine. For example, a `destroy` operation might want to inform
296
+ /// the projection engine that we don't want any field aliases... and
297
+ /// so it will `stackAssign` the `options`, setting `noProjectionAliases: true`
298
+ /// for the "stacked options" object. Javascript--being the prototypical language
299
+ /// that it is--will *behave* like the objects in question have been
300
+ /// passed through `Object.assign`, because all the original `options` to
301
+ /// any operation are still accessible in the prototype, but may have been
302
+ /// overridden like in our example of a `destroy` operation. This allows the
303
+ /// engine to easily and quickly override options without mutating the original
304
+ /// `options` object provided, and still be able to access provided options,
305
+ /// even if they are not enumerable.
306
+ ///
307
+ /// Arguments:
308
+ /// obj: object
309
+ /// The object to set as the prototype of the newly created object,
310
+ /// using `Object.create` on it.
311
+ /// ...args: Array<object>
312
+ /// The other objects to merge into this object, using `Object.assign`.
313
+ ///
314
+ /// Return: object
315
+ /// The newly "stacked" and merged object.
283
316
  stackAssign(obj, ..._args) {
284
317
  let newObj = Object.create(obj || {});
285
318
  let args = _args.filter(Boolean);
@@ -347,12 +380,14 @@ class ConnectionBase extends EventEmitter {
347
380
  }
348
381
 
349
382
  /// Get the default order for selecting rows
350
- /// from the database. This will call the
351
- /// Model's <see name="Model.defaultOrder">Model.static defaultOrder</see> method
352
- /// first to see if the model specifies a default order
353
- /// for itself. If it doesn't, then the connection
383
+ /// from the database. The connection
354
384
  /// driver itself might specify a default order for
355
- /// each table.
385
+ /// each table, if one isn't specified by the user.
386
+ ///
387
+ /// Note:
388
+ /// To specify a default order for each model, use
389
+ /// the <see>Model.static defaultScope</see> method
390
+ /// instead.
356
391
  ///
357
392
  /// Arguments:
358
393
  /// Model: class <see>Model</see>
@@ -408,6 +443,35 @@ class ConnectionBase extends EventEmitter {
408
443
  return true;
409
444
  }
410
445
 
446
+ /// A convenience method to get from "model cache".
447
+ ///
448
+ /// Model Cache is a simple system to cache
449
+ /// random results from model methods. This is used
450
+ /// for things that should never change, for example
451
+ /// the models fields, the models name, the table
452
+ /// name for the model, etc... Some of these values
453
+ /// are initially computed, and then cached using this
454
+ /// system so operations later on return much quicker.
455
+ ///
456
+ /// Note:
457
+ /// The underlying cache system uses the `Map` type,
458
+ /// so any value can be used as a cache key.
459
+ ///
460
+ /// Note:
461
+ /// This cache is never cleared or marked as stale, so
462
+ /// if using dynamic cache keys, make sure that you
463
+ /// properly remove them later to prevent memory leaks.
464
+ ///
465
+ /// Arguments:
466
+ /// Model: class <see>Model</see>
467
+ /// The model class we a caching for.
468
+ /// key: any
469
+ /// The key to use for our cache.
470
+ /// defaultValue?: any
471
+ /// The default value to return if no cache entry was found.
472
+ ///
473
+ /// Return: any
474
+ /// Any value found in the cache.
411
475
  _getFromModelCache(Model, key, defaultValue) {
412
476
  let cache = this._modelCache.get(Model);
413
477
  if (!cache)
@@ -420,6 +484,35 @@ class ConnectionBase extends EventEmitter {
420
484
  return value;
421
485
  }
422
486
 
487
+ /// A convenience method to set to the "model cache".
488
+ ///
489
+ /// Model Cache is a simple system to cache
490
+ /// random results from model methods. This is used
491
+ /// for things that should never change, for example
492
+ /// the models fields, the models name, the table
493
+ /// name for the model, etc... Some of these values
494
+ /// are initially computed, and then cached using this
495
+ /// system so operations later on return much quicker.
496
+ ///
497
+ /// Note:
498
+ /// The underlying cache system uses the `Map` type,
499
+ /// so any value can be used as a cache key.
500
+ ///
501
+ /// Note:
502
+ /// This cache is never cleared or marked as stale, so
503
+ /// if using dynamic cache keys, make sure that you
504
+ /// properly remove them later to prevent memory leaks.
505
+ ///
506
+ /// Arguments:
507
+ /// Model: class <see>Model</see>
508
+ /// The model class we a caching for.
509
+ /// key: any
510
+ /// The key to use for our cache.
511
+ /// value: any
512
+ /// The value to cache.
513
+ ///
514
+ /// Return: any
515
+ /// The `value` provided.
423
516
  _setToModelCache(Model, key, value) {
424
517
  let cache = this._modelCache.get(Model);
425
518
  if (!cache) {
@@ -493,6 +586,51 @@ class ConnectionBase extends EventEmitter {
493
586
  return queryEngine;
494
587
  }
495
588
 
589
+ /// Finalize a query before using it for database operations.
590
+ ///
591
+ /// `finalizeQuery` is called on **every** query immediately
592
+ /// before it is used for a database operation. Its only purpose
593
+ /// is to potentially modify the query before the database operation
594
+ /// occurs. This can be extremely useful for things like "row level permissions",
595
+ /// or ensuring that a certain type of query always has certain conditions.
596
+ ///
597
+ /// Because it is asynchronous by design, it is possible to finalize the
598
+ /// query using other asynchronous operations; for example validating
599
+ /// authentication tokens, or fetching user roles from the database.
600
+ ///
601
+ /// It works by walking the provided query, and calling <see>Model.static finalizeQuery</see>
602
+ /// on every model it encounters that is used in the query. It will also recursively
603
+ /// call itself for every new query it encounters that is part of the query,
604
+ /// for example sub-queries. In this way, you can take on extra conditions to any
605
+ /// part of a query, throw a "Forbidden" exception if the user is disallowed from querying
606
+ /// certain data, or whatever you want.
607
+ ///
608
+ /// Note:
609
+ /// "With great power comes great responsibility." Use `finalizeQuery` intelligently. It can
610
+ /// cause a noticeable performance hit, and can really make things hard to debug and
611
+ /// understand if you don't clearly document.
612
+ ///
613
+ /// Note:
614
+ /// `'create'` isn't actually currently supported, since no queries are
615
+ /// ever used in an `INSERT` operation. It is reserved for future use.
616
+ ///
617
+ /// Arguments:
618
+ /// crudOperation: 'create' | 'read' | 'update' | 'delete'
619
+ /// The Mythix ORM reports what "type" of operation is being executed
620
+ /// using this argument. This is used so one can know if the operation
621
+ /// that is about to be executed is a `read`, `update`, or `delete` operation.
622
+ /// query: <see>QueryEngine</see>
623
+ /// The query to operate upon. This will be walked, calling <see>Model.static finalizeQuery</see>
624
+ /// for each unique model encountered, and also recursively walking any sub-queries.
625
+ /// options?: object
626
+ /// Random options for the operation. These are not used by this method, but instead are
627
+ /// the `options` provided to the database operation when it was requested, and are also
628
+ /// available for use for any user needs.
629
+ ///
630
+ /// Return: <see>QueryEngine</see>
631
+ /// The query provided, possibly altered.
632
+ ///
633
+ /// See: Model.static finalizeQuery
496
634
  async finalizeQuery(crudOperation, queryEngine, options) {
497
635
  if (!QueryEngine.isQuery(queryEngine))
498
636
  return queryEngine;
@@ -1382,10 +1520,10 @@ class ConnectionBase extends EventEmitter {
1382
1520
  /// will be database specific. The database driver connection
1383
1521
  /// is free to override this method.
1384
1522
  ///
1385
- /// This method will convert a <see>AverageLiteral</see>, a
1386
- /// <see>CountLiteral</see>, a <see>DistinctLiteral</see>,
1387
- /// a <see>FieldLiteral</see>, a <see>MaxLiteral</see>, a
1388
- /// <see>MinLiteral</see>, a <see>SumLiteral</see>, or a
1523
+ /// This method will convert an <see>AverageLiteral</see>,
1524
+ /// <see>CountLiteral</see>, <see>DistinctLiteral</see>,
1525
+ /// <see>FieldLiteral</see>, <see>MaxLiteral</see>,
1526
+ /// <see>MinLiteral</see>, <see>SumLiteral</see>, or a
1389
1527
  /// <see>Literal</see> to a string. If the provided literal
1390
1528
  /// is not one of these types, than an exception will be thrown.
1391
1529
  ///
@@ -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 `AVG(column)`. This is
17
+ /// often used by the projection engine, to project it as a column
18
+ /// to be selected. For example `SELECT AVG(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.AverageLiteral`.
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.AverageLiteral('User:age');
40
+ /// let literal2 = new SQLiteConnection.Literals.AverageLiteral('User:age');
41
+ ///
42
+ /// See: LiteralFieldBase
43
+ ///
44
+ /// See: LiteralBase
5
45
  class AverageLiteral 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. `'AverageLiteral {}'`.
61
+ ///
62
+ /// Note:
63
+ /// Ultimately, for most connections, this will end up calling
64
+ /// <see>QueryGenerator._averageLiteralToString</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,15 +2,95 @@
2
2
 
3
3
  const LiteralFieldBase = require('./literal-field-base');
4
4
 
5
+ /// Define a "count" 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 a "count" operation across all matching
11
+ /// rows. It is used by <see>Connection.count</see> to get
12
+ /// the number of matching rows for a query. When serialized using
13
+ /// the <see>QueryGenerator</see> for the connection, it will turn
14
+ /// into a database method that is appropriate for the underlying database.
15
+ /// For example, with SQL type databases this would turn into `COUNT(column)`,
16
+ /// our `COUNT(*)`. This is often used by the projection engine, to project
17
+ /// it as a column to be selected. For example `SELECT COUNT(column) AS count ...`.
18
+ /// It can be used in other places in the query however, such as `ORDER`,
19
+ /// `GROUP BY`, and `HAVING` clauses.
20
+ ///
21
+ /// Note:
22
+ /// If no field is provided to `CountLiteral`
23
+ /// then all fields (`*`) is assumed.
24
+ ///
25
+ /// Note:
26
+ /// It is common to use the `{ as: 'count' }` option to give the count
27
+ /// literal an alias (name).
28
+ ///
29
+ /// There are two primary ways to access literals in Mythix ORM. The
30
+ /// first is to simply import them. The second way literals can be
31
+ /// accessed is via the connection class itself. All Mythix ORM connection
32
+ /// classes export all literals on the `static Literals` attribute of
33
+ /// the class. So for example, you could access literals like `SQLiteConnection.Literals.CountLiteral`.
34
+ ///
35
+ /// All built-in Mythix ORM literals--except `Literal` and `LiteralBase`--accept a field
36
+ /// as their first argument. This field can be a fully qualified field name, an actual
37
+ /// <see>Field</see> instance, or another literal. The second argument to all literal constructors
38
+ /// is an `options` object, that generally contains connection-specific (and operation-specific) options...
39
+ /// however, there are common options that can be supplied, such as `as: string;` which allows you to
40
+ /// define an alias for the defined field, and `noProjectionAliases: boolean;`, which allows you to disable
41
+ /// the column alias entirely.
42
+ ///
43
+ /// Example:
44
+ /// const { Literals } = require('mythix-orm');
45
+ /// const { SQLiteConnection } = require('mythix-orm-sqlite');
46
+ /// let literal1 = new Literals.CountLiteral('*', { as: 'count' });
47
+ /// let literal2 = new SQLiteConnection.CountLiteral.CountLiteral('*', { as: 'count' });
48
+ ///
49
+ /// See: LiteralFieldBase
50
+ ///
51
+ /// See: LiteralBase
5
52
  class CountLiteral extends LiteralFieldBase {
53
+ /// Return `false`, informing the engine that
54
+ /// a field is not required for this literal type.
55
+ ///
56
+ /// Return: boolean
57
+ /// Return `false`, informing the caller that this literal
58
+ /// does not require a field.
6
59
  static isFieldRequired() {
7
60
  return false;
8
61
  }
9
62
 
63
+ /// Return `true`, letting the caller know that
64
+ /// this is an "aggregating literal".
65
+ ///
66
+ /// Return: boolean
67
+ /// Return `true`, informing the caller that this literal is used for aggregate operations.
10
68
  static isAggregate() {
11
69
  return true;
12
70
  }
13
71
 
72
+ /// Convert this literal to a string to be used in a database query.
73
+ ///
74
+ /// This method proxies the conversion of this literal to the connection
75
+ /// by calling <see>Connection.literalToString</see>. If no connection
76
+ /// is provided when this is called, then the literal will be converted
77
+ /// to a string representing it for debugging, i.e. `'CountLiteral {}'`.
78
+ ///
79
+ /// Note:
80
+ /// Ultimately, for most connections, this will end up calling
81
+ /// <see>QueryGenerator._countLiteralToString</see>.
82
+ ///
83
+ /// Arguments:
84
+ /// connection?: <see>Connection</see>
85
+ /// The connection to use to stringify this literal. If none is provided,
86
+ /// then a string representing this object will be returned instead.
87
+ /// options?: object
88
+ /// A connection and operation specific set of options that can be provided.
89
+ /// This might for example be `{ as: 'name' }` to provided a field alias, or
90
+ /// `{ isProjection: true }` to define that this is being stringified for use
91
+ /// as a field in the query projection. Normally the end-user won't care about
92
+ /// any literal options, except `as`, which is commonly used to give your literal
93
+ /// an alias.
14
94
  toString(connection, options) {
15
95
  if (!connection)
16
96
  return `${this.constructor.name} {}`;
@@ -2,7 +2,78 @@
2
2
 
3
3
  const LiteralFieldBase = require('./literal-field-base');
4
4
 
5
+ /// Define a "distinct" 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 a "distinct" operation across a single
11
+ /// column, or entire rows. Distinct is a little different than
12
+ /// most other literals. Whereas most other literals are simply
13
+ /// used as "values"--either identifiers, methods, or values--this
14
+ /// `DistinctLiteral` defines an entire state for a query. It can modify
15
+ /// the projection, the order, or modify the query in other ways. On
16
+ /// some database drivers, it may cause the engine to take an entirely
17
+ /// different path to fetch the data requested. `DistinctLiteral` requires
18
+ /// a field, or another literal. It may or may not use this field in
19
+ /// underlying database operations. However, to remain
20
+ /// consistent in the interface and across databases, it is required.
21
+ /// There are some cases in which a `DistinctLiteral` may not alter how
22
+ /// a query is carried out. One of these is if it is used as an argument to another
23
+ /// literal. For example, if one were to use a `DistinctLiteral` inside a
24
+ /// `CountLiteral`, then it would count distinctly across rows, not modify how the
25
+ /// query is carried out: `new CountLiteral(new DistinctLiteral('User:id'))`.
26
+ ///
27
+ /// There are two primary ways to access literals in Mythix ORM. The
28
+ /// first is to simply import them. The second way literals can be
29
+ /// accessed is via the connection class itself. All Mythix ORM connection
30
+ /// classes export all literals on the `static Literals` attribute of
31
+ /// the class. So for example, you could access literals like `SQLiteConnection.Literals.DistinctLiteral`.
32
+ ///
33
+ /// All built-in Mythix ORM literals--except `Literal` and `LiteralBase`--accept a field
34
+ /// as their first argument. This field can be a fully qualified field name, an actual
35
+ /// <see>Field</see> instance, or another literal. The second argument to all literal constructors
36
+ /// is an `options` object, that generally contains connection-specific (and operation-specific) options...
37
+ /// however, there are common options that can be supplied, such as `as: string;` which allows you to
38
+ /// define an alias for the defined field, and `noProjectionAliases: boolean;`, which allows you to disable
39
+ /// the column alias entirely.
40
+ ///
41
+ /// Note:
42
+ /// The `DistinctLiteral` is rarely used directly. Normally you would want to
43
+ /// call `query.DISTINCT` instead, which internally uses this literal.
44
+ ///
45
+ /// Example:
46
+ /// const { Literals } = require('mythix-orm');
47
+ /// const { SQLiteConnection } = require('mythix-orm-sqlite');
48
+ /// let literal1 = new Literals.DistinctLiteral('User:firstName');
49
+ /// let literal2 = new SQLiteConnection.Literals.DistinctLiteral('User:firstName');
50
+ ///
51
+ /// See: LiteralFieldBase
52
+ ///
53
+ /// See: LiteralBase
5
54
  class DistinctLiteral extends LiteralFieldBase {
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. `'CountLiteral {}'`.
61
+ ///
62
+ /// Note:
63
+ /// Ultimately, for most connections, this will end up calling
64
+ /// <see>QueryGenerator._distinctLiteralToString</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.
6
77
  toString(connection, options) {
7
78
  if (!connection)
8
79
  return `${this.constructor.name} {}`;
@@ -2,7 +2,61 @@
2
2
 
3
3
  const LiteralFieldBase = require('./literal-field-base');
4
4
 
5
+ /// Define a "field" 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 a "field" in the underlying database.
11
+ /// It could for example be used in a projection, an `ORDER`,
12
+ /// or a `GROUP BY` clause.
13
+ ///
14
+ /// There are two primary ways to access literals in Mythix ORM. The
15
+ /// first is to simply import them. The second way literals can be
16
+ /// accessed is via the connection class itself. All Mythix ORM connection
17
+ /// classes export all literals on the `static Literals` attribute of
18
+ /// the class. So for example, you could access literals like `SQLiteConnection.Literals.FieldLiteral`.
19
+ ///
20
+ /// All built-in Mythix ORM literals--except `Literal` and `LiteralBase`--accept a field
21
+ /// as their first argument. This field can be a fully qualified field name, an actual
22
+ /// <see>Field</see> instance, or another literal. The second argument to all literal constructors
23
+ /// is an `options` object, that generally contains connection-specific (and operation-specific) options...
24
+ /// however, there are common options that can be supplied, such as `as: string;` which allows you to
25
+ /// define an alias for the defined field, and `noProjectionAliases: boolean;`, which allows you to disable
26
+ /// the column alias entirely.
27
+ ///
28
+ /// Example:
29
+ /// const { Literals } = require('mythix-orm');
30
+ /// const { SQLiteConnection } = require('mythix-orm-sqlite');
31
+ /// let literal1 = new Literals.FieldLiteral('User:age');
32
+ /// let literal2 = new SQLiteConnection.Literals.FieldLiteral('User:age');
33
+ ///
34
+ /// See: LiteralFieldBase
35
+ ///
36
+ /// See: LiteralBase
5
37
  class FieldLiteral extends LiteralFieldBase {
38
+ /// Convert this literal to a string to be used in a database query.
39
+ ///
40
+ /// This method proxies the conversion of this literal to the connection
41
+ /// by calling <see>Connection.literalToString</see>. If no connection
42
+ /// is provided when this is called, then the literal will be converted
43
+ /// to a string representing it for debugging, i.e. `'FieldLiteral {}'`.
44
+ ///
45
+ /// Note:
46
+ /// Ultimately, for most connections, this will end up calling
47
+ /// <see>QueryGenerator._fieldLiteralToString</see>.
48
+ ///
49
+ /// Arguments:
50
+ /// connection?: <see>Connection</see>
51
+ /// The connection to use to stringify this literal. If none is provided,
52
+ /// then a string representing this object will be returned instead.
53
+ /// options?: object
54
+ /// A connection and operation specific set of options that can be provided.
55
+ /// This might for example be `{ as: 'name' }` to provided a field alias, or
56
+ /// `{ isProjection: true }` to define that this is being stringified for use
57
+ /// as a field in the query projection. Normally the end-user won't care about
58
+ /// any literal options, except `as`, which is commonly used to give your literal
59
+ /// an alias.
6
60
  toString(connection, options) {
7
61
  if (!connection)
8
62
  return `${this.constructor.name} {}`;
@@ -9,6 +9,7 @@ declare class LiteralBase {
9
9
  public static isLiteralClass(value: any): boolean;
10
10
  public static isLiteral(value: any): boolean;
11
11
  public static isLiteralType(value: any): boolean;
12
+ public static isAggregate(): boolean;
12
13
 
13
14
  public constructor(literal: any, options?: GenericObject);
14
15
  public fullyQualifiedNameToDefinition(fullyQualifiedName: LiteralBase | string | Field): LiteralBase | FullyQualifiedFieldDefinition;