-
Notifications
You must be signed in to change notification settings - Fork 0
ConnectionBase
class ConnectionBase extends EventEmitter 📜
ConnectionBase is the base class that all connection classes should inherit from. It provides common functionality to all connections, and converts literals and types into their native database representation.
A "connection" in Mythix ORM is essentially the "application" for the ORM. It stores all models used by the connection, stores and defines the query generator (if any), converts literals and types, and also provides the query engine.
Multiple connections can be used at the same time in Mythix ORM. It is also planned that someday Mythix ORM (or the community) will provide a multiplex connection, to mix multiple connections into a single connection for the entire application.
For now you can use multiple connections at once. Just know that you should read and fully understand Connection Binding if you plan on using more than one connection for your application.
ConnectionBase is also an Event Emitter,
so you can bind events to a connection instance with .on, and unbind
with .off. Events are connection specific, but common events that
can be bound to are:
-
connect- Commonly fired when a connection is successfully established -
acquire- Commonly fired when a connection is acquired from a connection pool -
error- Commonly fired when a database level error occurs -
disconnect- Commonly fired when a connection is disconnected
This is just an example of common connection driver events. Please see documentation for your specific database connection for the proper events.
static property ConnectionBase::_isMythixConnection: boolean 📜
Helper for type checking methods. Should always be true.
static property ConnectionBase::DefaultQueryGenerator = QueryGeneratorBase 📜
property ConnectionBase::dialect: string = "none" 📜
The dialect of the database, i.e. 'sqlite', or 'postgresql'.
static property ConnectionBase::Literals: Literals = Literals 📜
All default Mythix ORM literal classes, provided for convenient access.
method ConnectionBase::_averageLiteralToString(literal: AverageLiteral, options?: object): string 📜
Convert the provided AverageLiteral to a string for the underlying database driver. The conversion will be database specific. The database driver connection is free to override this method.
Notes:
- This method is a proxy method for QueryGenerator._averageLiteralToString. If the connection has no instance of a
queryGeneratoravailable to it, then this method will simply returnundefined.- Generally speaking, Literal "options" are literal (and connection) specific. They often aren't needed or used directly by the user, but instead are used by the underlying connection itself, to define context specific options. For example, the underlying connection might have an option to tell a literal that it is the "DEFAULT" value of a field, instead of just a raw value to inject in the generated query stream, and this might change the output of the literal when converted to a string.
Arguments:
literal: AverageLiteralThe literal to convert to a string for the database.
options?:objectOptional options to pass to the QueryGenerator._averageLiteralToString method.
Return value:
stringThe provided AverageLiteral converted to a string for the underlying database driver.
Convert a "BIGINT" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be BIGINT,
however, it may be different based on what database you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
Convert a "BLOB" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be BLOB,
however, it may be different based on what database you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
Convert a "BOOLEAN" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be BOOLEAN,
however, it may be different based on what database you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
Convert a "CHAR" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be CHAR,
however, it may be different based on what database you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
method ConnectionBase::_countLiteralToString(literal: CountLiteral, options?: object): string 📜
Convert the provided CountLiteral to a string for the underlying database driver. The conversion will be database specific. The database driver connection is free to override this method.
Notes:
- This method is a proxy method for QueryGenerator._countLiteralToString. If the connection has no instance of a
queryGeneratoravailable to it, then this method will simply returnundefined.- Generally speaking, Literal "options" are literal (and connection) specific. They often aren't needed or used directly by the user, but instead are used by the underlying connection itself, to define context specific options. For example, the underlying connection might have an option to tell a literal that it is the "DEFAULT" value of a field, instead of just a raw value to inject in the generated query stream, and this might change the output of the literal when converted to a string.
Arguments:
literal: CountLiteralThe literal to convert to a string for the database.
options?:objectOptional options to pass to the QueryGenerator._countLiteralToString method.
Return value:
stringThe provided CountLiteral converted to a string for the underlying database driver.
Convert a "DATETIME" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be BIGINT,
however, it may be different based on what database you are using.
Notes:
- Mythix ORM always stores DATE and DATETIME types as a timestamp (in milliseconds from the UNIX Epoch) whenever it is able to. This is why the default type for most connection drivers is
BIGINT. Another common type for this conversion isTIMESTAMP.Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
Convert a "DATE" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be BIGINT,
however, it may be different based on what database you are using.
Notes:
- Mythix ORM always stores DATE and DATETIME types as a timestamp (in milliseconds from the UNIX Epoch) whenever it is able to. This is why the default type for most connection drivers is
BIGINT. Another common type for this conversion isTIMESTAMP.Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
method ConnectionBase::_distinctLiteralToString(literal: DistinctLiteral, options?: object): string 📜
Convert the provided DistinctLiteral to a string for the underlying database driver. The conversion will be database specific. The database driver connection is free to override this method.
Notes:
- This method is a proxy method for QueryGenerator._distinctLiteralToString. If the connection has no instance of a
queryGeneratoravailable to it, then this method will simply returnundefined.- Generally speaking, Literal "options" are literal (and connection) specific. They often aren't needed or used directly by the user, but instead are used by the underlying connection itself, to define context specific options. For example, the underlying connection might have an option to tell a literal that it is the "DEFAULT" value of a field, instead of just a raw value to inject in the generated query stream, and this might change the output of the literal when converted to a string.
Arguments:
literal: DistinctLiteralThe literal to convert to a string for the database.
options?:objectOptional options to pass to the QueryGenerator._distinctLiteralToString method.
Return value:
stringThe provided DistinctLiteral converted to a string for the underlying database driver.
method ConnectionBase::_escape(value: any): string 📜
The low-level DB interface for escaping a
value. By default this function uses the
sqlstring
module to escape values. However, the escape
method for whatever database the connection is
using should be used instead of this. This is
a "default implementation" that is meant as a
fallback when a connection doesn't provide its
own, but each connection should provide its own
when it is able.
Notes:
- This method escapes "values" that are given in the underlying query language of the database. To escape identifiers, use the ConnectionBase._escapeID instead.
Arguments:
value:anyThe value to escape. This could be a number, a boolean, a string, or anything else that can be provided to your specific database.
Return value:
stringThe value provided, escaped for the specific underlying database driver.
method ConnectionBase::_escapeID(value: string): string 📜
Low-level database method for escaping an identifier. Each database driver should provide its own version of this method. This is the "default" method Mythix ORM provides as a "fallback" to database drivers that don't supply their own.
It works by first stripping all quotes (single ', double ", and backtick `)
from the provided value. After this, it will split on the period (dot) character
., and then will map each resulting part through sqlstring
escapeId method, finally re-joining the parts with a period . character.
The extra processing is to allow for already escaped identifiers to not be double-escaped.
Arguments:
value:stringThe identifier to escape.
Return value:
stringThe provided identifier, escaped for the underlying database.
method ConnectionBase::_fieldLiteralToString(literal: FieldLiteral, options?: object): string 📜
Convert the provided FieldLiteral to a string for the underlying database driver. The conversion will be database specific. The database driver connection is free to override this method.
Notes:
- This method is a proxy method for QueryGenerator._fieldLiteralToString. If the connection has no instance of a
queryGeneratoravailable to it, then this method will simply returnundefined.- Generally speaking, Literal "options" are literal (and connection) specific. They often aren't needed or used directly by the user, but instead are used by the underlying connection itself, to define context specific options. For example, the underlying connection might have an option to tell a literal that it is the "DEFAULT" value of a field, instead of just a raw value to inject in the generated query stream, and this might change the output of the literal when converted to a string.
Arguments:
literal: FieldLiteralThe literal to convert to a string for the database.
options?:objectOptional options to pass to the QueryGenerator._fieldLiteralToString method.
Return value:
stringThe provided FieldLiteral converted to a string for the underlying database driver.
A convenience method to get from "model cache".
Model Cache is a simple system to cache random results from model methods. This is used for things that should never change, for example the models fields, the models name, the table name for the model, etc... Some of these values are initially computed, and then cached using this system so operations later on return much quicker.
Notes:
- The underlying cache system uses the
Maptype, so any value can be used as a cache key.- This cache is never cleared or marked as stale, so if using dynamic cache keys, make sure that you properly remove them later to prevent memory leaks.
Arguments:
Model: class ModelThe model class we a caching for.
key:anyThe key to use for our cache.
defaultValue?:anyThe default value to return if no cache entry was found.
Return value:
anyAny value found in the cache.
Convert a "INTEGER" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be INTEGER,
however, it may be different based on what database you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
method ConnectionBase::_maxLiteralToString(literal: MaxLiteral, options?: object): string 📜
Convert the provided MaxLiteral to a string for the underlying database driver. The conversion will be database specific. The database driver connection is free to override this method.
Notes:
- This method is a proxy method for QueryGenerator._maxLiteralToString. If the connection has no instance of a
queryGeneratoravailable to it, then this method will simply returnundefined.- Generally speaking, Literal "options" are literal (and connection) specific. They often aren't needed or used directly by the user, but instead are used by the underlying connection itself, to define context specific options. For example, the underlying connection might have an option to tell a literal that it is the "DEFAULT" value of a field, instead of just a raw value to inject in the generated query stream, and this might change the output of the literal when converted to a string.
Arguments:
literal: MaxLiteralThe literal to convert to a string for the database.
options?:objectOptional options to pass to the QueryGenerator._maxLiteralToString method.
Return value:
stringThe provided MaxLiteral converted to a string for the underlying database driver.
method ConnectionBase::_minLiteralToString(literal: MinLiteral, options?: object): string 📜
Convert the provided MinLiteral to a string for the underlying database driver. The conversion will be database specific. The database driver connection is free to override this method.
Notes:
- This method is a proxy method for QueryGenerator._minLiteralToString. If the connection has no instance of a
queryGeneratoravailable to it, then this method will simply returnundefined.- Generally speaking, Literal "options" are literal (and connection) specific. They often aren't needed or used directly by the user, but instead are used by the underlying connection itself, to define context specific options. For example, the underlying connection might have an option to tell a literal that it is the "DEFAULT" value of a field, instead of just a raw value to inject in the generated query stream, and this might change the output of the literal when converted to a string.
Arguments:
literal: MinLiteralThe literal to convert to a string for the database.
options?:objectOptional options to pass to the QueryGenerator._minLiteralToString method.
Return value:
stringThe provided MinLiteral converted to a string for the underlying database driver.
Convert a "NUMERIC" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be NUMERIC, DECIMAL,
or NUMBER, however, it may be different based on what database
you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
Convert a "REAL" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be FLOAT,
however, it may be different based on what database you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
A convenience method to set to the "model cache".
Model Cache is a simple system to cache random results from model methods. This is used for things that should never change, for example the models fields, the models name, the table name for the model, etc... Some of these values are initially computed, and then cached using this system so operations later on return much quicker.
Notes:
- The underlying cache system uses the
Maptype, so any value can be used as a cache key.- This cache is never cleared or marked as stale, so if using dynamic cache keys, make sure that you properly remove them later to prevent memory leaks.
Arguments:
Model: class ModelThe model class we a caching for.
key:anyThe key to use for our cache.
value:anyThe value to cache.
Return value:
anyThe
valueprovided.
Convert a "STRING" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be VARCHAR,
however, it may be different based on what database you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
method ConnectionBase::_sumLiteralToString(literal: SumLiteral, options?: object): string 📜
Convert the provided SumLiteral to a string for the underlying database driver. The conversion will be database specific. The database driver connection is free to override this method.
Notes:
- This method is a proxy method for QueryGenerator._sumLiteralToString. If the connection has no instance of a
queryGeneratoravailable to it, then this method will simply returnundefined.- Generally speaking, Literal "options" are literal (and connection) specific. They often aren't needed or used directly by the user, but instead are used by the underlying connection itself, to define context specific options. For example, the underlying connection might have an option to tell a literal that it is the "DEFAULT" value of a field, instead of just a raw value to inject in the generated query stream, and this might change the output of the literal when converted to a string.
Arguments:
literal: SumLiteralThe literal to convert to a string for the database.
options?:objectOptional options to pass to the QueryGenerator._sumLiteralToString method.
Return value:
stringThe provided SumLiteral converted to a string for the underlying database driver.
Convert a "TEXT" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be TEXT,
however, it may be different based on what database you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
Convert a "UUIDV1" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be VARCHAR,
however, it may be different based on what database you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
Convert a "UUIDV3" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be VARCHAR,
however, it may be different based on what database you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
Convert a "UUIDV4" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be VARCHAR,
however, it may be different based on what database you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
Convert a "UUIDV5" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be VARCHAR,
however, it may be different based on what database you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
Convert a "XID" field type to a type acceptable by the underlying database driver.
For most SQL connections this would be VARCHAR,
however, it may be different based on what database you are using.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
Return value:
stringThe field type needed by the underlying database driver.
Add the column/field specified to the database.
The table/bucket to add the field to is fetched from the
Model property on the supplied field.
Arguments:
Field: FieldThe new field to add to the underlying database.
options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
Promise<void>
method ConnectionBase::addIndex(Model: class Model, indexFields: Array<string>, options?: object): Promise<void> 📜
Create an index (or combo index) in the database.
This will create a new index for the field(s) specified.
The indexFields argument must be an array of field names
as strings. It can contain more than one field. If it does
contain more than one field, then a combo index will be created
for all specified fields (if the database you are using supports
combined indexes).
All the provided field names must exist on the provided Model.
If they don't, then an exception will be thrown. The field names
can be fully qualified, but they don't need to be. If they are
fully qualified, then they must all still be owned by the provided
Model. You can not for example use a fully qualified field name
from another model.
Combo indexes are created by combining two or more fields to create
the index. For example, you could create a combo index for Users
like [ 'firstName', 'lastName', 'email' ] if it is common for your
application to query on all three of these fields at once.
If you just want to index a single column/field, simply provide only
one field name, i.e. [ 'firstName' ].
Arguments:
Model: class ModelThe model that owns the specified fields.
indexFields:Array<string>The field names to use to create the index. One field name is valid if you only wish to index a single field. These are used to generate the index name, along with which fields to index.
options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
Promise<void>
method ConnectionBase::aggregate(query: QueryEngine, literal: LiteralBase, options?: object): Promise<number> 📜
Aggregate data across rows.
Though this method can be called directly, it is generally called from one of ConnectionBase.average, ConnectionBase.sum, ConnectionBase.count, ConnectionBase.min, or ConnectionBase.max, or one of the other aggregate methods provided by the connection.
It takes a query which is used to generate a query for the underlying
database, and sets the query PROJECTION to the aggregate literal provided.
For example, a sum method call would call this method with a SumLiteral,
which would change the query projection to the expanded result of the
SumLiteral, returning the "sum" of all column values targeted by the literal field.
The results will then be collected, and always returned as a number primitive
to the caller.
Arguments:
query: QueryEngineThe query used to select which rows to aggregate across.
literal: LiteralBaseA literal, used as the aggregate function. For example, if a CountLiteral is provided, then the count of all rows matching the provided query will be the result.
options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
Promise<number>The result of the aggregate operation, as a number.
method ConnectionBase::alterColumn(Field: Field, NewField: Field | object, options?: object): Promise<void> 📜
Alter the specified column/field in the database.
This will take the two fields, Field and NewField,
and will compare them. It will generate multiple alter
table statements internally, and will alter the column/field
based on the differences it detects between the two fields.
If NewField is provided as a raw object, then it will be
converted into a Field.
This method will check for the following differences between the two fields, in this order:
allowNulltypedefaultValueprimaryKeyunique-
index(will calculate index differences, and do the minimum work required) columnName
Arguments:
Field: FieldThe current column/field (as it is in the database) that we are changing.
NewField: Field |objectThe new field properties to compare. Only the provided properties will be compared. For example, if you only supply a
defaultValueproperty, then only that will be altered (if it differs fromField).options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
Promise<void>
Alter a table/bucket based on the provided attributes for the model.
For SQL based drivers this might run a statement like the following
ALTER TABLE "users" RENAME TO "old_users";
Please refer to the documentation of the database driver you are using for more information.
Arguments:
Model: class ModelThe model to alter. This is used to alter the underlying table/bucket in the database.
newAttributes:objectThe attributes to alter. Please refer to the documentation of the database driver you are using for more information.
Return value:
Promise<void>
method ConnectionBase::average(query: QueryEngine, field: Field | string, options?: object): Promise<number> 📜
Get the average for a single column, spanning all matching rows.
This will return the average of all values in a column,
across all matching rows, as a number primitive.
Arguments:
query: QueryEngineThe query used to select which rows are used to calculate the average.
field: Field |stringA field instance, or a fully qualified field name, used as the target column in the underlying database to calculate an average across all matching values.
options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
Promise<number>The average of all matching columns.
method ConnectionBase::buildConnectionContext(connection?: Connection = this): Map<any, any> 📜
This builds a "connection context" to provide to the AsyncLocalStorage context of a Connection.createContext call.
By default, this will set a connection property on the context,
which will be the value of this connection instance. It also sets
a connection property on the sub-contexts for each model. This
is because models might have different connections, and so need
a context per-model to work properly.
"How could a model have different connections?" you ask? Well, it probably won't. But being as this is an AsyncLocalStorage context, it provides the connection to every model inside the context. Your application might be using other models that aren't part of this connection, and we wouldn't want those to get the wrong connection for those models.
Arguments:
connection?: Connection (Default:this)The connection to create the context for. This can be provided, and is used in place of
thisinstance, for example, in the case of transactions. Transactions generally are the "same" connection, but not the same instance.Return value:
Map<any, any>The new context that will be used for Connection.createContext.
method ConnectionBase::bulkModelOperation(Model: class Model, models: Array<Model>, options?: object, beforeCallback?: (Model: typeof Model, batchModelInstances: Array, options: object, queryGenerator: QueryGenerator) => Promise, callback: (Model: typeof Model, preparedModels: PreparedModels, options: object, queryGenerator: QueryGenerator) => Promise, afterCallback?: (Model: typeof Model, models: Array, options: object, queryGenerator: QueryGenerator) => Promise, afterOperationCallback?: (Model: typeof Model, dirtyModels: Set, options: object, queryGenerator: QueryGenerator) => Promise): Array<Model> 📜
This is a low-level "helper" method that is used by all
"bulk operations", such as insert, upsert, update,
or destroyModels. It prepares all provided models for operation,
splits out sub-models provided, skips already persisted models,
and also calls the model hooks onBeforeSave, onAfterSave, etc...
This method will also always operate in batches, as defined by the
batchSize option (default is 500 if not provided).
Lastly, when it is all done running the "batch operation" on all models, it will update any foreign keys on each model, and if any model has again been marked dirty from this update it will finally persist those updated models.
When it is fully complete, this method will return all "primary" models supplied
to the method (i.e. if saving User models, then all supplied users will be returned
and if any sub models were involved those won't be returned). The "primary model" is
the model whose model class was specified as the Model argument on invocation of this
method, and should match the type of the input models.
Arguments:
Model: class ModelThe model class for the input models being provided.
models:Array<Model>The models to bulk operate on. All of them must be instances of the class provided as the
Modelargument.options?:objectOptions to supply to the method. Refer to the following table for a list of possible options.
Option Type Default Value Description batchSizenumber500The number of models for each batch isInsertOperationbooleanfalsetrueif this is an insert operation. If this is an insert operation, then dirty models will be collected post-insert, and re-saved if any are re-marked dirty after foreign key updates.isDeleteOperationbooleanfalsetrueif this is a delete operation. If this is a delete operation, then model preparation and splitting is skipped, and the models are processed directly.beforeCallback?: (Model: typeof Model, batchModelInstances: Array, options: object, queryGenerator: QueryGenerator) => PromiseCallback that is called for each batch of models, before the current operation (i.e. insert) operates on them. It is generally in this callback that
onBefore*model hooks are called.callback: (Model: typeof Model, preparedModels: PreparedModels, options: object, queryGenerator: QueryGenerator) => PromiseCallback to call to process each batch of models. The models are in "prepared model" format, meaning they are supplied as an object with
models,dirtyFields, anddirtyModelsproperties.afterCallback?: (Model: typeof Model, models: Array, options: object, queryGenerator: QueryGenerator) => PromiseCallback that is called for each entire model set (not in batches). For example, if you bulk insert 1000 users, and your
batchSizeis100, then this will be called once, with all 1000 processed users, not 10 times with 100 users each. It is generally in this callback thatonAfter*model hooks are called.afterOperationCallback?: (Model: typeof Model, dirtyModels: Set, options: object, queryGenerator: QueryGenerator) => PromiseCallback that is called after the entire operation completes successfully. This will only be called if
dirtyModelsis not empty. This method generally will re-save any models that got dirty during the operation... for example, when foreign keys have been updated on the models being processed. Models won't be added to thedirtyModelsset if they are marked dirty inonAfter*model hooks, but only if the foreign key update process marked the model as dirty.Return value:
Array<Model>Return all input models, converted to model instances, and updated. How they are updated depends on the operation being performed.
method ConnectionBase::constructor(options: object): Connection 📜
Create a connection.
The options argument is generally connection
specific. However, there are a few generic options,
which you will find listed in the table below:
| Option | Type | Default Value | Description |
|---|---|---|---|
bindModels |
boolean |
true |
If true, then bind the provided models to this connection. Models are bound to a connection by setting a static _mythixBoundConnection property on each model class to this connection instance. |
forceConnectionBinding |
boolean |
false |
Normally attempting to bind a connection to a model more than once will result in an exception being thrown. However, if you set this property to true, then Mythix ORM will rebind the connection without complaint, even if a connection is already bound to your models. Make sure you know what you are doing if you use this option. |
models |
Array or Object of Models
|
undefined |
Models to provide to this connection. This can be either an array of Models, or an Object where each value is a Model |
QueryEngine |
class QueryEngine | QueryEngine | The QueryEngine class to use for this connection and all this connection's models. You can provide your own class if you wish to add onto the query interface. |
queryGenerator |
QueryGenerator | Connection specific | The query generator for this connection. If a QueryGenerator instance is provided (the correct one for the connection you are using), then this provided query generator will be used. If one isn't provided, then the connection will create its own query generator that is specific to the connection type. |
Arguments:
options:objectConnection specific options to supply to your connection. These will commonly include things like a hostname to connect to, a user name and password, and any connection specific parameters.
Return value: Connection
Convert a given "time" type object to the value needed by the underlying database.
By default this method will take a
Luxon DateTime instance, or a Date instance,
and convert it to the value needed by the
underlying field in the database. This is
generally a BIGINT, or TIMESTAMP value,
as Mythix ORM will always try to store dates
and times as millisecond timestamps
(number of milliseconds since the UNIX Epoch).
If a number, bigint, or a string type is
provided, then Mythix ORM will use Luxon to try
and parse the provided value. If the value is parsed
correctly, it will then be converted to the proper
value as needed by the underlying field in the database.
Arguments:
value:anyThe incoming date/time type to convert to the proper database value for the underlying field.
type: TypeThe field type that this conversion is for. This will generally be a
DATEorDATETIMEtype.Return value:
anyReturn the value needed by the underlying database field. Generally this will be a
biginttype that is returned, but may be something different depending on the field and the database itself.
method ConnectionBase::count(query: QueryEngine, field: Field | string, options?: object): Promise<number> 📜
Get the number of rows matching the query.
This will return the number of rows matching
the provided query, as a number primitive.
Notes:
- In most databases, if the
fieldargument is not specified, then the count operation will be across all table columns (COUNT(*)).Arguments:
query: QueryEngineThe query used to select which rows to count.
field: Field |stringA field instance, or a fully qualified field name, used as the target column in the underlying database to count the rows. If not specified, then most database drivers will count across all columns (i.e.
COUNT(*)).options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
Promise<number>The count (number) of all rows matching the provided query.
method ConnectionBase::createContext(callback: async Function, connection?: Connection = this, thisArg?: any = this): any 📜
Create a connection context to serve all code running inside it this connection.
This uses AsyncLocalStorage to create a context that is passed through the entire call stack of the callback. In this way, a connection can be provided to every model and every operation within the call.
Arguments:
callback:async FunctionThe method to provide the context to. Every call inside this call stack will be provided the connection.
connection?: Connection (Default:this)The connection to provide. Generally this will just be
thisconnection instance, however, it can be specified, and is for example inside transactions.thisArg?:any(Default:this)The
thisvalue to provide to the givencallback.Return value:
anyThe return value of the given
callback.
method ConnectionBase::createQueryGenerator(options) 📜
This method will create the default query generator.
Arguments:
options
Create a table/bucket using the provided model class.
The provided options are database specific,
but might contain things like ifExists, for
example.
Arguments:
Model: class ModelThe model class used to create the table/bucket. The Model.getTableName method will be called to get the table/bucket name to create. Then the
static fieldsproperty on the model class is used to create the columns/fields for the table/bucket. Only "concrete" fields are created in the underlying database. Any "virtual" or "relational" fields will be skipped.options?:objectDatabase specific operations for creating the table/bucket. Please refer to the documentation of the driver you are using for further information.
Return value:
anyA connection specific return value for the operation.
Create all specified tables/buckets in the database.
This uses the provided Models classes to
create the tables/buckets specified.
The options argument is database specific,
but might contain options such as ifNotExists,
for example.
The model classes provided are first sorted in "creation order" using the Utils.sortModelNamesByCreationOrder method, and then the tables/buckets are created in the that order. This is to ensure that any foreign key constraints in play will play nicely with the operation and not throw errors.
This method simply calls ConnectionBase.createTable for every model provided--after sorting the models based on their foreign keys.
Arguments:
Models: Array<class Model>The model classes used to create the tables/buckets. The Model.getTableName method will be called for each model to get the table/bucket name to create. Then the
static fieldsproperty on each model class is used to create the columns/fields for the table/bucket. Only "concrete" fields are created in the underlying database. Any "virtual" or "relational" fields will be skipped.options?:objectDatabase specific operations for dropping the table/bucket. Please refer to the documentation of the driver you are using for further information.
Return value:
anyA database specific return value for the create tables operation.
method ConnectionBase::destroy(queryOrModel: class Model | QueryEngine, modelsOrOptions: Array<Model> | Model | object, options?: object | undefined): Promise<Array<Models> | Model | number> 📜
Destroy multiple models by query, or by the provided models themselves. If models are provided, then each model must have a valid primary key field, or an exception will be thrown.
If models are provided as the second argument, then it is required that the first argument be a Model class. In this case, this method simply calls ConnectionBase.destroyModels to complete the operation.
If the first argument is a QueryEngine instance, then rows will be deleted from the database using the provided query. In this case, it is expected that the second argument will be the "options" for this operation instead of an array of models.
Arguments:
queryOrModel: class Model | QueryEngineA QueryEngine instance to specify which models to delete via a query, or a Model class if models are being provided to be deleted.
modelsOrOptions:Array<Model>|Model|objectIf a QueryEngine instance is provided as the first argument then this is expected to be the "options" for the operation. If however a Model class is provided as the first argument, then this should be a Model instance, or an array of Model instances.
options?:object|undefinedMost of these options are database/driver specific. The
batchSizeoption is ignored if a QueryEngine instance is provided as the first argument to the call. If a Model class is provided as the first argument to the call, then thisoptionsobject will be at argument index1instead (the second argument,modelsOrOptions). The following options are common across all database drivers (skipHooksis not supported in this context):
Option Type Default Value Description batchSizenumber500The size of each batch during a multi-model destroy operation. Return value:
Promise<Array<Models>|Model|number>Return the models deleted (if models were provided), or the number of rows deleted (if a query was provided).
method ConnectionBase::destroyModels(Model: class Model, models: Array<Model | object> | object | Model, options?: object): Promise<Array<Model> | Model> 📜
Destroy the provided models.
This method will bulk-iterate the specified models and will destroy each one. A primary key field is required for every model, or this method will throw an exception.
The skipHooks option (see ConnectionBase.runSaveHooks) won't
do anything here, because Mythix ORM doesn't have any on*Destroy hooks.
Mythix ORM doesn't have any destroy hooks for performance reasons.
However, the batchSize option is still useful for this method.
Notes:
- WARNING!!!: If you supply
nullorundefinedas themodelsargument then this method will silently return. If you also supply the option{ truncate: true }then the entire table will be truncated. This option is an "opt-in", to make sure you don't truncate an entire table on accident.- Some databases (i.e. SQLite) don't support a
TRUNCATEstatement, and so will deliberately call this method withnullfor themodelsargument fortruncateoperations. When doing so they will also deliberately supply the{ truncate: true }option.Arguments:
Model: class ModelThe model class used for the operation. This defines what table/bucket to delete from.
models:Array<Model | object>|object| ModelThe model(s) to delete from the database. If raw objects are provided, then they must contain a
primaryKeyfor each model. If any of the models provided don't contain aprimaryKeyfield, then an exception will be thrown. If you have a table/bucket that has no primary key column, then you will need to destroy rows manually yourself using a manual query with ConnectionBase.query, or by using the ConnectionBase.destroy method.options?:objectMost of these options are database/driver specific. However, the following options are common across all database drivers (
skipHooksis not supported in this context):
Option Type Default Value Description batchSizenumber500The size of each batch during a multi-model destroy operation. Return value:
Promise<Array<Model>|Model>If you provide an array of models, then an array of models will be returned. If you provide only a single model, then a single model will be returned.
method ConnectionBase::dirtyFieldHelper(context: DefaultValueContext): any 📜
A connection specific "helper" to force "dirty" fields for all models.
This method, when present on a connection, will assist in
defining which fields are "dirty" for a model. It is used,
for example, by Types.DATETIME.Defaults.NOW.UPDATED default values.
In the case presented, DATETIME fields that should always be updated
are always marked dirty by this method, even though they might
not actually be "dirty" client-side.
If this method returns any value other than undefined, then
the field being operated upon will be marked "dirty" with the value
returned, even if the field would otherwise not be marked "dirty".
Arguments:
context:DefaultValueContextSee Field for documentation on the
DefaultValueContextinterface.Return value:
anyIf any value is returned that is not
undefined, then the field will be marked "dirty" with the value returned. Returnundefinedif you do not wish to mark a specific field as "dirty". Note however that the field might actually still be dirty because the user modified the field, in which case this method will not even be called for that field. In short, this method is only called for fields that are not already marked as dirty, and will force a field to be marked dirty if any value other thanundefinedis returned.
Drop the specified column/field from the database.
The table/bucket to drop the field from is known
by the Model property (model class) on the field
itself.
The provided options are specific to the database
you are using.
Please refer to the documentation of the database driver
you are using for more information.
Arguments:
Field: FieldThe column/field to drop from the database.
options?:objectDatabase specific option for the operation. Please refer to the documentation of the database driver you are using for more information.
Return value:
anyA database specific return value for the operation completed.
method ConnectionBase::dropIndex(Model: class Model, indexFields: Array<string>, options?: object): Promise<void> 📜
Drop the index from the database based on the specified fields.
This is the exact inverse of ConnectionBase.addIndex, and it functions nearly identically, except that it will drop the specified index instead of creating it.
Arguments:
Model: class ModelThe model that owns the specified fields.
indexFields:Array<string>The field names to used to drop the index. These are used to generate the index name, which will then be dropped.
options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
Promise<void>
Drop a table/bucket from the database.
This uses the provided Model class to
find the table/bucket name to drop, and then
will drop it from the underlying database.
The options argument is database specific,
but might contain options such as ifExists,
or cascade, for example.
Arguments:
Model: class ModelThe model to drop from the database. The method Model.getTableName is called on the model class to figure out what table/bucket to drop from the database.
options?:objectDatabase specific operations for dropping the table/bucket. Please refer to the documentation of the driver you are using for further information.
Return value:
anyA database specific return value for the drop table operation.
Drop all specified tables/buckets from the database.
This uses the provided Models classes to
find the table/bucket names to drop, and then
will drop all of them from the underlying database.
The options argument is database specific,
but might contain options such as ifExists,
or cascade, for example.
The model classes provided are first sorted in "creation order" using the Utils.sortModelNamesByCreationOrder method, and then the tables/buckets are dropped in the reverse order. This is to ensure that any foreign key constraints in play will play nicely with the operation and not throw errors.
This method simply calls ConnectionBase.dropTable for every model provided--after sorting the models based on their foreign keys.
Arguments:
Models: Array<class Model>All the models to drop from the database. The method Model.getTableName is called on each model class to figure out what table/bucket to drop from the database.
options?:objectDatabase specific operations for dropping the table/bucket. Please refer to the documentation of the driver you are using for further information.
Return value:
anyA database specific return value for the drop tables operation.
method ConnectionBase::ensureAllModelsAreInstances(Model: class Model, models: object | Model | Array<Model | object>, options: object): Array<Model> 📜
This method will ensure all provided "models" are instances of the provided model class.
This method is used by the insert, upsert, and update
methods of the connection to ensure every model
provided by the user is an actual model instance.
For example, it is perfectly valid to create a model
like await Model.create({ ...attributes }). As you
can see, the provided "model" is actually just a raw
object. Nearly any call in Mythix ORM will accept a
raw object in-place of a model instance, and this
method is used to ensure all provided "models" are
actually model instances.
Arguments:
Model: class ModelThe model class to use for instantiating models.
models:object| Model |Array<Model | object>The models to convert to model instances (if needed).
options:objectOptions for the operation. This options object is used to pass the
startIndexandendIndex(orbatchSize) as provided by the user when callinginsert,upsert, orupdate.Return value:
Array<Model>Return all provided models, converted to model instances. Any provided model that is already a model instance will not be modified, and instead will simply be returned.
Unlike ConnectionBase._escape --which is a low-level interface for the database-- this method will escape specific values in specific ways needed by Mythix ORM. Said another way, whereas ConnectionBase._escape is a "low level database method", this is a "high level Mythix ORM" method.
If this method is provided a literal, then it will convert
the literal into a string, and return the resulting string.
This is the purpose of the options argument. The options
argument will be passed to the literal's toString method.
For any non-literal value, it is first passed through the
field's serialize method, for example value = field.type.serialize(value, thisConnection);.
This generally won't modify the incoming value, but it might,
for example, with DATE, or DATETIME types, that are modified
to match an acceptable format for the underlying database.
If this method is provided a boolean, then it will return
an upper-cased version of the boolean as a string, i.e. true will be returned
as 'TRUE', and false will be returned as 'FALSE'.
If this method is provided a BigInt, then it will convert the
bigint into a string representation of the number, i.e. 42n will
be returned as '42'.
If this method is provided an Array value, then the array
is processed by the connection-specific prepareArrayValuesForSQL
method. By default, this method will complete the following operations
on the provided array:
- It will flatten the provided array into a 1D array
- It will filter the array, such that it removes
undefined, and any value that isn't a LiteralBase, anull, astring, aboolean, anumber, or abigint - It will further filter out duplicate values from the array, such that the processed array only contains unique values
After the array is processed with the prepareArrayValuesForSQL method,
it will then be mapped such that each value is passed through this
escape method, and then all remaining values in the array will be
joined with a , character between each element. The idea here is that
if you are providing an array to the underlying database, it is usually
for an IN or NOT IN operator, so the result will generally be used for
one of these. Keep in mind however that each connection driver might escape
values (including arrays) differently.
All other provided values are simply handed off to ConnectionBase._escape.
Arguments:
field: FieldThe field this value is coming from.
value:anyThe value to escape.
options?:objectThe options to provide to a Literal's
toStringmethod. Thisoptionsobject is only ever used if the providedvalueis a Literal.Return value:
stringThe escaped value, as a string.
method ConnectionBase::escapeID(value: string, options?: object): string 📜
This method is very similar to ConnectionBase._escapeID, except that instead of being a "low level database method" that the database driver itself provides, this is the "Mythix ORM" implementation of escaping identifiers. The only difference from ConnectionBase._escapeID is that if the provided value is a Literal, it will be converted to a string and returned without being escaped. Literals are never modified, and are always provided to the underlying database exactly as they were defined.
Arguments:
value:stringThe identifier to escape. If this is a Literal instead of a string, then the Literal will be converted to a string and returned.
options?:objectThe options to pass to
Literal.toString. This options object is only used if the providedvalueis a Literal instance.Return value:
stringThe escaped identifier, or if
valueis a Literal, the Literal converted to a string.
method ConnectionBase::exists(query: QueryEngine, options?: object): boolean 📜
Check if any rows match the provided query.
Arguments:
query: QueryEngineThe query used to select rows, to check if said rows exist in the database.
options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
boolean
trueif one or more rows match the provided query, orfalseotherwise.
method ConnectionBase::finalizeQuery(crudOperation: 'create' | 'read' | 'update' | 'delete', query: QueryEngine, options?: object): QueryEngine 📜
Finalize a query before using it for database operations.
finalizeQuery is called on every query immediately
before it is used for a database operation. Its only purpose
is to potentially modify the query before the database operation
occurs. This can be extremely useful for things like "row level permissions",
or ensuring that a certain type of query always has certain conditions.
Because it is asynchronous by design, it is possible to finalize the query using other asynchronous operations; for example validating authentication tokens, or fetching user roles from the database.
It works by walking the provided query, and calling Model.static finalizeQuery on every model it encounters that is used in the query. It will also recursively call itself for every new query it encounters that is part of the query, for example sub-queries. In this way, you can take on extra conditions to any part of a query, throw a "Forbidden" exception if the user is disallowed from querying certain data, or whatever you want.
Notes:
- "With great power comes great responsibility." Use
finalizeQueryintelligently. It can cause a noticeable performance hit, and can really make things hard to debug and understand if you don't clearly document.'create'isn't actually currently supported, since no queries are ever used in anINSERToperation. It is reserved for future use.Arguments:
crudOperation:'create'|'read'|'update'|'delete'The Mythix ORM reports what "type" of operation is being executed using this argument. This is used so one can know if the operation that is about to be executed is a
read,update, ordeleteoperation.query: QueryEngineThe query to operate upon. This will be walked, calling Model.static finalizeQuery for each unique model encountered, and also recursively walking any sub-queries.
options?:objectRandom options for the operation. These are not used by this method, but instead are the
optionsprovided to the database operation when it was requested, and are also available for use for any user needs.Return value: QueryEngine
The query provided, possibly altered.
See also: static Model.finalizeQuery
method ConnectionBase::findModelField(finder: Function): Field | undefined 📜
Find a specific field across all registered models.
This method is similar to Array.find,
except that the arguments to this finder method are those provided by
Model.iterateFields. If this finder method
returns a truthy value for a given field, then that is the field that will be returned.
Notes:
- This will search for the field across all models registered to the connection. To find a specific field for a known model use Connection.getField instead.
Arguments:
finder:FunctionA function to assist in finding the specified field. The signature for this function must match that used by Model.iterateFields.
Return value:
Field|undefinedThe field found, if any.
method ConnectionBase::getContextValue(key: any, defaultValue?: any): any 📜
Get a value from the AsyncLocalStorage context.
AsyncLocalStorage is used primarily for two purposes: 1) to provide a connection to models, and 2) to pass a transaction connection down through the call stack. However, it can also be used for any "context" level values the user wishes to store.
Notes:
- An
AsyncLocalStoragecontext might not exist when this call is made, in which case this method will returnundefined, or thedefaultValueif any was provided.Arguments:
key:anyThe key for the value you wish to fetch. The underlying "context" provided by
AsyncLocalStorageis aMap, so the "key" can be any value.defaultValue?:anyThe default value to return if there is no current
AsyncLocalStoragecontext, or if the requested key is not found.Return value:
any
Translate the defaultValue as provided by each models field's
into a DEFAULT value for the underlying database.
For example, if you were to specify a defaultValue for one of your
models field's, such as defaultValue: Types.INTEGER.Defaults.AUTOINCREMENT,
then this method would return a database specific autoincrement default for
the column defined by your field. For date/time fields, this might be a database
specific NOW() default. For non-database specific "defaults", the default value
as defined by your defaultValue on your fields is simply returned.
Arguments:
type: TypeThe field's
typeinstance, as defined by the field itself.context:DefaultValueContextA
DefaultValueContextas is normally provided to alldefaultValuemethods defined on fields. See the documentation for thedefaultValueproperty of Field for more information.Return value:
anyYour defined field's
defaultValue, intercepted, and possibly translated to a proper value for the underlying database. It is common for many database drivers that only date/time and auto-increment default values are intercepted and translated. Most other "default values" are simply returned.
Get the default order for selecting rows from the database. The connection driver itself might specify a default order for each table, if one isn't specified by the user.
Notes:
- To specify a default order for each model, use the Model.static defaultScope method instead.
Arguments:
Model: class ModelThe model/table to fetch the default order for.
options:objectOperation specific options (i.e. options for a "select" call)
Return value:
Array<string>An array of fully qualified field names for this model should be returned by this method. An empty array,
null, orundefinedare also valid return values (in which case no order will be applied to the given operation).
Get a field by its fully qualified name, or by a fieldName + a modelName.
Arguments:
fieldName:stringFully qualified field name. If a fully qualified field name isn't provided, then you must provide the
modelNameargument.modelName?:stringThe name of the model that the field exists on. This argument is optional if the provided
fieldNameis a fully qualified name.Return value: Field
The field found, or
undefinedif the specified field is not found.
method ConnectionBase::getLockMode(options: any): object 📜
This method is an internal method that parses the "lock mode" options passed to a call to Connection.transaction.
These might be different depending on the connection driver you are using. Please refer to the documentation for your connection driver for more details.
Arguments:
options:anyPossibly connection specific lock options for a connection's Connection.transaction method. Generally this will either be a
truevalue, a Model name (for which table to lock), or a complete lock options object, which generally will look something like:{ lock: boolean; modelName: string; read: boolean; write: boolean }
lock- Iftrue, then lock the transactionmodelName- The name of the table(s) to lockread- Iftrue, then lock for readswrite- Iftrue, then lock for writes.Return value:
objectReturn the lock options for a transaction. These might change based on the connection driver you are using, but will generally look like
{ lock: boolean; modelName: string; read: boolean; write: boolean }.
lock- Iftrue, then lock the transactionmodelName- The name of the table(s) to lockread- Iftrue, then lock for readswrite- Iftrue, then lock for writes.
Retrieve a single model by its name. The model must be registered with this connection to be found.
Models can be registered to a connection with the ConnectionBase.registerModel or ConnectionBase.registerModels methods.
This method is "fully qualified aware", meaning you can pass a fully qualified name, such as "User:id" and it will fetch the "User" model.
Arguments:
modelName:stringThe model's name, or a fully qualified field name.
Return value: class Model
The model class found by the model's name, or
undefinedif no model is found.
method ConnectionBase::getModels(): object 📜
Get all models known to this connection.
Models are returned as a raw Object, and
so can be destructured. The keys of the returned
object are the model's names.
Models can be registered to a connection with the ConnectionBase.registerModel or ConnectionBase.registerModels methods.
Return value:
objectAn object of all models known to the connection, where each key is a model name, and each property value is the model's class.
method ConnectionBase::getOptions(): object 📜
Get the options for this connection.
These will be the options provided to the connection during creation, plus any other options the connection driver itself internally sets.
Return value:
objectThe options for this connection.
method ConnectionBase::getQueryEngineClass(): class QueryEngine 📜
Return the QueryEngine class used
for this connection, all its models, and all
query operations. By default this is just the
built-in QueryEngine that Mythix ORM
provides. You can create your own, and provide
it as the QueryEngine option to the connection
when you create the connection.
Return value: class QueryEngine
The QueryEngine to use for this connection, all its models, and all query operations for this connection.
method ConnectionBase::getQueryGenerator(): QueryGenerator | null 📜
Get the QueryGenerator instance for this connection, if it has one.
All connection drivers may not have a query generator. The query generator is the class that takes care of generating queries for the underlying database (i.e. SQL). If a query generator exists on a connection, it is very likely to be unique to the connection (i.e. PostgreSQL and MySQL have different query generators).
Return value: QueryGenerator |
nullReturn the QueryGenerator for this connection, or return
nullif none is defined for this connection.
method ConnectionBase::insert(Model: class Model, models: Array<Model | object> | object | Model, options?: object): Promise<Array<Model> | Model> 📜
Insert the specified models into the specified
table/bucket (based on the provided Model).
This will insert one or more models into the database.
Like nearly all such Mythix ORM methods, bulk operations are supported
out-of-the-box. You can provide a single model to models,
or you can provide an array of models.
The provided "models" can be either an object, an array of
objects, a model instance, or an array of model instances,
or a mix of both. Mythix ORM will ensure any provided raw
objects are first converted into model instances using the
provided Model before it inserts anything.
You can also supply "sub models", and those will also be
inserted in the correct order (and any foreign keys will
also be updated for you). For example, if you have a User
model that has a virtual Type.Model primaryRole field,
then you can supply a new Role model upon insertion and
Mythix ORM will handle this properly for you. For example:
await connection.insert(User, new User({ primaryRole: new Role({ ... }) })).
This type of sub model save also works on through-tables.
If primaryRole was targeting a Role model, but through
another table(s), then Mythix ORM will also create the through-table
relationships (if it is able to).
This will not work for Types.Models (multi-relations).
Mythix ORM doesn't know what you intend for multi-relations
(overwrite the set? add to the set? what?) so it will deliberately
skip multi-relational fields. "sub models on insert" only work for
single-relation fields defined with Types.Model. For multi-relation
fields you must manually work through the relation yourself. For example,
if our user instead had a Types.Models roles field (plural), then you
would instead need to:
Example:
let user = await connection.insert(User, new User({ ... })); let role = await connection.insert(Role, { ... }); // model instance is not required await user.addToRoles(role);Arguments:
Model: class ModelThe model class used for the operation. This defines what table/bucket to insert the specified models into.
models:Array<Model | object>|object| ModelThe model(s) to insert into the database. If raw objects are provided, then the properties of each object must match the required attributes for the model class.
options?:objectMost of these options are database/driver specific. However, the following options are common across all database drivers:
Option Type Default Value Description skipHooksboolean|objectundefinedSkip specific hooks. See ConnectionBase.runSaveHooks for more information. batchSizenumber500The size of each batch during a multi-model insert operation. Return value:
Promise<Array<Model>|Model>If you provide an array of models, then an array of models will be returned. If you provide only a single model, then a single model will be returned. If you provided "sub models" then those will be returned as "related models" on the primary model. For example, using the above
Userexample, the newly createdRolemodel that was stored for theprimaryRolewould be available on the returnedUsermodel asuser.Roles[0], or you could also access it via the field you set it onuser.primaryRole.
method ConnectionBase::isLimitSupportedInContext(options: object): boolean 📜
This method is called (and often provided)
by the underlying database driver to see
if a LIMIT clause is allowed to appear in
a given context/operation.
Arguments:
options:objectDriver specific options for the context.
Return value:
boolean
method ConnectionBase::isOrderSupportedInContext(options: object): boolean 📜
This method is called (and often provided)
by the underlying database driver to see
if an ORDER BY clause is allowed to appear in
a given context/operation.
Arguments:
options:objectDriver specific options for the context.
Return value:
boolean
method ConnectionBase::isStarted(): boolean 📜
Check to see if start has already been called
on this connection. This is used to know if a
connection is "active" or not.
Return value:
boolean
method ConnectionBase::literalToString(literal: LiteralBase, options?: object): string 📜
Convert the provided Literal to a string for the underlying database driver. The conversion will be database specific. The database driver connection is free to override this method.
This method will convert a AverageLiteral, a CountLiteral, a DistinctLiteral, a FieldLiteral, a MaxLiteral, a MinLiteral, a SumLiteral, or a Literal to a string. If the provided literal is not one of these types, than an exception will be thrown.
If you want to add custom literals to your application, then you will need to overload this method, and handle those custom literals manually (or simply stick to using Literal).
Arguments:
literal: LiteralBaseThe literal to convert.
options?:objectOptional options that can be passed to the literal conversion method. These are generally not provided by the user, but rather are often provided by the connection itself, for context-specific literal conversions. These options can and will changed based on the literal being converted, and the underlying connection.
Return value:
stringThe provided literal, converted to a string for the underlying database driver.
method ConnectionBase::max(query: QueryEngine, field: Field | string, options?: object): Promise<number> 📜
Get the maximum value for a column, spanning all matching rows.
This will return the maximum of all values in a column,
across all matching rows, as a number primitive.
Arguments:
query: QueryEngineThe query used to select which rows are used to calculate the maximum.
field: Field |stringA field instance, or a fully qualified field name, used as the target column in the underlying database to find the maximum across all matching values.
options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
Promise<number>The maximum value found across all matching rows.
method ConnectionBase::min(query: QueryEngine, field: Field | string, options?: object): Promise<number> 📜
Get the minimum value for a column, spanning all matching rows.
This will return the minimum of all values in a column,
across all matching rows, as a number primitive.
Arguments:
query: QueryEngineThe query used to select which rows are used to calculate the minimum.
field: Field |stringA field instance, or a fully qualified field name, used as the target column in the underlying database to find the minimum across all matching values.
options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
Promise<number>The minimum value found across all matching rows.
method ConnectionBase::parseQualifiedName(fieldName: string): object 📜
This is simply a convenience method that calls ModelUtils.parseQualifiedName.
Arguments:
fieldName:stringThe field name, fully qualified field name, or model name to parse. See ModelUtils.parseQualifiedName for more information.
Return value:
objectThe result. See ModelUtils.parseQualifiedName for more information.
See also: ModelUtils.parseQualifiedName
method ConnectionBase::pluck(query: QueryEngine, fields: Field | string | Array<Field> | Array<string>, options?: object): Array<any> | Array<Array<any>> | Array<object> 📜
Pluck only specific columns/fields from the
underlying database, using the provided query.
This method will return only the specified fields
from the database--as raw values--from rows matched
on by the provided query.
This method is often much faster than a normal select operation,
in that only the data requested will be transmitted from the database,
and models won't be constructed and stitched together on load. Use this
when you just need an "array of values" across certain columns from a table.
Arguments:
query: QueryEngineThe query used to select rows from which columns will be plucked.
fields: Field |string|Array<Field>|Array<string>Which fields to "pluck" from the matching rows. If an array is provided (even if it only contains a single field), then an array of arrays will be returned as the result. If a single field is provided (not an array), then an array of raw plucked column values will be returned instead.
options?:objectOperation specified options. These might change based on the database driver you are using, so please refer to your specific database driver documentation. One option that is common across all drivers is the
mapToObjectsboolean option. Iftrue, then each row in the returned array will be an object instead of raw column values, where the property of each "row object" will be the fully qualified names of each field provided as thefieldsargument.Return value:
Array<any>|Array<Array<any>>|Array<object>If the provided
fieldsargument is an array of fields (fully qualified field names, or Field instances), then the result will be an array of arrays, where each item in the top-level array is a "row", and each sub-array is the values for the columns (fields) specified. If a single field is specified, then an one dimensional array is returned, where each item is the column value for each row fetched. For example, if we callplucklike:let result = await connection.pluck(User.where.firstName.EQ('Bob'), 'User:id')then theresultwould look like[ 'USER_id_1,USER_id_2, ... ]where each value in the array is a user id. If however we call pluck like:let result = await connection.pluck(User.where.firstName.EQ('Bob'), [ 'User:id', 'User:firstName' ])then theresultwould look like[ [ 'USER_id_1', 'Bob' ], [ 'USER_id_2', 'Bob' ], ... ], because the providedfieldsis an array, an array of field values will be returned from each row. If theoptionmapToObjectsistrue, then an array of objects will be returned, where each object is a "row", and each property one of the specified fields. Note that the properties of each returned object will be the fully qualified field name of each field specified. So, for example, specifying a pluck field ofUser:idmeans that each returned object in the array will look like[ { 'User:id': 'USER_id_1' }, { 'User:id': 'USER_id_2' }, ... ]`.
method ConnectionBase::prepareAllModelsAndSubModelsForOperation(Model: class Model, models: object | Model | Array<Model | object>, options?: object): Map<string, Set<Model>> 📜
Recursively prepare all models for a persisting operation while also splitting each model out into its own separate list, and finally sorting the models based on insertion order.
This method will use ConnectionBase.splitModelAndSubModels to split provided models out into their own separate space. See this method for a better explanation of what this means.
It will also assign any foreign key values across models that it is able to.
For example, in the example provided in the documentation for ConnectionBase.splitModelAndSubModels,
we had new User({ primaryRole: new Role({ name: 'admin' }) }), where the Role
model is being persisted (as a child of User) at the same time the User is being
persisted. If Role has a generated id, such as one of the UUID or XID types,
then in our example here the primaryRoleID of the User could be set before User
is persisted, saving an extra query to the database to update this foreign key after
Role is persisted. In short, this method will also assign any foreign key values
that it already has before persisting any models.
Finally, after it has "prepared" the models, and split all models into their own
space, it will sort the resulting Map such that the models are in the correct
order for insertion. In the example we have been using, if User has a primaryRoleID
that is a foreign key, then it might require a non-null value before the User
model can be persisted. Because of this, it is important that the Role model
is stored first, so that we have the value we need for this primaryRoleID foreign key.
This is why the models are sorted in what is known as "creation order", or "insertion order".
This order is defined by the foreign keys themselves. Mythix ORM will walk all foreign keys
involved in the operation, and decide based on these what the "creation order" should be.
If you have two models that both have foreign keys pointing to each other, then the sort
order is undefined. If this is the case, the work-around is to simply manually persist
your models in the correct order (i.e. save Role first, and then supply the foreign key
to User yourself from the result).
Arguments:
Model: class ModelThe model class of the primary model being persisted. The primary model could also be called the "root model". In our example above the primary model is
User.models:object| Model |Array<Model | object>The models to prepare. Any model that is a "raw object" will be instantiated into the Model class provided. Any "sub models" will be split into their own space in the resulting
Map.options?:objectOptional options to supply to this operation. This options object isn't used by Mythix ORM, but is provided in case any driver specific connection needs them when overloading this model. These options come from the options provided to a database operation, such as the options provided to an
insert,upsert, orupdatecall.Return value:
Map<string, Set<Model>>The models processed, and put into their own named
Set. The keys for theMapare the names of the models themselves.
method ConnectionBase::prepareAllModelsForOperation(Model: class Model, models: object | Model | Array<Model | object>, options: object): PreparedModels 📜
This method will prepare all provided models for
an insert, upsert, or update operation.
What it does is ensure every provided model is a model instance, checks if the model is persisted, and if each model has dirty fields.
Models that are persisted and not dirty will be filtered out, so that proceeding operations will "ignore" them entirely.
All dirty fields across all models are combined into a unified
list of dirty fields. This unified list is then used for the list
of columns in an insert, upsert, or updateAll operation.
Arguments:
Model: class ModelThe model class to use for preparing the provided models. All models provided must be of this model type.
models:object| Model |Array<Model | object>The models to prepare. Any model that is a "raw object" will be instantiated into the Model class provided.
options:objectOptions for the operation. These include
startIndex,endIndex(orbatchSize) for batch operations, andskipPersisted,isUpdateOperation, orisInsertOperationfor other context-specific operations.Return value:
PreparedModelsReturn an object with the shape
{ models: Array<Model>, dirtyFields: Array<Field>, dirtyModels: Array<Model> }which is known to Mythix ORM as "prepared models". Mythix ORM can understand "prepared models" verses simple "models" in most contexts. PreparedModels are often passed around after first receiving models from the user, so as not to "prepare" them more than once.
method ConnectionBase::query(sql, options): database specific 📜
"raw" database/driver specific query interface.
For SQL based databases, this would send a direct query string to the database. For other drivers, the arguments and operations that are executed might change.
Use this method to directly interact with the underlying database, in its own native query language.
The arguments and return value from this method is database/driver
specific. Any options argument the database provides are also
specific to the underlying database driver. However, one option
is common across all drivers, and this is the logger option. If
set, it is expected to have a log method in the provided logger
object. Oftentimes, this will simply be { logger: console }, but
you can provided any custom logger instance you want, as long as it
has a log method that can be called to log the results of the query.
Most drivers also support a { logger } option as a connection option
when the connection is first instantiated, which will provided logging
to every query that goes through the connection.
Arguments:
sqloptionsReturn value:
database specificA database/driver specific return value, based on the query provided.
Register the provided model class.
This will register the provided model class with this
connection. The model must not already be bound to
another connection, or you must specify the option
{ forceConnectionBinding: true } if it is. You
can specify the option of { bindModels: false }
if you don't wish to bind this model to this connection.
Any options provided are optional, and will override
the same options provided to the connection itself when
it was created.
Arguments:
Model: class ModelThe model class to register with this connection. If not bound, then it will simply exist in the model pool for this connection. If bound, then this connection will bind itself to the model being registered.
options?:objectOptions looks like
{ forceConnectionBinding: boolean; bindModels: boolean; }. This is an optional argument. Both options will default to the same options provided to the connection when it was created. If you specify either of these options they simply override the connection's default.Return value: class Model
The registered model class, which may have changed during registration. It is not uncommon for the connection driver itself to modify the model class, or to return a new model class that inherits from your model class. The class that is returned should be the class that you use for this connection, and will be the same class returned by a call to Connection.getModel, or Connection.getModels.
method ConnectionBase::registerModels(Model: Array<class Model> | { [key: string]: class Model }, options?: object): class Model 📜
Register multiple models at the same time.
This will register the provided models with this
connection. The models provided must not already be bound to
another connection, or you must specify the option
{ forceConnectionBinding: true } if any of them are. You
can specify the option of { bindModels: false }
if you don't wish to bind these models to this connection.
Any options provided are optional, and will override
the same options provided to the connection itself when
it was created.
Arguments:
Model: Array<class Model> | { [key: string]: class Model }The model classes to register with this connection. If no models are bound, then they will simply exist in the model pool for this connection. If bound, then this connection will bind itself to every model being registered.
options?:objectOptions looks like
{ forceConnectionBinding: boolean; bindModels: boolean; }. This is an optional argument. Both options will default to the same options provided to the connection when it was created. If you specify either of these options they simply override the connection's default.Return value: class Model
The registered model classes, which may have changed during registration. It is not uncommon for the connection driver itself to modify the model classes, or to return a new model classes that inherit from your model classes. The classes that are returned should be the classes that you use for this connection, and will be the same classes returned by a call to Connection.getModel, or Connection.getModels.
method ConnectionBase::runSaveHooks(Model: class Model, models: Array<Model>, operationHookName: 'onBeforeCreate' | 'onBeforeUpdate' | 'onAfterCreate' | 'onAfterUpdate', saveHookName: 'onBeforeSave' | 'onAfterSave', options: object): Promise<Array<any>> 📜
Run model hooks by name.
This method will run the hooks for a model instance.
operationHookName will be one of onBeforeCreate, onBeforeUpdate,
onAfterCreate, or onAfterUpdate.
operationHookName will be one of onBeforeSave, or onAfterSave.
The idea is that any of the onBefore* operations will always be
followed by an onBeforeSave, whereas the onAfter* operations
are all followed by an onAfterSave.
Notes:
- Hooks for models are run serially for a given model, but all model hooks are run in parallel across all models.
- The
onValidatehook is called from theonBeforeSavehook itself. This is so that the user can decide if model validations should be ran or not (simply by callingthis.onValidatethemselves... or not). If you overload theonBeforeSavemethod, make certain you callsuper.onBeforeSave.apply(this, arguments)(orthis.onValidate.apply(this, arguments)directly), because if you don't your model validations will be skipped.Arguments:
Model: class ModelThe model class we are running hooks for. All
modelsprovided should be instances of this class.models: Array<Model>All model instances to run hooks on. These should all be instances of the provided
Modelclass.operationHookName:'onBeforeCreate'|'onBeforeUpdate'|'onAfterCreate'|'onAfterUpdate'The hook to call (if not skipped by the
skipHooksoption).saveHookName:'onBeforeSave'|'onAfterSave'The name of the save hook to call after the operation hook has completed (if not skipped by the
skipHooksoption).options:objectOptions for the operation being completed. For example, if this is an
insertoperation, then these "options" will be the options for theinsertoperation. One other useful option that can be supplied here is theskipHooks: boolean | { [key: 'onBeforeCreate' | 'onBeforeUpdate' | 'onAfterCreate' | 'onAfterUpdate' | 'onBeforeSave' | 'onAfterSave' ]: boolean; }option. If this istrue, then all hooks will be bypassed (not called). If this is an object, then each key should be a hook name, and if it has atruevalue, then that specific hook will be bypassed (not called). This allows the caller of an operation such asinsert, orupdateto request that specific hooks not be called.Return value:
Promise<Array<any>>The result of all model hooks. Mythix ORM ignores the return value from model hooks, but it collects them and returns them for the user.
method ConnectionBase::select(query: QueryEngine, options?: object): AsyncGenerator<Model> 📜
Select data from the underlying database.
To select data from the database you will use this method,
providing a query as a QueryEngine instance.
The provided query will be used to generate the underlying
request to the database, will collect the response, and return
the results to the caller.
This method is an async generator method, and is designed for
"streaming" results from the database, one "row" at a time. Many
methods that call this method (such as QueryEngine.all)
collect all the results from the async generator to return an array
of results to the caller. This is because it is often tedious to
collect the results yourself from the async generator, and often the
caller simply wants a small amount of data from the database.
However, if you intend to fetch large amounts of data from your database,
it is a good idea to call this method directly, and iterate the results
of the async generator manually. All methods that in-turn call this
method (such as QueryEngine.all) will generally have a
{ stream: true } option that can be provided, causing the method to
return the async generator, instead of the collected results.
Arguments:
query: QueryEngineThe query to run against the underlying database. This is generated from a QueryEngine interface. The result of this QueryEngine instance will then be converted to a query, or generated code to interact with the underlying database.
options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
AsyncGenerator<Model>
method ConnectionBase::setContextValue(key: any, value: any): any 📜
Set a value onto the AsyncLocalStorage context.
AsyncLocalStorage is used primarily for two purposes: 1) to provide a connection to models, and 2) to pass a transaction connection down through the call stack. However, it can also be used for any "context" level values the user wishes to store.
Notes:
- An
AsyncLocalStoragecontext might not exist when this call is made, in which case this method will do nothing, and silently return.Arguments:
key:anyThe key for the value you wish to set. The underlying "context" provided by
AsyncLocalStorageis aMap, so the "key" can be any value.value:anyThe value to set to the specified key.
Return value:
any
method ConnectionBase::setPersisted(models: Array<Model> | PreparedModels, value): undefined 📜
Mark all models provided as "persisted".
Every Mythix ORM model instance has a non-enumerable property _persisted.
If this is true, then Mythix ORM will treat the model as persisted.
This method iterates all provided models, and marks each as persisted
by setting this _persisted property to true.
For each model iterated, this method checks if the instance property
_mythixModelInstance is true. If this is not the case, then that
instance (whatever it is) will be silently skipped.
Arguments:
models:Array<Model>| PreparedModelsModels to mark as persisted.
valueIf
true, models will be marked as persisted. Iffalse, models will be marked as not-persisted.Return value:
undefinedThis method modifies
modelsdirectly, and returns nothing.
method ConnectionBase::setQueryGenerator(queryGenerator: QueryGenerator | null): undefined 📜
Set the QueryGenerator instance for this
connection. This is rarely used as the QueryGenerator
is often supplied as connection options when creating
the connection (as the queryGenerator option). However,
it can be set to a new instance at any time with this
method.
Arguments:
queryGenerator: QueryGenerator |nullThe new QueryGenerator instance to use for generating underlying database queries. Set to
nullto specify no query generator (note: this might break whatever connection you are using as most connections require their query generator).Return value:
undefined
method ConnectionBase::splitModelAndSubModels(Model: class Model, primaryModel: Model, _relationMap?: Map<string, Set<Model>>): Map<string, Set<Model>> 📜
Recursively walk all provided models and split models into a map of model name and model instances.
This method is used to split apart provided models by the user.
For example, it is fully valid to provide "sub models" during most persisting
operations, such as new User({ primaryRole: new Role({ name: 'admin' }) }).
This method would find the sub model "Role" in the above example, and split it out to be processed separately in the persisting operation.
Arguments:
Model: class ModelThe model class of the primary model being scanned. The primary model could also be called the "root model". In our example above the primary model is
User.primaryModel: ModelThe model instance to scan for "sub models". In the example above this would be
User(thoughRoleitself will also be passed through this method to check if it also has any sub models)._relationMap?:Map<string, Set<Model>>This argument is provided internally while recursing, and should not be provided unless you know exactly what you are doing.
Return value:
Map<string, Set<Model>>Return a map of all models found, where the model name is the key for the
Map, and each model instance is added to theSetfor that key. Using the above example, the return value would be:new Map({ User: new Set([ user ]), Role: new Set([ role ]) }).
method ConnectionBase::stackAssign(obj: object): object 📜
An Object.assign type of operation... with a twist.
stackAssign works kinda like Object.assign. It has
the same interface, and accomplishes the same result.
What it does differently however is that it uses
Object.create on the first argument to create a new
object, using the first argument as a prototype. It then
merges all remaining object arguments into this newly
created object.
This is used quite heavily in the underlying Mythix ORM engine.
It's purpose is to modify options arguments as they pass through
the engine. For example, a destroy operation might want to inform
the projection engine that we don't want any field aliases... and
so it will stackAssign the options, setting noProjectionAliases: true
for the "stacked options" object. Javascript--being the prototypical language
that it is--will behave like the objects in question have been
passed through Object.assign, because all the original options to
any operation are still accessible in the prototype, but may have been
overridden like in our example of a destroy operation. This allows the
engine to easily and quickly override options without mutating the original
options object provided, and still be able to access provided options,
even if they are not enumerable.
Arguments:
obj:objectThe object to set as the prototype of the newly created object, using
Object.createon it. ...args: Array The other objects to merge into this object, usingObject.assign.Return value:
objectThe newly "stacked" and merged object.
method ConnectionBase::start(): Promise<void> 📜
Start this connection.
The default implementation will throw an exception.
Every connection is expected to overload this and provide connection specific startup code (such as connecting to the database).
Return value:
Promise<void>
static method ConnectionBase::getLiteralClassByName(name: string): class LiteralBase 📜
Fetch a literal class by its name.
The following is a table that displays
the name argument that can be provided,
and the resulting Literal class that would
be returned for that name.
name |
Resulting literal class |
|---|---|
'Average' |
AverageLiteral |
'Base' |
LiteralBase |
'Count' |
CountLiteral |
'Distinct' |
DistinctLiteral |
'Field' |
FieldLiteral |
'FieldBase' |
LiteralFieldBase |
'Literal' |
Literal |
'Max' |
MaxLiteral |
'Min' |
MinLiteral |
'Sum' |
SumLiteral |
Arguments:
name:stringThe name of the literal class to return.
Return value: class LiteralBase
Return the literal class requested.
static method ConnectionBase::isConnection(value: any): boolean 📜
Check to see if the provided value is
an instance of a Mythix ORM ConnectionBase.
Unlike ConnectionBase.static isConnectionClass, which
checks if a class is a ConnectionBase, this will check
to see if an instance is an instance of a
Mythix ORM ConnectionBase. It will return
true if the provided value is an instanceof
ConnectionBase, or if the value's constructor
property has a truthy _isMythixConnection property
(value.constructor._isMythixConnection)
Arguments:
value:anyValue to check.
Return value:
boolean
static method ConnectionBase::isConnectionClass(value: Function): boolean 📜
Use this method to check if a class
is a Mythix ORM connection. It will return
true if the provided value is a class
that inherits from ConnectionBase, or
if the provided value has an attribute
named _isMythixConnection that is truthy.
Arguments:
value:FunctionValue to check.
Return value:
boolean
static method ConnectionBase::Literal(name: string): LiteralBase 📜
Create the literal specified by name.
Whereas ConnectionBase.static getLiteralClassByName will simply return the literal class specified, this will create the specified literal, with the provided arguments.
Please see ConnectionBase.static getLiteralClassByName for
possible names that can be provided as the name argument.
Arguments:
name:stringThe name of the literal to create. See ConnectionBase.static getLiteralClassByName for possible values. ...args: Array Arguments to provide to the literal constructor.
Return value: LiteralBase
Return an instance the literal requested, using the arguments specified.
See also: static ConnectionBase.getLiteralClassByName
method ConnectionBase::stop(): Promise<void> 📜
Stop (shutdown) this connection.
The default implementation will throw an exception.
Every connection is expected to overload this and provide connection specific shutdown code (such as disconnecting from the database).
Return value:
Promise<void>
method ConnectionBase::sum(query: QueryEngine, field: Field | string, options?: object): Promise<number> 📜
Get the sum of all values for a column, spanning all matching rows.
This will return the sum of all values in a column,
across all matching rows, as a number primitive.
Arguments:
query: QueryEngineThe query used to select which rows are used to calculate the sum.
field: Field |stringA field instance, or a fully qualified field name, used as the target column in the underlying database to find the sum of all matching values.
options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
Promise<number>The sum of all values found across all matching rows.
method ConnectionBase::toQueryEngine(value: any): QueryEngine | undefined 📜
This will take something that can be turned into a query and turn it into a query.
If a QueryEngine instance is provided, it will simply be returned.
If a Model is provided, then Model.where
will be returned, returning a QueryEngine
for the model provided.
In the future this may also accept other possible values that could be turned into a query.
This is often internally called by methods of the connection on a given argument provided by the user, which could validly be either a model or a query. Connection.destroyModels is one example of this.
Arguments:
value:anyThe value to attempt to turn into a QueryEngine.
Return value: QueryEngine |
undefined
method ConnectionBase::transaction(callback: (connection: Connection) => any, options?: object): Promise<any> 📜
Initiate a transaction (or snapshot/sub-transaction) if the database driver supports transactions.
This will initiate a transaction in the underlying database,
if the database supports it. For SQL type databases this would
be a BEGIN/COMMIT/ROLLBACK block. If this method is called
when a transaction is already in-progress, then a snapshot/sub-transaction
will be started instead.
This method will start a transaction in the underlying database,
and call the provided asynchronous callback. If the callback throws
an error, then the transaction (or snapshot) will be automatically
rolled-back. There is a single connection argument that will be
provided to the callback function when called. This connection argument
will be the transaction connection itself, which for many database drivers is simply
the same connection the transaction was started from. At a lower-level,
Mythix ORM will use an AsyncLocalStorage
context to provide the transaction connection to all code executed inside
the callback, so the provided connection argument can generally be ignored.
However, if AsyncLocalStorage isn't
supported in your environment, or the specific driver you are using requires that you use
the supplied connection argument, then you must use the supplied connection
for all your operations, and provide it as the { connection } option to all Mythix ORM
calls made inside the callback.
Arguments:
callback: (connection: Connection) => anyThe async callback to call for the transaction operation. This should return as quickly as possible to avoid deadlocks in the underlying database. Whatever value this method returns will be the return value from the
transactioncall itself. If an exception is thrown in this method, then the transaction will be automatically rolled-back. If no exception is thrown from this method, then when done executing, aCOMMITwill be sent to the underlying database automatically for you.options?:objectOptional database specific options to supply for the transaction operation. There are two options that are supported across most database drivers, and those are
connectionandlock. Theconnectionoption supplies the the connection to initiate the transaction from, which for example might be another transaction connection (initiating a sub-transaction). If noconnectionoption is supplied, then theconnectionthis method was called from is used instead. The second common option islock, which specifies how/if to lock the table for the transaction. See ConnectionBase.getLockMode for your specific driver for more information on thislockoption.Return value:
Promise<any>Return whatever return value is returned from the provided callback.
Truncate (erase/clear) the entire table/bucket defined
by the provided Model. All rows/objects from the underlying
table/bucket will be destroyed, leaving you with an empty
table/bucket.
Arguments:
Model: class ModelThe model class that defines the underlying table/bucket to wipe clean/erase.
options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
Promise<void>
Convert any field type to the type needed for the underlying database driver. Only built-in Mythix ORM fields are supported. If a custom field type that is not supported is provided then an exception will be thrown.
If you need to support a custom field type, simply subclass the connection you are using, and overload this method to handle your custom field types.
Arguments:
type: TypeThe field type to convert to use in the underlying database.
options?:objectOptional options to pass to the underlying conversion method.
Return value:
stringThe field type needed by the underlying database driver.
method ConnectionBase::update(Model: class Model, models: Array<Model | object> | object | Model, options?: object): Promise<Array<Model> | Model> 📜
Update the specified models in the database.
Many databases don't have good (or even decent) support for bulk updates, so unfortunately this method is fairly slow, and will usually make a query to the database for each model updated.
If you want to update many models at the same time (using the same attributes across all models), then consider using the ConnectionBase.updateAll method instead.
Notes:
- Models will only be updated if they are dirty. Also, only the dirty attributes for each model will be updated (some attributes are always dirty, for example
updatedAtfields are forced to always be dirty based on the configuration of theirdefaultValue).Arguments:
Model: class ModelThe model class used for the operation. This defines what table/bucket to update.
models:Array<Model | object>|object| ModelThe model(s) to update in the database. If raw objects are provided, then the properties of each object must match the required attributes for the model class.
options?:objectMost of these options are database/driver specific. However, the following options are common across all database drivers:
Option Type Default Value Description skipHooksboolean|objectundefinedSkip specific hooks. See ConnectionBase.runSaveHooks for more information. batchSizenumber500The size of each batch during a multi-model update operation. Return value:
Promise<Array<Model>|Model>If you provide an array of models, then an array of models will be returned. If you provide only a single model, then a single model will be returned.
method ConnectionBase::updateAll(query: QueryEngine, attributes: object | Model, options?: object): Promise<any> 📜
Update multiple models at the same time (bulk update).
This will update multiple models at the same time
using the provided query to select which models to update.
All matching rows will set the provided attributes upon them.
The provided attributes can be a model instance, or
a raw object. If a raw object is provided, then they
will be converted into a model instance using the provided
Model class. This also means that you can only bulk update
columns/fields that exist on the model itself (i.e. you might have
other columns in your table not related to this model, and
those can not be updated using this method).
Notes:
- As always with Mythix ORM, you will never supply raw column names as the
attributes. You must always provide model field names in Mythix ORM.- This will be an update operation across all matching rows, using the data provided. This method is really only useful when you want to update multiple rows to the same values. If you need to update each row to different values per-row, then use the ConnectionBase.update method instead.
Arguments:
query: QueryEngineThe query used to select which models/rows to update. The "root model" of the query is the table/bucket that will be updated.
attributes:object|ModelThe attributes to set across all updated rows.
options?:objectOperation specific options. These will change depending on the database driver you are using. Please refer to the documentation for your specific driver for more information.
Return value:
Promise<any>A database specific result from the
UPDATEstatement. In the future all "database specific" results will be abstracted away. So in the future, this will likely return the number of rows updated as anumber(HELP WANTED).
method ConnectionBase::upsert(Model: class Model, models: Array<Model | object> | object | Model, options?: object): Promise<Array<Model> | Model> 📜
Insert or update (upsert) models into the database.
This method is only supported by some databases. Database
drivers that don't support upsert natively may attempt to emulate
the operation (at the cost of speed).
This method should function identically to ConnectionBase.insert, with the exception that it should update rows that already exist in the database instead of inserting new rows.
Arguments:
Model: class ModelThe model class used for the operation. This defines what table/bucket to insert the specified models into.
models:Array<Model | object>|object| ModelThe model(s) to insert into the database. If raw objects are provided, then the properties of each object must match the required attributes for the model class.
options?:objectMost of these options are database/driver specific. However, the following options are common across all database drivers:
Option Type Default Value Description skipHooksboolean|objectundefinedSkip specific hooks. See ConnectionBase.runSaveHooks for more information. batchSizenumber500The size of each batch during a multi-model upsert operation. Return value:
Promise<Array<Model>|Model>If you provide an array of models, then an array of models will be returned. If you provide only a single model, then a single model will be returned. If you provided "sub models" then those will be returned as "related models" on the primary model. For example, using the above
Userexample, the newly createdRolemodel that was stored for theprimaryRolewould be available on the returnedUsermodel asuser.Roles[0], or you could also access it via the field you set it onuser.primaryRole.See also: ConnectionBase.insert
- Associations
- Certifications
- Connection Binding
- Home
- Models
- Queries
- TypeScript
- Types Reference
-
namespace AsyncStore
- function getContextStore
- function getContextValue
- function runInContext
- function setContextValue
-
namespace Helpers
- function checkDefaultValueFlags
- function defaultValueFlags
- function getDefaultValueFlags
- property FLAG_LITERAL
- property FLAG_ON_INITIALIZE
- property FLAG_ON_INSERT
- property FLAG_ON_STORE
- property FLAG_ON_UPDATE
- property FLAG_REMOTE
-
namespace MiscUtils
- function collect
- function valueToDateTime
-
namespace ModelUtils
- function parseQualifiedName
-
namespace QueryUtils
- function generateQueryFromFilter
- function mergeFields
- function parseFilterFieldAndOperator
-
class AverageLiteral
- method static isAggregate
- method toString
-
class BigIntType
- property Default
- method castToType
- method constructor
- method isValidValue
- method static getDisplayName
- method toString
-
class BlobType
- method castToType
- method constructor
- method isValidValue
- method static getDisplayName
- method toString
-
class BooleanType
- method castToType
- method isValidValue
- method static getDisplayName
- method toString
-
class CacheKey
- method constructor
- method valueOf
-
class CharType
- method castToType
- method isValidValue
- method static getDisplayName
- method toString
-
class ConnectionBase
- property _isMythixConnection
- property DefaultQueryGenerator
- property dialect
- property Literals
- method _averageLiteralToString
- method _bigintTypeToString
- method _blobTypeToString
- method _booleanTypeToString
- method _charTypeToString
- method _countLiteralToString
- method _datetimeTypeToString
- method _dateTypeToString
- method _distinctLiteralToString
- method _escape
- method _escapeID
- method _fieldLiteralToString
- method _getFromModelCache
- method _integerTypeToString
- method _maxLiteralToString
- method _minLiteralToString
- method _numericTypeToString
- method _realTypeToString
- method _setToModelCache
- method _stringTypeToString
- method _sumLiteralToString
- method _textTypeToString
- method _uuidV1TypeToString
- method _uuidV3TypeToString
- method _uuidV4TypeToString
- method _uuidV5TypeToString
- method _xidTypeToString
- method addColumn
- method addIndex
- method aggregate
- method alterColumn
- method alterTable
- method average
- method buildConnectionContext
- method bulkModelOperation
- method constructor
- method convertDateToDBTime
- method count
- method createContext
- method createQueryGenerator
- method createTable
- method createTables
- method destroy
- method destroyModels
- method dirtyFieldHelper
- method dropColumn
- method dropIndex
- method dropTable
- method dropTables
- method ensureAllModelsAreInstances
- method escape
- method escapeID
- method exists
- method finalizeQuery
- method findModelField
- method getContextValue
- method getDefaultFieldValue
- method getDefaultOrder
- method getField
- method getLockMode
- method getModel
- method getModels
- method getOptions
- method getQueryEngineClass
- method getQueryGenerator
- method insert
- method isStarted
- method literalToString
- method max
- method min
- method parseQualifiedName
- method pluck
- method prepareAllModelsAndSubModelsForOperation
- method prepareAllModelsForOperation
- method query
- method registerModel
- method registerModels
- method runSaveHooks
- method select
- method setContextValue
- method setPersisted
- method setQueryGenerator
- method splitModelAndSubModels
- method stackAssign
- method start
- method static getLiteralClassByName
- method static isConnection
- method static isConnectionClass
- method static Literal
- method stop
- method sum
- method toQueryEngine
- method transaction
- method truncate
- method typeToString
- method update
- method updateAll
- method upsert
-
class CountLiteral
- method static isAggregate
- method static isFieldRequired
- method toString
-
class DateTimeType
- property Default
- method castToType
- method constructor
- method deserialize
- method isValidValue
- method serialize
- method static getDisplayName
- method toString
-
class DateType
- property Default
- method castToType
- method constructor
- method deserialize
- method isValidValue
- method serialize
- method static getDisplayName
- method toString
-
class DistinctLiteral
- method toString
-
class Field
- property _isMythixField
- property allowNull
- property defaultValue
- property fieldName
- property get
- property index
- property primaryKey
- property set
- property type
- property unique
- property validate
- method clone
- method constructor
- method setModel
- method static isField
- method static isFieldClass
-
class FieldLiteral
- method toString
- class FieldScope
-
class ForeignKeyType
- method castToType
- method constructor
- method getOptions
- method getTargetField
- method getTargetFieldName
- method getTargetModel
- method getTargetModelName
- method initialize
- method isValidValue
- method parseOptionsAndCheckForErrors
- method static getDisplayName
- method static isForeignKey
- method toString
-
class IntegerType
- property Default
- method castToType
- method constructor
- method isValidValue
- method static getDisplayName
- method toString
-
class Literal
- method constructor
-
class LiteralBase
- property _isMythixLiteral
- method constructor
- method definitionToField
- method fullyQualifiedNameToDefinition
- method static isAggregate
- method static isLiteral
- method static isLiteralClass
- method static isLiteralType
- method toString
- method valueOf
-
class LiteralFieldBase
- method constructor
- method getField
- method getFullyQualifiedFieldName
- method static isFieldRequired
- method valueOf
-
class MaxLiteral
- method static isAggregate
- method toString
-
class MinLiteral
- method static isAggregate
- method toString
-
class Model
- property _isMythixModel
- method _castFieldValue
- method _constructField
- method _constructFields
- method _constructor
- method _getConnection
- method _getDirtyFields
- method _getFieldValue
- method _initializeFieldData
- method _initializeModelData
- method _setFieldValue
- method clearDirty
- method constructor
- method destroy
- method getAttributes
- method getConnection
- method getDataValue
- method getDirtyFields
- method getOptions
- method hasValidPrimaryKey
- method isDirty
- method isPersisted
- method onAfterCreate
- method onAfterSave
- method onAfterUpdate
- method onBeforeCreate
- method onBeforeSave
- method onBeforeUpdate
- method onValidate
- method reload
- method save
- method setAttributes
- method setDataValue
- method static _getConnection
- method static all
- method static bindConnection
- method static count
- method static create
- method static cursor
- method static defaultScope
- method static finalizeQuery
- method static first
- method static getConcreteFieldCount
- method static getContextValue
- method static getField
- method static getFields
- method static getForeignKeyFieldsMap
- method static getForeignKeysTargetField
- method static getForeignKeysTargetFieldNames
- method static getForeignKeysTargetModelNames
- method static getForeignKeysTargetModels
- method static getModel
- method static getModelContext
- method static getModelName
- method static getPluralModelName
- method static getPrimaryKeyField
- method static getPrimaryKeyFieldName
- method static getQueryEngine
- method static getQueryEngineClass
- method static getSingularName
- method static getSortedFields
- method static getTableName
- method static getUnscopedQueryEngine
- method static getWhereWithConnection
- method static hasField
- method static hasRemoteFieldValues
- method static initializeFields
- method static isForeignKeyTargetModel
- method static isModel
- method static isModelClass
- method static iterateFields
- method static last
- method static mergeFields
- method static pluck
- method static primaryKeyHasRemoteValue
- method static setContextValue
- method static toString
- method static updateModelContext
- method toJSON
- method toString
- method updateDirtyID
-
class ModelScope
- method _getField
- method AND
- method CROSS_JOIN
- method DISTINCT
- method EXISTS
- method Field
- method FULL_JOIN
- method GROUP_BY
- method HAVING
- method INNER_JOIN
- method JOIN
- method LEFT_JOIN
- method LIMIT
- method mergeFields
- method NOT
- method OFFSET
- method OR
- method ORDER
- method PROJECT
- method RIGHT_JOIN
-
class ModelType
- method fieldNameToOperationName
- method initialize
-
class ModelsType
- method fieldNameToOperationName
- method initialize
-
class NumericType
- method castToType
- method constructor
- method isValidValue
- method static getDisplayName
- method toString
-
class ProxyClass
- property APPLY
- property AUTO_CALL
- property AUTO_CALL_CALLED
- property AUTO_CALL_CALLER
- property CALLABLE
- property CONSTRUCT
- property DEFINE_PROPERTY
- property DELETE_PROPERTY
- property GET
- property GET_OWN_PROPERTY_DESCRIPTOR
- property GET_PROTOTYPEOF
- property HAS
- property IS_EXTENSIBLE
- property MISSING
- property OWN_KEYS
- property PREVENT_EXTENSIONS
- property PROXY
- property SELF
- property SET
- property SET_PROTOTYPEOF
- property shouldSkipProxy
- property TARGET
- method ___autoCall
- method ___call
- method constructor
-
class QueryEngine
- method all
- method average
- method constructor
- method count
- method cursor
- method destroy
- method exists
- method finalizeQuery
- method first
- method getFieldScopeClass
- method getModelScopeClass
- method last
- method max
- method MERGE
- method min
- method Model
- method pluck
- method sum
- method toString
- method unscoped
- method updateAll
-
class QueryEngineBase
- method _fetchScope
- method _inheritContext
- method _newFieldScope
- method _newModelScope
- method _newQueryEngineScope
- method _pushOperationOntoStack
- method clone
- method constructor
- method filter
- method getAllModelsUsedInQuery
- method getConnection
- method getFieldScopeClass
- method getModel
- method getModelScopeClass
- method getOperationContext
- method getOperationStack
- method getQueryEngineClass
- method getQueryEngineScope
- method getQueryEngineScopeClass
- method getQueryID
- method isLastOperationCondition
- method isLastOperationControl
- method isModelUsedInQuery
- method logQueryOperations
- method map
- method queryHasConditions
- method queryHasJoins
- method static generateID
- method static getQueryOperationInfo
- method static isQuery
- method static isQueryOperationContext
- method walk
-
class QueryGeneratorBase
- method _averageLiteralToString
- method _countLiteralToString
- method _distinctLiteralToString
- method _fieldLiteralToString
- method _maxLiteralToString
- method _minLiteralToString
- method _sumLiteralToString
- method constructor
- method escape
- method escapeID
- method getConnection
- method getFieldDefaultValue
- method getIndexFieldsFromFieldIndex
- method setConnection
- method stackAssign
- method toConnectionString
-
class RealType
- method castToType
- method constructor
- method isValidValue
- method static getDisplayName
- method toString
-
class SerializedType
- method castToType
- method constructor
- method deserialize
- method getOptions
- method initialize
- method isDirty
- method isValidValue
- method onSetFieldValue
- method serialize
- method static getDisplayName
- method toString
-
class StringType
- method castToType
- method constructor
- method isValidValue
- method static getDisplayName
- method toString
-
class SumLiteral
- method static isAggregate
- method toString
-
class TextType
- method castToType
- method constructor
- method isValidValue
- method static getDisplayName
- method toString
-
class Type
- property _isMythixFieldType
- property clone
- method castToType
- method clone
- method constructor
- method deserialize
- method exposeToModel
- method getDisplayName
- method getField
- method getModel
- method initialize
- method isDirty
- method isForeignKey
- method isRelational
- method isRemote
- method isValidValue
- method isVirtual
- method onSetFieldValue
- method serialize
- method setField
- method setModel
- method static instantiateType
- method static isSameType
- method static isType
- method static isTypeClass
- method static wrapConstructor
- method toConnectionType
-
class UUIDV1Type
- property Default
- method castToType
- method getArgsForUUID
- method isValidValue
- method static getDisplayName
- method validateOptions
-
class UUIDV3Type
- property Default
- method castToType
- method getArgsForUUID
- method isValidValue
- method static getDisplayName
- method validateOptions
-
class UUIDV4Type
- property Default
- method castToType
- method getArgsForUUID
- method isValidValue
- method static getDisplayName
- method validateOptions
-
class UUIDV5Type
- property Default
- method castToType
- method getArgsForUUID
- method isValidValue
- method static getDisplayName
- method validateOptions
-
class XIDType
- property Default
- method castToType
- method isValidValue
- method static getDisplayName