mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
implemented custom repositories support
This commit is contained in:
parent
82249a4523
commit
8884789d31
@ -5,7 +5,9 @@
|
||||
* all table decorators are renamed to `Entity` (`Table` => `Entity`, `AbstractTable` => `AbstractEntity`,
|
||||
`ClassTableChild` => `ClassEntityChild`, `ClosureTable` => `ClosureEntity`, `EmbeddableTable` => `EmbeddableEntity`,
|
||||
`SingleTableChild` => `SingleEntityChild`). This change is required because upcoming versions of orm will work
|
||||
not only with tables, but also with documents and other database-specific "tables".
|
||||
not only with tables, but also with documents and other database-specific "tables".
|
||||
Previous decorator names are deprecated and will be removed in the future.
|
||||
* added custom repositories support. Example in samples directory.
|
||||
|
||||
# 0.0.6 (latest)
|
||||
|
||||
|
||||
55
sample/sample33-custom-repository/app.ts
Normal file
55
sample/sample33-custom-repository/app.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import "reflect-metadata";
|
||||
import {ConnectionOptions, createConnection} from "../../src/index";
|
||||
import {Post} from "./entity/Post";
|
||||
import {Author} from "./entity/Author";
|
||||
import {MigrationExecutor} from "../../src/migration/MigrationExecutor";
|
||||
import {PostRepository} from "./repository/PostRepository";
|
||||
import {AuthorRepository} from "./repository/AuthorRepository";
|
||||
|
||||
const options: ConnectionOptions = {
|
||||
driver: {
|
||||
type: "mysql",
|
||||
host: "localhost",
|
||||
port: 3306,
|
||||
username: "root",
|
||||
password: "admin",
|
||||
database: "test"
|
||||
},
|
||||
autoSchemaSync: true,
|
||||
logging: {
|
||||
logQueries: true,
|
||||
},
|
||||
entities: [Post, Author],
|
||||
};
|
||||
|
||||
createConnection(options).then(async connection => {
|
||||
|
||||
const post = connection
|
||||
.getCustomRepository(PostRepository)
|
||||
.create();
|
||||
|
||||
post.title = "Hello Repositories!";
|
||||
|
||||
await connection
|
||||
.entityManager
|
||||
.getCustomRepository(PostRepository)
|
||||
.persist(post);
|
||||
|
||||
const loadedPost = await connection
|
||||
.entityManager
|
||||
.getCustomRepository(PostRepository)
|
||||
.findMyPost();
|
||||
|
||||
console.log("Post persisted! Loaded post: ", loadedPost);
|
||||
|
||||
const author = await connection
|
||||
.getCustomRepository(AuthorRepository)
|
||||
.createAndSave("Umed", "Khudoiberdiev");
|
||||
|
||||
const loadedAuthor = await connection
|
||||
.getCustomRepository(AuthorRepository)
|
||||
.findMyAuthor();
|
||||
|
||||
console.log("Author persisted! Loaded author: ", loadedAuthor);
|
||||
|
||||
}).catch(error => console.log("Error: ", error));
|
||||
15
sample/sample33-custom-repository/entity/Author.ts
Normal file
15
sample/sample33-custom-repository/entity/Author.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import {PrimaryGeneratedColumn, Column, Entity} from "../../../src/index";
|
||||
|
||||
@Entity()
|
||||
export class Author {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
firstName: string;
|
||||
|
||||
@Column()
|
||||
lastName: string;
|
||||
|
||||
}
|
||||
18
sample/sample33-custom-repository/entity/Post.ts
Normal file
18
sample/sample33-custom-repository/entity/Post.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import {PrimaryGeneratedColumn, Column, Entity, ManyToOne} from "../../../src/index";
|
||||
import {Author} from "./Author";
|
||||
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@ManyToOne(type => Author, {
|
||||
cascadeInsert: true
|
||||
})
|
||||
author: Author;
|
||||
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
import {EntityRepository} from "../../../src/decorator/EntityRepository";
|
||||
import {AbstractRepository} from "../../../src/repository/AbstractRepository";
|
||||
import {Author} from "../entity/Author";
|
||||
|
||||
/**
|
||||
* Second type of custom repository - extends abstract repository (also can not extend anything).
|
||||
*/
|
||||
@EntityRepository(Author)
|
||||
export class AuthorRepository extends AbstractRepository<Author> {
|
||||
|
||||
createAndSave(firstName: string, lastName: string) {
|
||||
const author = new Author();
|
||||
author.firstName = firstName;
|
||||
author.lastName = lastName;
|
||||
|
||||
return this.entityManager.persist(author);
|
||||
}
|
||||
|
||||
findMyAuthor() {
|
||||
return this
|
||||
.createQueryBuilder("author")
|
||||
.getOne();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
import {Repository} from "../../../src/repository/Repository";
|
||||
import {Post} from "../entity/Post";
|
||||
import {EntityRepository} from "../../../src/decorator/EntityRepository";
|
||||
|
||||
/**
|
||||
* First type of custom repository - extends standard repository.
|
||||
*/
|
||||
@EntityRepository(Post)
|
||||
export class PostRepository extends Repository<Post> {
|
||||
|
||||
findMyPost() {
|
||||
return this.findOne();
|
||||
}
|
||||
|
||||
}
|
||||
@ -32,6 +32,10 @@ import {MigrationInterface} from "../migration/MigrationInterface";
|
||||
import {MigrationExecutor} from "../migration/MigrationExecutor";
|
||||
import {CannotRunMigrationNotConnectedError} from "./error/CannotRunMigrationNotConnectedError";
|
||||
import {PlatformTools} from "../platform/PlatformTools";
|
||||
import {AbstractRepository} from "../repository/AbstractRepository";
|
||||
import {CustomRepositoryNotFoundError} from "../repository/error/CustomRepositoryNotFoundError";
|
||||
import {CustomRepositoryReusedError} from "../repository/error/CustomRepositoryReusedError";
|
||||
import {CustomRepositoryCannotInheritRepositoryError} from "../repository/error/CustomRepositoryCannotInheritRepositoryError";
|
||||
|
||||
/**
|
||||
* Connection is a single database connection to a specific database of a database management system.
|
||||
@ -82,6 +86,11 @@ export class Connection {
|
||||
*/
|
||||
private readonly repositoryAggregators: RepositoryAggregator[] = [];
|
||||
|
||||
/**
|
||||
* Stores all entity repository instances.
|
||||
*/
|
||||
private readonly entityRepositories: Object[] = [];
|
||||
|
||||
/**
|
||||
* Entity listeners that are registered for this connection.
|
||||
*/
|
||||
@ -427,6 +436,13 @@ export class Connection {
|
||||
*/
|
||||
getTreeRepository<Entity>(entityClass: ObjectType<Entity>): TreeRepository<Entity>;
|
||||
|
||||
/**
|
||||
* Gets tree repository for the given entity class.
|
||||
* Only tree-type entities can have a TreeRepository,
|
||||
* like ones decorated with @ClosureTable decorator.
|
||||
*/
|
||||
getTreeRepository<Entity>(entityClassOrName: ObjectType<Entity>|string): TreeRepository<Entity>;
|
||||
|
||||
/**
|
||||
* Gets tree repository for the given entity class.
|
||||
* Only tree-type entities can have a TreeRepository,
|
||||
@ -497,6 +513,73 @@ export class Connection {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets custom entity repository marked with @EntityRepository decorator.
|
||||
*/
|
||||
getCustomRepository<T>(customRepository: ObjectType<T>): T {
|
||||
const entityRepositoryMetadataArgs = getMetadataArgsStorage().entityRepositories.toArray().find(repository => {
|
||||
return repository.target === (customRepository instanceof Function ? customRepository : (customRepository as any).constructor);
|
||||
});
|
||||
if (!entityRepositoryMetadataArgs)
|
||||
throw new CustomRepositoryNotFoundError(customRepository);
|
||||
|
||||
let entityRepositoryInstance: any = this.entityRepositories.find(entityRepository => entityRepository.constructor === customRepository);
|
||||
if (!entityRepositoryInstance) {
|
||||
if (entityRepositoryMetadataArgs.useContainer) {
|
||||
entityRepositoryInstance = getFromContainer(entityRepositoryMetadataArgs.target);
|
||||
|
||||
// if we get custom entity repository from container then there is a risk that it already was used
|
||||
// in some different connection. If it was used there then we check it and throw an exception
|
||||
// because we cant override its connection there again
|
||||
|
||||
if (entityRepositoryInstance instanceof AbstractRepository || entityRepositoryInstance instanceof Repository) {
|
||||
// NOTE: dynamic access to protected properties. We need this to prevent unwanted properties in those classes to be exposed,
|
||||
// however we need these properties for internal work of the class
|
||||
if ((entityRepositoryInstance as any)["connection"] && (entityRepositoryInstance as any)["connection"] !== this)
|
||||
throw new CustomRepositoryReusedError(customRepository);
|
||||
}
|
||||
|
||||
} else {
|
||||
entityRepositoryInstance = new (entityRepositoryMetadataArgs.target as any)();
|
||||
}
|
||||
|
||||
if (entityRepositoryInstance instanceof AbstractRepository) {
|
||||
// NOTE: dynamic access to protected properties. We need this to prevent unwanted properties in those classes to be exposed,
|
||||
// however we need these properties for internal work of the class
|
||||
if (!(entityRepositoryInstance as any)["connection"])
|
||||
(entityRepositoryInstance as any)["connection"] = this;
|
||||
}
|
||||
if (entityRepositoryInstance instanceof Repository) {
|
||||
if (!entityRepositoryMetadataArgs.entity)
|
||||
throw new CustomRepositoryCannotInheritRepositoryError(customRepository);
|
||||
|
||||
// NOTE: dynamic access to protected properties. We need this to prevent unwanted properties in those classes to be exposed,
|
||||
// however we need these properties for internal work of the class
|
||||
(entityRepositoryInstance as any)["connection"] = this;
|
||||
(entityRepositoryInstance as any)["metadata"] = this.getMetadata(entityRepositoryMetadataArgs.entity);
|
||||
}
|
||||
|
||||
// register entity repository
|
||||
this.entityRepositories.push(entityRepositoryInstance);
|
||||
}
|
||||
|
||||
return entityRepositoryInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets custom repository's managed entity.
|
||||
* If given custom repository does not manage any entity then undefined will be returned.
|
||||
*/
|
||||
getCustomRepositoryTarget<T>(customRepository: any): Function|string|undefined {
|
||||
const entityRepositoryMetadataArgs = getMetadataArgsStorage().entityRepositories.toArray().find(repository => {
|
||||
return repository.target === (customRepository instanceof Function ? customRepository : (customRepository as any).constructor);
|
||||
});
|
||||
if (!entityRepositoryMetadataArgs)
|
||||
throw new CustomRepositoryNotFoundError(customRepository);
|
||||
|
||||
return entityRepositoryMetadataArgs.entity;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
@ -630,4 +713,5 @@ export class Connection {
|
||||
protected createLazyRelationsWrapper() {
|
||||
return new LazyRelationsWrapper(this);
|
||||
}
|
||||
|
||||
}
|
||||
34
src/decorator/EntityRepository.ts
Normal file
34
src/decorator/EntityRepository.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import {getMetadataArgsStorage} from "../index";
|
||||
import {EntityRepositoryMetadataArgs} from "../metadata-args/EntityRepositoryMetadataArgs";
|
||||
|
||||
/**
|
||||
* Used to declare a class as a custom repository.
|
||||
* Custom repository can either manage some specific entity, either just be generic.
|
||||
* Custom repository can extend AbstractRepository or regular Repository or TreeRepository.
|
||||
*/
|
||||
export function EntityRepository(entity?: Function, options?: { useContainer?: boolean }): Function;
|
||||
|
||||
/**
|
||||
* Used to declare a class as a custom repository.
|
||||
* Custom repository can either manage some specific entity, either just be generic.
|
||||
* Custom repository can extend AbstractRepository or regular Repository or TreeRepository.
|
||||
*/
|
||||
export function EntityRepository(options?: { useContainer?: boolean }): Function;
|
||||
|
||||
/**
|
||||
* Used to declare a class as a custom repository.
|
||||
* Custom repository can either manage some specific entity, either just be generic.
|
||||
* Custom repository can extend AbstractRepository or regular Repository or TreeRepository.
|
||||
*/
|
||||
export function EntityRepository(entityOrOptions?: Function|{ useContainer?: boolean }, maybeOptions?: { useContainer?: boolean }): Function {
|
||||
const entity = entityOrOptions instanceof Function ? entityOrOptions as Function : undefined;
|
||||
const options = entityOrOptions instanceof Function ? maybeOptions : entityOrOptions as { useContainer?: boolean };
|
||||
return function (target: Function) {
|
||||
const args: EntityRepositoryMetadataArgs = {
|
||||
target: target,
|
||||
entity: entity,
|
||||
useContainer: !!(options && options.useContainer)
|
||||
};
|
||||
getMetadataArgsStorage().entityRepositories.add(args);
|
||||
};
|
||||
}
|
||||
@ -140,6 +140,13 @@ export abstract class BaseEntityManager {
|
||||
return this.connection.getSpecificRepository<Entity>(entityClassOrName as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets custom entity repository marked with @EntityRepository decorator.
|
||||
*/
|
||||
getCustomRepository<T>(customRepository: ObjectType<T>): T {
|
||||
return this.connection.getCustomRepository<T>(customRepository);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if entity has an id.
|
||||
*/
|
||||
|
||||
22
src/metadata-args/EntityRepositoryMetadataArgs.ts
Normal file
22
src/metadata-args/EntityRepositoryMetadataArgs.ts
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Arguments for EntityRepositoryMetadata class, helps to construct an EntityRepositoryMetadata object.
|
||||
*/
|
||||
export interface EntityRepositoryMetadataArgs {
|
||||
|
||||
/**
|
||||
* Constructor of the custom entity repository.
|
||||
*/
|
||||
readonly target: Function;
|
||||
|
||||
/**
|
||||
* Entity managed by this custom repository.
|
||||
*/
|
||||
readonly entity?: Function|string;
|
||||
|
||||
/**
|
||||
* Indicates if entity repository will be retrieved from the service container.
|
||||
* Note: this may cause problems if you are sharing entity repositories between using multiple connections.
|
||||
*/
|
||||
readonly useContainer: boolean;
|
||||
|
||||
}
|
||||
@ -14,6 +14,7 @@ import {EntitySubscriberMetadataArgs} from "./EntitySubscriberMetadataArgs";
|
||||
import {RelationIdMetadataArgs} from "./RelationIdMetadataArgs";
|
||||
import {InheritanceMetadataArgs} from "./InheritanceMetadataArgs";
|
||||
import {DiscriminatorValueMetadataArgs} from "./DiscriminatorValueMetadataArgs";
|
||||
import {EntityRepositoryMetadataArgs} from "./EntityRepositoryMetadataArgs";
|
||||
|
||||
/**
|
||||
* Storage all metadatas of all available types: tables, fields, subscribers, relations, etc.
|
||||
@ -31,6 +32,7 @@ export class MetadataArgsStorage {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
readonly tables = new TargetMetadataArgsCollection<TableMetadataArgs>();
|
||||
readonly entityRepositories = new TargetMetadataArgsCollection<EntityRepositoryMetadataArgs>();
|
||||
readonly namingStrategies = new TargetMetadataArgsCollection<NamingStrategyMetadataArgs>();
|
||||
readonly entitySubscribers = new TargetMetadataArgsCollection<EntitySubscriberMetadataArgs>();
|
||||
readonly indices = new TargetMetadataArgsCollection<IndexMetadataArgs>();
|
||||
|
||||
120
src/repository/AbstractRepository.ts
Normal file
120
src/repository/AbstractRepository.ts
Normal file
@ -0,0 +1,120 @@
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {QueryBuilder} from "../query-builder/QueryBuilder";
|
||||
import {ObjectLiteral} from "../common/ObjectLiteral";
|
||||
import {EntityManager} from "../entity-manager/EntityManager";
|
||||
import {Repository} from "./Repository";
|
||||
import {TreeRepository} from "./TreeRepository";
|
||||
import {SpecificRepository} from "./SpecificRepository";
|
||||
import {ObjectType} from "../common/ObjectType";
|
||||
import {CustomRepositoryDoesNotHaveEntityError} from "./error/CustomRepositoryDoesNotHaveEntityError";
|
||||
|
||||
/**
|
||||
* Provides abstract class for custom repositories that do not inherit from original orm Repository.
|
||||
* Contains all most-necessary methods to simplify code in the custom repository.
|
||||
* All methods are protected thus not exposed and it allows to create encapsulated custom repository.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export class AbstractRepository<Entity extends ObjectLiteral> {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods Set Dynamically
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Connection used by this repository.
|
||||
*/
|
||||
protected connection: Connection;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Accessors
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets entity manager that allows to perform repository operations with any entity.
|
||||
*/
|
||||
protected get entityManager(): EntityManager {
|
||||
return this.connection.entityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original ORM repository for the entity that is managed by this repository.
|
||||
* If current repository does not manage any entity, then exception will be thrown.
|
||||
*/
|
||||
protected get repository(): Repository<Entity> {
|
||||
const target = this.connection.getCustomRepositoryTarget(this as any);
|
||||
if (!target)
|
||||
throw new CustomRepositoryDoesNotHaveEntityError(this.constructor);
|
||||
|
||||
return this.connection.getRepository<Entity>(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original ORM tree repository for the entity that is managed by this repository.
|
||||
* If current repository does not manage any entity, then exception will be thrown.
|
||||
*/
|
||||
protected get treeRepository(): TreeRepository<Entity> {
|
||||
const target = this.connection.getCustomRepositoryTarget(this as any);
|
||||
if (!target)
|
||||
throw new CustomRepositoryDoesNotHaveEntityError(this.constructor);
|
||||
|
||||
return this.connection.getTreeRepository<Entity>(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original ORM specific repository for the entity that is managed by this repository.
|
||||
* If current repository does not manage any entity, then exception will be thrown.
|
||||
*/
|
||||
protected get specificRepository(): SpecificRepository<Entity> {
|
||||
const target = this.connection.getCustomRepositoryTarget(this as any);
|
||||
if (!target)
|
||||
throw new CustomRepositoryDoesNotHaveEntityError(this.constructor);
|
||||
|
||||
return this.connection.getSpecificRepository<Entity>(target);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates a new query builder for the repository's entity that can be used to build a sql query.
|
||||
* If current repository does not manage any entity, then exception will be thrown.
|
||||
*/
|
||||
protected createQueryBuilder(alias: string): QueryBuilder<Entity> {
|
||||
const target = this.connection.getCustomRepositoryTarget(this.constructor);
|
||||
if (!target)
|
||||
throw new CustomRepositoryDoesNotHaveEntityError(this.constructor);
|
||||
|
||||
return this.connection.getRepository(target).createQueryBuilder(alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new query builder for the given entity that can be used to build a sql query.
|
||||
*/
|
||||
protected createQueryBuilderFor<T>(entity: ObjectType<T>, alias: string): QueryBuilder<T> {
|
||||
return this.getRepositoryFor(entity).createQueryBuilder(alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original ORM repository for the given entity class.
|
||||
*/
|
||||
protected getRepositoryFor<T>(entity: ObjectType<T>): Repository<T> {
|
||||
return this.entityManager.getRepository(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original ORM tree repository for the given entity class.
|
||||
*/
|
||||
protected getTreeRepositoryFor<T>(entity: ObjectType<T>): TreeRepository<T> {
|
||||
return this.entityManager.getTreeRepository(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original ORM specific repository for the given entity class.
|
||||
*/
|
||||
protected getSpecificRepositoryFor<T>(entity: ObjectType<T>): SpecificRepository<T> {
|
||||
return this.entityManager.getSpecificRepository(entity);
|
||||
}
|
||||
|
||||
}
|
||||
@ -16,13 +16,23 @@ import {SubjectBuilder} from "../persistence/SubjectBuilder";
|
||||
export class Repository<Entity extends ObjectLiteral> {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// Protected Methods Set Dynamically
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(protected connection: Connection,
|
||||
protected metadata: EntityMetadata,
|
||||
protected queryRunnerProvider?: QueryRunnerProvider) {
|
||||
}
|
||||
/**
|
||||
* Connection used by this repository.
|
||||
*/
|
||||
protected connection: Connection;
|
||||
|
||||
/**
|
||||
* Entity metadata of the entity current repository manages.
|
||||
*/
|
||||
protected metadata: EntityMetadata;
|
||||
|
||||
/**
|
||||
* Query runner provider used for this repository.
|
||||
*/
|
||||
protected queryRunnerProvider?: QueryRunnerProvider;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
@ -317,7 +327,14 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
async transaction(runInTransaction: (repository: Repository<Entity>) => Promise<any>|any): Promise<any> {
|
||||
const queryRunnerProvider = this.queryRunnerProvider || new QueryRunnerProvider(this.connection.driver, true);
|
||||
const queryRunner = await queryRunnerProvider.provide();
|
||||
const transactionRepository = new Repository<Entity>(this.connection, this.metadata, queryRunnerProvider);
|
||||
|
||||
// NOTE: dynamic access to protected properties. We need this to prevent unwanted properties in those classes to be exposed,
|
||||
// however we need these properties for internal work of the class
|
||||
const transactionRepository = new Repository<any>();
|
||||
(transactionRepository as any)["connection"] = this.connection;
|
||||
(transactionRepository as any)["metadata"] = this.metadata;
|
||||
(transactionRepository as any)["queryRunnerProvider"] = queryRunnerProvider;
|
||||
// todo: same code in the repository factory. probably better to use repository factory here too
|
||||
|
||||
try {
|
||||
await queryRunner.beginTransaction();
|
||||
|
||||
@ -18,14 +18,28 @@ export class RepositoryFactory {
|
||||
* Creates a regular repository.
|
||||
*/
|
||||
createRepository(connection: Connection, metadata: EntityMetadata, queryRunnerProvider?: QueryRunnerProvider): Repository<any> {
|
||||
return new Repository<any>(connection, metadata, queryRunnerProvider);
|
||||
|
||||
// NOTE: dynamic access to protected properties. We need this to prevent unwanted properties in those classes to be exposed,
|
||||
// however we need these properties for internal work of the class
|
||||
const repository = new Repository<any>();
|
||||
(repository as any)["connection"] = connection;
|
||||
(repository as any)["metadata"] = metadata;
|
||||
(repository as any)["queryRunnerProvider"] = queryRunnerProvider;
|
||||
return repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a tree repository.
|
||||
*/
|
||||
createTreeRepository(connection: Connection, metadata: EntityMetadata, queryRunnerProvider?: QueryRunnerProvider): TreeRepository<any> {
|
||||
return new TreeRepository<any>(connection, metadata, queryRunnerProvider);
|
||||
|
||||
// NOTE: dynamic access to protected properties. We need this to prevent unwanted properties in those classes to be exposed,
|
||||
// however we need these properties for internal work of the class
|
||||
const repository = new TreeRepository<any>();
|
||||
(repository as any)["connection"] = connection;
|
||||
(repository as any)["metadata"] = metadata;
|
||||
(repository as any)["queryRunnerProvider"] = queryRunnerProvider;
|
||||
return repository;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Thrown if custom repository inherits Repository class however entity is not set in @EntityRepository decorator.
|
||||
*/
|
||||
export class CustomRepositoryCannotInheritRepositoryError extends Error {
|
||||
name = "CustomRepositoryCannotInheritRepositoryError";
|
||||
|
||||
constructor(repository: any) {
|
||||
super(`Custom entity repository ${repository instanceof Function ? repository.name : repository.constructor.name} ` +
|
||||
` cannot inherit Repository class without entity being set in the @EntityRepository decorator.`);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Thrown if custom repositories that extend AbstractRepository classes does not have managed entity.
|
||||
*/
|
||||
export class CustomRepositoryDoesNotHaveEntityError extends Error {
|
||||
name = "CustomRepositoryDoesNotHaveEntityError";
|
||||
|
||||
constructor(repository: any) {
|
||||
super(`Custom repository ${repository instanceof Function ? repository.name : repository.constructor.name} does not have managed entity. ` +
|
||||
`Did you forget to specify entity for it @EntityRepository(MyEntity)? `);
|
||||
}
|
||||
|
||||
}
|
||||
13
src/repository/error/CustomRepositoryNotFoundError.ts
Normal file
13
src/repository/error/CustomRepositoryNotFoundError.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Thrown if custom repository was not found.
|
||||
*/
|
||||
export class CustomRepositoryNotFoundError extends Error {
|
||||
name = "CustomRepositoryNotFoundError";
|
||||
|
||||
constructor(repository: any) {
|
||||
super();
|
||||
this.message = `Custom repository ${repository instanceof Function ? repository.name : repository.constructor.name } was not found. ` +
|
||||
`Did you forgot to put @EntityRepository decorator on it?`;
|
||||
}
|
||||
|
||||
}
|
||||
13
src/repository/error/CustomRepositoryReusedError.ts
Normal file
13
src/repository/error/CustomRepositoryReusedError.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Thrown if same custom repository instance is reused between different connections.
|
||||
*/
|
||||
export class CustomRepositoryReusedError extends Error {
|
||||
name = "CustomRepositoryReusedError";
|
||||
|
||||
constructor(repository: any) {
|
||||
super(`Custom entity repository ${repository instanceof Function ? repository.name : repository.constructor.name} ` +
|
||||
`was already used in the different connection. You can't share entity repositories between different connections ` +
|
||||
`when useContainer is set to true for the entity repository.`);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user