@loopback/repository
Version:
Define and implement a common set of interfaces for interacting with databases
333 lines (332 loc) • 15.9 kB
TypeScript
import { Getter } from '@loopback/core';
import { Filter, FilterExcludingWhere, InclusionFilter, Where } from '@loopback/filter';
import legacy from 'loopback-datasource-juggler';
import { AnyObject, Command, Count, DataObject, NamedParameters, Options, PositionalParameters } from '../common-types';
import { Entity, Model } from '../model';
import { BelongsToAccessor, HasManyRepositoryFactory, HasManyThroughRepositoryFactory, HasOneRepositoryFactory, InclusionResolver, ReferencesManyAccessor } from '../relations';
import { IsolationLevel, Transaction } from '../transaction';
import { EntityCrudRepository, TransactionalEntityRepository } from './repository';
export declare namespace juggler {
export import DataSource = legacy.DataSource;
export import ModelBase = legacy.ModelBase;
export import ModelBaseClass = legacy.ModelBaseClass;
export import PersistedModel = legacy.PersistedModel;
export import KeyValueModel = legacy.KeyValueModel;
export import PersistedModelClass = legacy.PersistedModelClass;
export import Transaction = legacy.Transaction;
export import IsolationLevel = legacy.IsolationLevel;
}
/**
* This is a bridge to the legacy DAO class. The function mixes DAO methods
* into a model class and attach it to a given data source
* @param modelClass - Model class
* @param ds - Data source
* @returns {} The new model class with DAO (CRUD) operations
*/
export declare function bindModel<T extends juggler.ModelBaseClass>(modelClass: T, ds: juggler.DataSource): T;
/**
* Ensure the value is a promise
* @param p - Promise or void
*/
export declare function ensurePromise<T>(p: legacy.PromiseOrVoid<T>): Promise<T>;
/**
* Default implementation of CRUD repository using legacy juggler model
* and data source
*/
export declare class DefaultCrudRepository<T extends Entity, ID, Relations extends object = {}> implements EntityCrudRepository<T, ID, Relations> {
entityClass: typeof Entity & {
prototype: T;
};
dataSource: juggler.DataSource;
modelClass: juggler.PersistedModelClass;
readonly inclusionResolvers: Map<string, InclusionResolver<T, Entity>>;
/**
* Constructor of DefaultCrudRepository
* @param entityClass - LoopBack 4 entity class
* @param dataSource - Legacy juggler data source
*/
constructor(entityClass: typeof Entity & {
prototype: T;
}, dataSource: juggler.DataSource);
private ensurePersistedModel;
/**
* Creates a legacy persisted model class, attaches it to the datasource and
* returns it. This method can be overridden in sub-classes to acess methods
* and properties in the generated model class.
* @param entityClass - LB4 Entity constructor
*/
protected definePersistedModel(entityClass: typeof Model): typeof juggler.PersistedModel;
private resolvePropertyType;
/**
* @deprecated
* Function to create a constrained relation repository factory
*
* Use `this.createHasManyRepositoryFactoryFor()` instead
*
* @param relationName - Name of the relation defined on the source model
* @param targetRepo - Target repository instance
*/
protected _createHasManyRepositoryFactoryFor<Target extends Entity, TargetID, ForeignKeyType>(relationName: string, targetRepositoryGetter: Getter<EntityCrudRepository<Target, TargetID>>): HasManyRepositoryFactory<Target, ForeignKeyType>;
/**
* Function to create a constrained relation repository factory
*
* @example
* ```ts
* class CustomerRepository extends DefaultCrudRepository<
* Customer,
* typeof Customer.prototype.id,
* CustomerRelations
* > {
* public readonly orders: HasManyRepositoryFactory<Order, typeof Customer.prototype.id>;
*
* constructor(
* protected db: juggler.DataSource,
* orderRepository: EntityCrudRepository<Order, typeof Order.prototype.id>,
* ) {
* super(Customer, db);
* this.orders = this._createHasManyRepositoryFactoryFor(
* 'orders',
* orderRepository,
* );
* }
* }
* ```
*
* @param relationName - Name of the relation defined on the source model
* @param targetRepo - Target repository instance
*/
protected createHasManyRepositoryFactoryFor<Target extends Entity, TargetID, ForeignKeyType>(relationName: string, targetRepositoryGetter: Getter<EntityCrudRepository<Target, TargetID>>): HasManyRepositoryFactory<Target, ForeignKeyType>;
/**
* Function to create a constrained hasManyThrough relation repository factory
*
* @example
* ```ts
* class CustomerRepository extends DefaultCrudRepository<
* Customer,
* typeof Customer.prototype.id,
* CustomerRelations
* > {
* public readonly cartItems: HasManyRepositoryFactory<CartItem, typeof Customer.prototype.id>;
*
* constructor(
* protected db: juggler.DataSource,
* cartItemRepository: EntityCrudRepository<CartItem, typeof, CartItem.prototype.id>,
* throughRepository: EntityCrudRepository<Through, typeof Through.prototype.id>,
* ) {
* super(Customer, db);
* this.cartItems = this.createHasManyThroughRepositoryFactoryFor(
* 'cartItems',
* cartItemRepository,
* );
* }
* }
* ```
*
* @param relationName - Name of the relation defined on the source model
* @param targetRepo - Target repository instance
* @param throughRepo - Through repository instance
*/
protected createHasManyThroughRepositoryFactoryFor<Target extends Entity, TargetID, Through extends Entity, ThroughID, ForeignKeyType>(relationName: string, targetRepositoryGetter: Getter<EntityCrudRepository<Target, TargetID>> | {
[repoType: string]: Getter<EntityCrudRepository<Target, TargetID>>;
}, throughRepositoryGetter: Getter<EntityCrudRepository<Through, ThroughID>>): HasManyThroughRepositoryFactory<Target, TargetID, Through, ForeignKeyType>;
/**
* @deprecated
* Function to create a belongs to accessor
*
* Use `this.createBelongsToAccessorFor()` instead
*
* @param relationName - Name of the relation defined on the source model
* @param targetRepo - Target repository instance
*/
protected _createBelongsToAccessorFor<Target extends Entity, TargetId>(relationName: string, targetRepositoryGetter: Getter<EntityCrudRepository<Target, TargetId>> | {
[repoType: string]: Getter<EntityCrudRepository<Target, TargetId>>;
}): BelongsToAccessor<Target, ID>;
/**
* Function to create a belongs to accessor
*
* @param relationName - Name of the relation defined on the source model
* @param targetRepo - Target repository instance
*/
protected createBelongsToAccessorFor<Target extends Entity, TargetId>(relationName: string, targetRepositoryGetter: Getter<EntityCrudRepository<Target, TargetId>> | {
[repoType: string]: Getter<EntityCrudRepository<Target, TargetId>>;
}): BelongsToAccessor<Target, ID>;
/**
* @deprecated
* Function to create a constrained hasOne relation repository factory
*
* @param relationName - Name of the relation defined on the source model
* @param targetRepo - Target repository instance
*/
protected _createHasOneRepositoryFactoryFor<Target extends Entity, TargetID, ForeignKeyType>(relationName: string, targetRepositoryGetter: Getter<EntityCrudRepository<Target, TargetID>> | {
[repoType: string]: Getter<EntityCrudRepository<Target, TargetID>>;
}): HasOneRepositoryFactory<Target, ForeignKeyType>;
/**
* Function to create a constrained hasOne relation repository factory
*
* @param relationName - Name of the relation defined on the source model
* @param targetRepo - Target repository instance
*/
protected createHasOneRepositoryFactoryFor<Target extends Entity, TargetID, ForeignKeyType>(relationName: string, targetRepositoryGetter: Getter<EntityCrudRepository<Target, TargetID>> | {
[repoType: string]: Getter<EntityCrudRepository<Target, TargetID>>;
}): HasOneRepositoryFactory<Target, ForeignKeyType>;
/**
* @deprecated
* Function to create a references many accessor
*
* Use `this.createReferencesManyAccessorFor()` instead
*
* @param relationName - Name of the relation defined on the source model
* @param targetRepo - Target repository instance
*/
protected _createReferencesManyAccessorFor<Target extends Entity, TargetId>(relationName: string, targetRepoGetter: Getter<EntityCrudRepository<Target, TargetId>>): ReferencesManyAccessor<Target, ID>;
/**
* Function to create a references many accessor
*
* @param relationName - Name of the relation defined on the source model
* @param targetRepo - Target repository instance
*/
protected createReferencesManyAccessorFor<Target extends Entity, TargetId>(relationName: string, targetRepoGetter: Getter<EntityCrudRepository<Target, TargetId>>): ReferencesManyAccessor<Target, ID>;
create(entity: DataObject<T>, options?: Options): Promise<T>;
createAll(entities: DataObject<T>[], options?: Options): Promise<T[]>;
save(entity: T, options?: Options): Promise<T>;
find(filter?: Filter<T>, options?: Options): Promise<(T & Relations)[]>;
findOne(filter?: Filter<T>, options?: Options): Promise<(T & Relations) | null>;
findById(id: ID, filter?: FilterExcludingWhere<T>, options?: Options): Promise<T & Relations>;
update(entity: T, options?: Options): Promise<void>;
delete(entity: T, options?: Options): Promise<void>;
updateAll(data: DataObject<T>, where?: Where<T>, options?: Options): Promise<Count>;
updateById(id: ID, data: DataObject<T>, options?: Options): Promise<void>;
replaceById(id: ID, data: DataObject<T>, options?: Options): Promise<void>;
deleteAll(where?: Where<T>, options?: Options): Promise<Count>;
deleteById(id: ID, options?: Options): Promise<void>;
count(where?: Where<T>, options?: Options): Promise<Count>;
exists(id: ID, options?: Options): Promise<boolean>;
/**
* 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 repo.execute(
* 'SELECT * FROM Products WHERE size > ?',
* [42]
* );
*
* // PostgreSQL
* const result = await repo.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.
*/
execute(command: Command, parameters: NamedParameters | PositionalParameters, options?: Options): Promise<AnyObject>;
/**
* 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 repo.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: PositionalParameters): Promise<AnyObject>;
/**
* 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: PositionalParameters): Promise<AnyObject>;
protected toEntity<R extends T>(model: juggler.PersistedModel): R;
protected toEntities<R extends T>(models: juggler.PersistedModel[]): R[];
/**
* Register an inclusion resolver for the related model name.
*
* @param relationName - Name of the relation defined on the source model
* @param resolver - Resolver function for getting related model entities
*/
registerInclusionResolver(relationName: string, resolver: InclusionResolver<T, Entity>): void;
/**
* Returns model instances that include related models of this repository
* that have a registered resolver.
*
* @param entities - An array of entity instances or data
* @param include -Inclusion filter
* @param options - Options for the operations
*/
protected includeRelatedModels(entities: T[], include?: InclusionFilter[], options?: Options): Promise<(T & Relations)[]>;
/**
* This function works as a persist hook.
* It converts an entity from the CRUD operations' caller
* to a persistable data that can will be stored in the
* back-end database.
*
* User can extend `DefaultCrudRepository` then override this
* function to execute custom persist hook.
* @param entity The entity passed from CRUD operations' caller.
* @param options
*/
protected entityToData<R extends T>(entity: R | DataObject<R>, options?: {}): legacy.ModelData<legacy.PersistedModel>;
/** Converts an entity object to a JSON object to check if it contains navigational property.
* Throws an error if `entity` contains navigational property.
*
* @param entity The entity passed from CRUD operations' caller.
* @param options
*/
protected ensurePersistable<R extends T>(entity: R | DataObject<R>, options?: {}): legacy.ModelData<legacy.PersistedModel>;
/**
* Removes juggler's "include" filter as it does not apply to LoopBack 4
* relations.
*
* @param filter - Query filter
*/
protected normalizeFilter(filter?: Filter<T>): legacy.Filter | undefined;
}
/**
* Default implementation of CRUD repository using legacy juggler model
* and data source with beginTransaction() method for connectors which
* support Transactions
*/
export declare class DefaultTransactionalRepository<T extends Entity, ID, Relations extends object = {}> extends DefaultCrudRepository<T, ID, Relations> implements TransactionalEntityRepository<T, ID, Relations> {
beginTransaction(options?: IsolationLevel | Options): Promise<Transaction>;
}