added third custom repository support

This commit is contained in:
Umed Khudoiberdiev 2017-05-19 19:07:20 +05:00
parent 3baa57be3e
commit 4f31158576
7 changed files with 96 additions and 43 deletions

View File

@ -5,6 +5,8 @@ import {Author} from "./entity/Author";
import {MigrationExecutor} from "../../src/migration/MigrationExecutor";
import {PostRepository} from "./repository/PostRepository";
import {AuthorRepository} from "./repository/AuthorRepository";
import {UserRepository} from "./repository/UserRepository";
import {User} from "./entity/User";
const options: ConnectionOptions = {
driver: {
@ -19,11 +21,25 @@ const options: ConnectionOptions = {
logging: {
logQueries: true,
},
entities: [Post, Author],
entities: [Post, Author, User],
};
createConnection(options).then(async connection => {
// first type of custom repository
const author = await connection
.getCustomRepository(AuthorRepository)
.createAndSave("Umed", "Khudoiberdiev");
const loadedAuthor = await connection
.getCustomRepository(AuthorRepository)
.findMyAuthor();
console.log("Author persisted! Loaded author: ", loadedAuthor);
// second type of custom repository
const post = connection
.getCustomRepository(PostRepository)
.create();
@ -42,14 +58,13 @@ createConnection(options).then(async connection => {
console.log("Post persisted! Loaded post: ", loadedPost);
const author = await connection
.getCustomRepository(AuthorRepository)
.createAndSave("Umed", "Khudoiberdiev");
// third type of custom repository
const loadedAuthor = await connection
.getCustomRepository(AuthorRepository)
.findMyAuthor();
const userRepository = connection.manager.getCustomRepository(UserRepository);
await userRepository.createAndSave("Umed", "Khudoiberdiev");
const loadedUser = await userRepository.findByName("Umed", "Khudoiberdiev");
console.log("User loaded: ", loadedUser);
console.log("Author persisted! Loaded author: ", loadedAuthor);
}).catch(error => console.log("Error: ", error));

View File

@ -0,0 +1,15 @@
import {PrimaryGeneratedColumn, Column, Entity} from "../../../src/index";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
firstName: string;
@Column()
lastName: string;
}

View File

@ -3,7 +3,7 @@ import {AbstractRepository} from "../../../src/repository/AbstractRepository";
import {Author} from "../entity/Author";
/**
* Second type of custom repository - extends abstract repository (also can not extend anything).
* First type of custom repository - extends abstract repository.
*/
@EntityRepository(Author)
export class AuthorRepository extends AbstractRepository<Author> {

View File

@ -3,7 +3,7 @@ import {Post} from "../entity/Post";
import {EntityRepository} from "../../../src/decorator/EntityRepository";
/**
* First type of custom repository - extends standard repository.
* Second type of custom repository - extends standard repository.
*/
@EntityRepository(Post)
export class PostRepository extends Repository<Post> {

View File

@ -0,0 +1,26 @@
import {EntityRepository} from "../../../src/decorator/EntityRepository";
import {EntityManager} from "../../../src/entity-manager/EntityManager";
import {User} from "../entity/User";
/**
* Third type of custom repository - extends nothing and accepts entity manager as a first constructor parameter.
*/
@EntityRepository()
export class UserRepository {
constructor(private entityManager: EntityManager) {
}
async createAndSave(firstName: string, lastName: string) {
const user = await this.entityManager.create(User, { firstName, lastName });
return this.entityManager.save(user);
}
async findByName(firstName: string, lastName: string) {
return this.entityManager.createQueryBuilder(User, "user")
.where("user.firstName = :firstName AND user.lastName = :lastName")
.setParameters({ firstName, lastName })
.getOne();
}
}

View File

@ -567,40 +567,9 @@ export class Connection {
* Gets custom entity repository marked with @EntityRepository decorator.
*/
getCustomRepository<T>(customRepository: ObjectType<T>): T {
const entityRepositoryMetadataArgs = getMetadataArgsStorage().entityRepositories.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) {
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)["manager"])
(entityRepositoryInstance as any)["manager"] = this.manager;
}
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)["manager"] = this.manager;
(entityRepositoryInstance as any)["metadata"] = this.getMetadata(entityRepositoryMetadataArgs.entity);
}
// register entity repository
this.entityRepositories.push(entityRepositoryInstance);
}
return entityRepositoryInstance;
return this.manager.getCustomRepository(customRepository);
}
// -------------------------------------------------------------------------
// Protected Methods
// -------------------------------------------------------------------------

View File

@ -21,6 +21,10 @@ import {SubjectBuilder} from "../persistence/SubjectBuilder";
import {SubjectOperationExecutor} from "../persistence/SubjectOperationExecutor";
import {PlainObjectToNewEntityTransformer} from "../query-builder/transformer/PlainObjectToNewEntityTransformer";
import {PlainObjectToDatabaseEntityTransformer} from "../query-builder/transformer/PlainObjectToDatabaseEntityTransformer";
import {CustomRepositoryNotFoundError} from "../repository/error/CustomRepositoryNotFoundError";
import {getMetadataArgsStorage} from "../index";
import {AbstractRepository} from "../repository/AbstractRepository";
import {CustomRepositoryCannotInheritRepositoryError} from "../repository/error/CustomRepositoryCannotInheritRepositoryError";
/**
* Entity manager supposed to work with any entity, automatically find its repository and call its methods,
@ -665,7 +669,31 @@ export class EntityManager {
* Gets custom entity repository marked with @EntityRepository decorator.
*/
getCustomRepository<T>(customRepository: ObjectType<T>): T {
return this.connection.getCustomRepository<T>(customRepository);
const entityRepositoryMetadataArgs = getMetadataArgsStorage().entityRepositories.find(repository => {
return repository.target === (customRepository instanceof Function ? customRepository : (customRepository as any).constructor);
});
if (!entityRepositoryMetadataArgs)
throw new CustomRepositoryNotFoundError(customRepository);
const entityMetadata = entityRepositoryMetadataArgs.entity ? this.connection.getMetadata(entityRepositoryMetadataArgs.entity) : undefined;
const entityRepositoryInstance = new (entityRepositoryMetadataArgs.target as any)(this, entityMetadata);
// 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 instanceof AbstractRepository) {
if (!(entityRepositoryInstance as any)["manager"])
(entityRepositoryInstance as any)["manager"] = this;
}
if (entityRepositoryInstance instanceof Repository) {
if (!entityMetadata)
throw new CustomRepositoryCannotInheritRepositoryError(customRepository);
(entityRepositoryInstance as any)["manager"] = this;
(entityRepositoryInstance as any)["metadata"] = entityMetadata;
}
return entityRepositoryInstance;
}
/**