2020-01-21 18:12:14 +00:00
|
|
|
// Copyright IBM Corp. 2018,2019. All Rights Reserved.
|
2018-05-02 23:21:49 +00:00
|
|
|
// Node module: loopback-datasource-juggler
|
|
|
|
// This file is licensed under the MIT License.
|
|
|
|
// License text available at https://opensource.org/licenses/MIT
|
|
|
|
|
2019-12-05 08:51:54 +00:00
|
|
|
import {AnyObject, Callback, Options} from './common';
|
2018-05-02 23:21:49 +00:00
|
|
|
import {Connector} from './connector';
|
|
|
|
import {
|
|
|
|
ModelBaseClass,
|
|
|
|
ModelBuilder,
|
|
|
|
ModelDefinition,
|
2020-07-18 18:54:32 +00:00
|
|
|
PropertyDefinition
|
2018-05-02 23:21:49 +00:00
|
|
|
} from './model';
|
2018-07-24 20:48:17 +00:00
|
|
|
import {EventEmitter} from 'events';
|
2019-06-27 13:10:30 +00:00
|
|
|
import {IsolationLevel, Transaction} from './transaction-mixin';
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* LoopBack models can manipulate data via the DataSource object.
|
|
|
|
* Attaching a `DataSource` to a `Model` adds instance methods and static methods to the `Model`.
|
|
|
|
*
|
|
|
|
* Define a data source to persist model data.
|
|
|
|
* To create a DataSource programmatically, call `createDataSource()` on the LoopBack object; for example:
|
|
|
|
* ```js
|
|
|
|
* var oracle = loopback.createDataSource({
|
|
|
|
* connector: 'oracle',
|
|
|
|
* host: '111.22.333.44',
|
|
|
|
* database: 'MYDB',
|
|
|
|
* username: 'username',
|
|
|
|
* password: 'password'
|
|
|
|
* });
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* All classes in single dataSource share same the connector type and
|
|
|
|
* one database connection.
|
|
|
|
*
|
|
|
|
* For example, the following creates a DataSource, and waits for a connection callback.
|
|
|
|
*
|
|
|
|
* ```
|
|
|
|
* var dataSource = new DataSource('mysql', { database: 'myapp_test' });
|
|
|
|
* dataSource.define(...);
|
|
|
|
* dataSource.on('connected', function () {
|
|
|
|
* // work with database
|
|
|
|
* });
|
|
|
|
* ```
|
|
|
|
* @class DataSource
|
|
|
|
* @param {String} [name] Optional name for datasource.
|
|
|
|
* @options {Object} settings Database-specific settings to establish connection (settings depend on specific connector).
|
|
|
|
* The table below lists a typical set for a relational database.
|
|
|
|
* @property {String} connector Database connector to use. For any supported connector, can be any of:
|
|
|
|
*
|
|
|
|
* - The connector module from `require(connectorName)`.
|
|
|
|
* - The full name of the connector module, such as 'loopback-connector-oracle'.
|
|
|
|
* - The short name of the connector module, such as 'oracle'.
|
|
|
|
* - A local module under `./connectors/` folder.
|
|
|
|
* @property {String} host Database server host name.
|
|
|
|
* @property {String} port Database server port number.
|
|
|
|
* @property {String} username Database user name.
|
|
|
|
* @property {String} password Database password.
|
|
|
|
* @property {String} database Name of the database to use.
|
|
|
|
* @property {Boolean} debug Display debugging information. Default is false.
|
|
|
|
*
|
|
|
|
* The constructor allows the following styles:
|
|
|
|
*
|
|
|
|
* 1. new DataSource(dataSourceName, settings). For example:
|
|
|
|
* - new DataSource('myDataSource', {connector: 'memory'});
|
|
|
|
* - new DataSource('myDataSource', {name: 'myDataSource', connector: 'memory'});
|
|
|
|
* - new DataSource('myDataSource', {name: 'anotherDataSource', connector: 'memory'});
|
|
|
|
*
|
|
|
|
* 2. new DataSource(settings). For example:
|
|
|
|
* - new DataSource({name: 'myDataSource', connector: 'memory'});
|
|
|
|
* - new DataSource({connector: 'memory'});
|
|
|
|
*
|
|
|
|
* 3. new DataSource(connectorModule, settings). For example:
|
|
|
|
* - new DataSource(connectorModule, {name: 'myDataSource})
|
|
|
|
* - new DataSource(connectorModule)
|
|
|
|
*/
|
2018-07-24 20:48:17 +00:00
|
|
|
export declare class DataSource extends EventEmitter {
|
2018-05-02 23:21:49 +00:00
|
|
|
name: string;
|
|
|
|
settings: Options;
|
|
|
|
|
2018-05-22 17:06:50 +00:00
|
|
|
initialized?: boolean;
|
2018-05-02 23:21:49 +00:00
|
|
|
connected?: boolean;
|
|
|
|
connecting?: boolean;
|
|
|
|
|
|
|
|
connector?: Connector;
|
|
|
|
|
2020-07-18 18:54:32 +00:00
|
|
|
definitions: {[modelName: string]: ModelDefinition};
|
|
|
|
|
2018-05-02 23:21:49 +00:00
|
|
|
DataAccessObject: AnyObject & {prototype: AnyObject};
|
|
|
|
|
2018-05-10 17:19:15 +00:00
|
|
|
constructor(name: string, settings?: Options, modelBuilder?: ModelBuilder);
|
|
|
|
|
|
|
|
constructor(settings?: Options, modelBuilder?: ModelBuilder);
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
constructor(
|
|
|
|
connectorModule: Connector,
|
|
|
|
settings?: Options,
|
|
|
|
modelBuilder?: ModelBuilder,
|
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a model class
|
|
|
|
* @param name Name of the model
|
|
|
|
* @param properties An object of property definitions
|
|
|
|
* @param options Options for model settings
|
|
|
|
*/
|
|
|
|
createModel<T extends ModelBaseClass>(
|
|
|
|
name: string,
|
|
|
|
properties?: AnyObject,
|
|
|
|
options?: Options,
|
|
|
|
): T;
|
|
|
|
|
2019-09-19 16:22:08 +00:00
|
|
|
/**
|
|
|
|
* Look up a model class by name
|
|
|
|
* @param modelName Model name
|
|
|
|
* @param forceCreate A flag to force creation of a model if not found
|
|
|
|
*/
|
|
|
|
getModel(
|
|
|
|
modelName: string,
|
|
|
|
forceCreate?: boolean,
|
|
|
|
): ModelBaseClass | undefined;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
2019-07-18 14:34:27 +00:00
|
|
|
/**
|
|
|
|
* Remove a model from the registry.
|
|
|
|
*
|
|
|
|
* @param modelName
|
|
|
|
*/
|
|
|
|
deleteModelByName(modelName: string): void;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove all models from the registry, but keep the connector instance
|
|
|
|
* (including the pool of database connections).
|
|
|
|
*/
|
|
|
|
deleteAllModels(): void;
|
|
|
|
|
2018-05-02 23:21:49 +00:00
|
|
|
/**
|
|
|
|
* Attach an existing model to a data source.
|
|
|
|
* This will mixin all of the data access object functions (DAO) into your
|
|
|
|
* modelClass definition.
|
|
|
|
* @param {ModelBaseClass} modelClass The model constructor that will be enhanced
|
|
|
|
* by DataAccessObject mixins.
|
|
|
|
*/
|
|
|
|
attach(modelClass: ModelBaseClass): ModelBaseClass;
|
|
|
|
|
2020-05-12 07:36:17 +00:00
|
|
|
automigrate(models?: string | string[]): Promise<void>;
|
2019-12-05 08:51:54 +00:00
|
|
|
// legacy callback style
|
2020-05-12 07:36:17 +00:00
|
|
|
automigrate(models: string | string[] | undefined, callback: Callback): void;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
2020-05-12 07:36:17 +00:00
|
|
|
autoupdate(models?: string | string[]): Promise<void>;
|
2019-12-05 08:51:54 +00:00
|
|
|
// legacy callback style
|
2020-05-12 07:36:17 +00:00
|
|
|
autoupdate(models: string | string[] | undefined, callback: Callback): void;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
discoverModelDefinitions(
|
|
|
|
options?: Options,
|
2019-12-05 08:51:54 +00:00
|
|
|
): Promise<ModelDefinition[]>;
|
|
|
|
// legacy callback style (no options)
|
|
|
|
discoverModelDefinitions(
|
|
|
|
callback: Callback<ModelDefinition[]>,
|
|
|
|
): void;
|
|
|
|
// legacy callback style (with options)
|
|
|
|
discoverModelDefinitions(
|
|
|
|
options: Options,
|
|
|
|
callback: Callback<ModelDefinition[]>,
|
|
|
|
): void;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
discoverModelProperties(
|
|
|
|
modelName: string,
|
|
|
|
options?: Options,
|
2019-12-05 08:51:54 +00:00
|
|
|
): Promise<PropertyDefinition[]>;
|
|
|
|
// legacy callback style (no options)
|
|
|
|
discoverModelProperties(
|
|
|
|
modelName: string,
|
|
|
|
callback: Callback<PropertyDefinition[]>,
|
|
|
|
): void;
|
|
|
|
// legacy callback style (with options)
|
|
|
|
discoverModelProperties(
|
|
|
|
modelName: string,
|
|
|
|
options: Options,
|
|
|
|
callback: Callback<PropertyDefinition[]>,
|
|
|
|
): void;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
discoverPrimaryKeys(
|
|
|
|
modelName: string,
|
|
|
|
options?: Options,
|
2019-12-05 08:51:54 +00:00
|
|
|
): Promise<PropertyDefinition[]>;
|
|
|
|
// legacy callback style (no options)
|
|
|
|
discoverPrimaryKeys(
|
|
|
|
modelName: string,
|
|
|
|
callback: Callback<PropertyDefinition[]>,
|
|
|
|
): void;
|
|
|
|
// legacy callback style (with options)
|
|
|
|
discoverPrimaryKeys(
|
|
|
|
modelName: string,
|
|
|
|
options: Options,
|
|
|
|
callback: Callback<PropertyDefinition[]>,
|
|
|
|
): void;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
discoverForeignKeys(
|
|
|
|
modelName: string,
|
|
|
|
options?: Options,
|
2019-12-05 08:51:54 +00:00
|
|
|
): Promise<PropertyDefinition[]>;
|
|
|
|
// legacy callback style (no options)
|
|
|
|
discoverForeignKeys(
|
|
|
|
modelName: string,
|
|
|
|
callback: Callback<PropertyDefinition[]>,
|
|
|
|
): void;
|
2019-12-06 09:35:19 +00:00
|
|
|
// legacy callback style (with options)
|
2019-12-05 08:51:54 +00:00
|
|
|
discoverForeignKeys(
|
|
|
|
modelName: string,
|
|
|
|
options: Options,
|
|
|
|
callback: Callback<PropertyDefinition[]>,
|
|
|
|
): void;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
discoverExportedForeignKeys(
|
|
|
|
modelName: string,
|
|
|
|
options?: Options,
|
2019-12-05 08:51:54 +00:00
|
|
|
): Promise<PropertyDefinition[]>;
|
|
|
|
// legacy callback style (no options)
|
|
|
|
discoverExportedForeignKeys(
|
|
|
|
modelName: string,
|
|
|
|
callback: Callback<PropertyDefinition[]>,
|
|
|
|
): void;
|
|
|
|
// legacy callback style (with options)
|
|
|
|
discoverExportedForeignKeys(
|
|
|
|
modelName: string,
|
|
|
|
options: Options,
|
|
|
|
callback: Callback<PropertyDefinition[]>,
|
|
|
|
): void;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
discoverAndBuildModels(
|
|
|
|
modelName: string,
|
|
|
|
options?: Options,
|
2019-12-05 08:51:54 +00:00
|
|
|
): Promise<{[name: string]: ModelBaseClass}>;
|
|
|
|
// legacy callback style (no options)
|
|
|
|
discoverAndBuildModels(
|
|
|
|
modelName: string,
|
|
|
|
callback: Callback<{[name: string]: ModelBaseClass}>,
|
|
|
|
): void;
|
|
|
|
// legacy callback style (with options)
|
|
|
|
discoverAndBuildModels(
|
|
|
|
modelName: string,
|
|
|
|
options: Options,
|
|
|
|
callback: Callback<{[name: string]: ModelBaseClass}>,
|
|
|
|
): void;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
discoverSchema(
|
|
|
|
tableName: string,
|
|
|
|
options?: Options,
|
2019-12-05 08:51:54 +00:00
|
|
|
): Promise<AnyObject>;
|
|
|
|
// legacy callback style (no options)
|
|
|
|
discoverSchema(
|
|
|
|
tableName: string,
|
|
|
|
callback: Callback<AnyObject>,
|
|
|
|
): void;
|
|
|
|
// legacy callback style (with options)
|
|
|
|
discoverSchema(
|
|
|
|
tableName: string,
|
|
|
|
options: Options,
|
|
|
|
callback: Callback<AnyObject>,
|
|
|
|
): void;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
discoverSchemas(
|
|
|
|
tableName: string,
|
|
|
|
options?: Options,
|
2019-12-05 08:51:54 +00:00
|
|
|
): Promise<AnyObject[]>;
|
|
|
|
// legacy callback style (no options)
|
|
|
|
discoverSchemas(
|
|
|
|
tableName: string,
|
|
|
|
callback: Callback<AnyObject[]>,
|
|
|
|
): void;
|
|
|
|
// legacy callback style (with options)
|
|
|
|
discoverSchemas(
|
|
|
|
tableName: string,
|
|
|
|
options: Options,
|
|
|
|
callback: Callback<AnyObject[]>,
|
|
|
|
): void;
|
2018-05-02 23:21:49 +00:00
|
|
|
|
|
|
|
buildModelFromInstance(
|
|
|
|
modelName: string,
|
|
|
|
jsonObject: AnyObject,
|
|
|
|
options?: Options,
|
|
|
|
): ModelBaseClass;
|
|
|
|
|
2019-12-05 08:51:54 +00:00
|
|
|
connect(): Promise<void>;
|
|
|
|
// legacy callback style
|
|
|
|
connect(callback: Callback): void;
|
|
|
|
|
|
|
|
disconnect(): Promise<void>;
|
|
|
|
// legacy callback style
|
|
|
|
disconnect(callback: Callback): void;
|
|
|
|
|
2020-04-21 12:11:50 +00:00
|
|
|
// Only promise variant, callback is intentionally not described.
|
2020-04-28 06:23:39 +00:00
|
|
|
// Note we must use `void | PromiseLike<void>` to avoid breaking
|
|
|
|
// existing LoopBack 4 applications.
|
|
|
|
// TODO(semver-major): change the return type to `Promise<void>`
|
|
|
|
stop(): void | PromiseLike<void>;
|
2020-04-21 12:11:50 +00:00
|
|
|
|
2019-12-05 08:51:54 +00:00
|
|
|
ping(): Promise<void>;
|
|
|
|
// legacy callback style
|
|
|
|
ping(callback: Callback): void;
|
2018-12-06 12:58:47 +00:00
|
|
|
|
|
|
|
// Only promise variant, callback is intentionally not supported.
|
2020-07-27 08:09:18 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute a SQL command.
|
|
|
|
*
|
|
|
|
* **WARNING:** In general, it is always better to perform database actions
|
|
|
|
* through repository methods. Directly executing SQL may lead to unexpected
|
|
|
|
* results, corrupted data, security vulnerabilities and other issues.
|
|
|
|
*
|
|
|
|
* @example
|
|
|
|
*
|
|
|
|
* ```ts
|
|
|
|
* // MySQL
|
|
|
|
* const result = await db.execute(
|
|
|
|
* 'SELECT * FROM Products WHERE size > ?',
|
|
|
|
* [42]
|
|
|
|
* );
|
|
|
|
*
|
|
|
|
* // PostgreSQL
|
|
|
|
* const result = await db.execute(
|
|
|
|
* 'SELECT * FROM Products WHERE size > $1',
|
|
|
|
* [42]
|
|
|
|
* );
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* @param command A parameterized SQL command or query.
|
|
|
|
* Check your database documentation for information on which characters to
|
|
|
|
* use as parameter placeholders.
|
|
|
|
* @param parameters List of parameter values to use.
|
|
|
|
* @param options Additional options, for example `transaction`.
|
|
|
|
* @returns A promise which resolves to the command output as returned by the
|
|
|
|
* database driver. The output type (data structure) is database specific and
|
|
|
|
* often depends on the command executed.
|
|
|
|
*/
|
2018-12-06 12:58:47 +00:00
|
|
|
execute(
|
|
|
|
command: string | object,
|
2020-07-27 08:09:18 +00:00
|
|
|
parameters?: any[] | object,
|
2019-09-19 16:22:08 +00:00
|
|
|
options?: Options,
|
2018-12-06 12:58:47 +00:00
|
|
|
): Promise<any>;
|
2019-06-27 13:10:30 +00:00
|
|
|
|
2020-07-27 08:09:18 +00:00
|
|
|
/**
|
|
|
|
* Execute a MongoDB command.
|
|
|
|
*
|
|
|
|
* **WARNING:** In general, it is always better to perform database actions
|
|
|
|
* through repository methods. Directly executing MongoDB commands may lead
|
|
|
|
* to unexpected results and other issues.
|
|
|
|
*
|
|
|
|
* @example
|
|
|
|
*
|
|
|
|
* ```ts
|
|
|
|
* const result = await db.execute('MyCollection', 'aggregate', [
|
|
|
|
* {$lookup: {
|
|
|
|
* // ...
|
|
|
|
* }},
|
|
|
|
* {$unwind: '$data'},
|
|
|
|
* {$out: 'tempData'}
|
|
|
|
* ]);
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* @param collectionName The name of the collection to execute the command on.
|
|
|
|
* @param command The command name. See
|
|
|
|
* [Collection API docs](http://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html)
|
|
|
|
* for the list of commands supported by the MongoDB client.
|
|
|
|
* @param parameters Command parameters (arguments), as described in MongoDB API
|
|
|
|
* docs for individual collection methods.
|
|
|
|
* @returns A promise which resolves to the command output as returned by the
|
|
|
|
* database driver.
|
|
|
|
*/
|
|
|
|
execute(
|
|
|
|
collectionName: string,
|
|
|
|
command: string,
|
|
|
|
...parameters: any[],
|
|
|
|
): Promise<any>;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute a raw database command using a connector that's not described
|
|
|
|
* by LoopBack's `execute` API yet.
|
|
|
|
*
|
|
|
|
* **WARNING:** In general, it is always better to perform database actions
|
|
|
|
* through repository methods. Directly executing database commands may lead
|
|
|
|
* to unexpected results and other issues.
|
|
|
|
*
|
|
|
|
* @param args Command and parameters, please consult your connector's
|
|
|
|
* documentation to learn about supported commands and their parameters.
|
|
|
|
* @returns A promise which resolves to the command output as returned by the
|
|
|
|
* database driver.
|
|
|
|
*/
|
|
|
|
execute(...args: any[]): Promise<any>;
|
|
|
|
|
2019-09-19 16:22:08 +00:00
|
|
|
/**
|
|
|
|
* Begin a new transaction.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param [options] Options {isolationLevel: '...', timeout: 1000}
|
|
|
|
* @returns Promise A promise which resolves to a Transaction object
|
|
|
|
*/
|
|
|
|
beginTransaction(options?: IsolationLevel | Options): Promise<Transaction>;
|
2018-05-02 23:21:49 +00:00
|
|
|
}
|