mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
added factories and used container in the connection class
This commit is contained in:
parent
1e79a63795
commit
8d68c8c40b
@ -23,7 +23,10 @@ import {ReactiveEntityManager} from "../entity-manager/ReactiveEntityManager";
|
||||
import {TreeRepository} from "../repository/TreeRepository";
|
||||
import {ReactiveTreeRepository} from "../repository/ReactiveTreeRepository";
|
||||
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
|
||||
import {RepositoryBuilder} from "../repository/RepositoryBuilder";
|
||||
import {NamingStrategyNotFoundError} from "./error/NamingStrategyNotFoundError";
|
||||
import {EntityManagerFactory} from "../entity-manager/EntityManagerFactory";
|
||||
import {RepositoryFactory} from "../repository/RepositoryFactory";
|
||||
import {SchemaCreatorFactory} from "../schema-creator/SchemaCreatorFactory";
|
||||
|
||||
/**
|
||||
* A single connection instance to the database. Each connection has its own repositories, subscribers and metadatas.
|
||||
@ -34,9 +37,20 @@ export class Connection {
|
||||
// Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* All connection's repositories.
|
||||
*/
|
||||
private repositories: Repository<any>[] = [];
|
||||
|
||||
/**
|
||||
* All connection's reactive repositories.
|
||||
*/
|
||||
private reactiveRepositories: ReactiveRepository<any>[] = [];
|
||||
|
||||
private repositoryFactory = getFromContainer(RepositoryFactory);
|
||||
|
||||
private schemaCreatorFactory = getFromContainer(SchemaCreatorFactory);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Readonly properties
|
||||
// -------------------------------------------------------------------------
|
||||
@ -119,8 +133,8 @@ export class Connection {
|
||||
this.driver = driver;
|
||||
this.driver.connectionOptions = options;
|
||||
this.options = options;
|
||||
this.entityManager = new EntityManager(this);
|
||||
this.reactiveEntityManager = new ReactiveEntityManager(this);
|
||||
this.entityManager = getFromContainer(EntityManagerFactory).createEntityManager(this);
|
||||
this.reactiveEntityManager = getFromContainer(EntityManagerFactory).createReactiveEntityManager(this);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -173,9 +187,12 @@ export class Connection {
|
||||
/**
|
||||
* Creates database schema for all entities registered in this connection.
|
||||
*/
|
||||
syncSchema() {
|
||||
async syncSchema(dropBeforeSync: boolean = false): Promise<void> {
|
||||
if (dropBeforeSync)
|
||||
await this.driver.clearDatabase();
|
||||
|
||||
const schemaBuilder = this.driver.createSchemaBuilder();
|
||||
const schemaCreator = new SchemaCreator(schemaBuilder, this.entityMetadatas);
|
||||
const schemaCreator = this.schemaCreatorFactory.create(schemaBuilder, this.entityMetadatas);
|
||||
return schemaCreator.create();
|
||||
}
|
||||
|
||||
@ -254,13 +271,7 @@ export class Connection {
|
||||
if (!this.isConnected)
|
||||
throw new NoConnectionForRepositoryError(this.name);
|
||||
|
||||
let metadata: EntityMetadata;
|
||||
if (typeof entityClassOrName === "string") {
|
||||
metadata = this.entityMetadatas.findByName(entityClassOrName);
|
||||
} else {
|
||||
metadata = this.entityMetadatas.findByTarget(entityClassOrName);
|
||||
}
|
||||
|
||||
const metadata = this.entityMetadatas.findByNameOrTarget(entityClassOrName);
|
||||
const repository = this.repositories.find(repository => Repository.ownsMetadata(repository, metadata));
|
||||
if (!repository)
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
@ -286,13 +297,7 @@ export class Connection {
|
||||
if (!this.isConnected)
|
||||
throw new NoConnectionForRepositoryError(this.name);
|
||||
|
||||
let metadata: EntityMetadata;
|
||||
if (typeof entityClassOrName === "string") {
|
||||
metadata = this.entityMetadatas.findByName(entityClassOrName);
|
||||
} else {
|
||||
metadata = this.entityMetadatas.findByTarget(entityClassOrName);
|
||||
}
|
||||
|
||||
const metadata = this.entityMetadatas.findByNameOrTarget(entityClassOrName);
|
||||
const repository = this.repositories.find(repository => Repository.ownsMetadata(repository, metadata));
|
||||
if (!repository)
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
@ -365,15 +370,15 @@ export class Connection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the naming strategy to be used for this connection.
|
||||
* Creates a naming strategy to be used for this connection.
|
||||
*/
|
||||
private createNamingStrategy(): NamingStrategyInterface {
|
||||
if (!this.options.namingStrategy)
|
||||
return new DefaultNamingStrategy();
|
||||
return getFromContainer(DefaultNamingStrategy);
|
||||
|
||||
const namingMetadata = this.namingStrategyMetadatas.find(strategy => strategy.name === this.options.namingStrategy);
|
||||
if (!namingMetadata)
|
||||
throw new Error(`Naming strategy called "${this.options.namingStrategy}" was not found.`);
|
||||
throw new NamingStrategyNotFoundError(this.options.namingStrategy, this.name);
|
||||
|
||||
return getFromContainer<NamingStrategyInterface>(namingMetadata.target);
|
||||
}
|
||||
@ -383,13 +388,15 @@ export class Connection {
|
||||
*/
|
||||
private createRepository(metadata: EntityMetadata) {
|
||||
if (metadata.table.isClosure) {
|
||||
const repository = new TreeRepository<any>(this, this.entityMetadatas, metadata);
|
||||
const repository = this.repositoryFactory.createRepository(this, this.entityMetadatas, metadata);
|
||||
const reactiveRepository = this.repositoryFactory.createReactiveRepository(repository);
|
||||
this.repositories.push(repository);
|
||||
this.reactiveRepositories.push(new ReactiveTreeRepository(repository));
|
||||
this.reactiveRepositories.push(reactiveRepository);
|
||||
} else {
|
||||
const repository = new Repository<any>(this, this.entityMetadatas, metadata);
|
||||
const repository = this.repositoryFactory.createTreeRepository(this, this.entityMetadatas, metadata);
|
||||
const reactiveRepository = this.repositoryFactory.createReactiveTreeRepository(repository);
|
||||
this.repositories.push(repository);
|
||||
this.reactiveRepositories.push(new ReactiveRepository(repository));
|
||||
this.reactiveRepositories.push(reactiveRepository);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
13
src/connection/error/NamingStrategyNotFoundError.ts
Normal file
13
src/connection/error/NamingStrategyNotFoundError.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class NamingStrategyNotFoundError extends Error {
|
||||
name = "NamingStrategyNotFoundError";
|
||||
|
||||
constructor(strategyName: string, connectionName: string) {
|
||||
super();
|
||||
this.message = `Naming strategy named "${strategyName}" was not found. Looks like this naming strategy does not ` +
|
||||
`exist or it was not registered in current "${connectionName}" connection?`;
|
||||
}
|
||||
|
||||
}
|
||||
@ -331,5 +331,4 @@ export class EntityManager {
|
||||
return this.getTreeRepository(entityClass).countAncestors(entity);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
23
src/entity-manager/EntityManagerFactory.ts
Normal file
23
src/entity-manager/EntityManagerFactory.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {EntityManager} from "./EntityManager";
|
||||
import {ReactiveEntityManager} from "./ReactiveEntityManager";
|
||||
|
||||
/**
|
||||
* Entity manager supposed to work with any entity, automatically find its repository and call its method, whatever
|
||||
* entity type are you passing.
|
||||
*/
|
||||
export class EntityManagerFactory {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
createEntityManager(connection: Connection) {
|
||||
return new EntityManager(connection);
|
||||
}
|
||||
|
||||
createReactiveEntityManager(connection: Connection) {
|
||||
return new ReactiveEntityManager(connection);
|
||||
}
|
||||
|
||||
}
|
||||
@ -21,6 +21,14 @@ export class EntityMetadataCollection extends Array<EntityMetadata> {
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
findByNameOrTarget(nameOrTarget: Function|string) {
|
||||
if (typeof nameOrTarget === "string") {
|
||||
return this.findByName(nameOrTarget);
|
||||
} else {
|
||||
return this.findByTarget(nameOrTarget);
|
||||
}
|
||||
}
|
||||
|
||||
findByName(name: string) {
|
||||
const metadata = this.find(metadata => metadata.name === name);
|
||||
|
||||
@ -31,7 +31,7 @@ export class Repository<Entity> {
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(protected connection: Connection,
|
||||
constructor(protected connection: Connection,
|
||||
protected entityMetadatas: EntityMetadataCollection,
|
||||
protected metadata: EntityMetadata) {
|
||||
this.driver = connection.driver;
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {EntityMetadata} from "../metadata/EntityMetadata";
|
||||
import {QueryBuilder} from "../query-builder/QueryBuilder";
|
||||
import {PlainObjectToNewEntityTransformer} from "../query-builder/transformer/PlainObjectToNewEntityTransformer";
|
||||
import {PlainObjectToDatabaseEntityTransformer} from "../query-builder/transformer/PlainObjectToDatabaseEntityTransformer";
|
||||
import {EntityPersistOperationBuilder} from "../persistment/EntityPersistOperationsBuilder";
|
||||
import {PersistOperationExecutor} from "../persistment/PersistOperationExecutor";
|
||||
import {EntityWithId} from "../persistment/operation/PersistOperation";
|
||||
import {FindOptions, FindOptionsUtils} from "./FindOptions";
|
||||
import {EntityMetadataCollection} from "../metadata/collection/EntityMetadataCollection";
|
||||
import {Broadcaster} from "../subscriber/Broadcaster";
|
||||
import {Driver} from "../driver/Driver";
|
||||
|
||||
/**
|
||||
* Repository is supposed to work with your entity objects. Find entities, insert, update, delete, etc.
|
||||
*/
|
||||
export class RepositoryBuilder {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(protected connection: Connection,
|
||||
protected entityMetadatas: EntityMetadataCollection,
|
||||
protected metadata: EntityMetadata) {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
|
||||
}
|
||||
37
src/repository/RepositoryFactory.ts
Normal file
37
src/repository/RepositoryFactory.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import {TreeRepository} from "./TreeRepository";
|
||||
import {EntityMetadata} from "../metadata/EntityMetadata";
|
||||
import {EntityMetadataCollection} from "../metadata/collection/EntityMetadataCollection";
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {Repository} from "./Repository";
|
||||
import {ReactiveRepository} from "./ReactiveRepository";
|
||||
import {ReactiveTreeRepository} from "./ReactiveTreeRepository";
|
||||
|
||||
/**
|
||||
*/
|
||||
export class RepositoryFactory {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
createRepository(connection: Connection,
|
||||
allMetadatas: EntityMetadataCollection,
|
||||
metadata: EntityMetadata) {
|
||||
return new Repository<any>(connection, allMetadatas, metadata);
|
||||
}
|
||||
|
||||
createTreeRepository(connection: Connection,
|
||||
allMetadatas: EntityMetadataCollection,
|
||||
metadata: EntityMetadata) {
|
||||
return new TreeRepository<any>(connection, allMetadatas, metadata);
|
||||
}
|
||||
|
||||
createReactiveRepository(repository: Repository<any>) {
|
||||
return new ReactiveRepository(repository);
|
||||
}
|
||||
|
||||
createReactiveTreeRepository(repository: TreeRepository<any>) {
|
||||
return new ReactiveTreeRepository(repository);
|
||||
}
|
||||
|
||||
}
|
||||
17
src/schema-creator/SchemaCreatorFactory.ts
Normal file
17
src/schema-creator/SchemaCreatorFactory.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import {SchemaBuilder} from "../schema-builder/SchemaBuilder";
|
||||
import {SchemaCreator} from "./SchemaCreator";
|
||||
import {EntityMetadataCollection} from "../metadata/collection/EntityMetadataCollection";
|
||||
|
||||
/**
|
||||
*/
|
||||
export class SchemaCreatorFactory {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
create(schemaBuilder: SchemaBuilder, entityMetadatas: EntityMetadataCollection) {
|
||||
return new SchemaCreator(schemaBuilder, entityMetadatas);
|
||||
}
|
||||
|
||||
}
|
||||
@ -51,9 +51,7 @@ describe("persistence > many-to-many", function() {
|
||||
|
||||
// clean up database before each test
|
||||
function reloadDatabase() {
|
||||
return connection.driver
|
||||
.clearDatabase()
|
||||
.then(() => connection.syncSchema())
|
||||
return connection.syncSchema(true)
|
||||
.catch(e => console.log("Error during schema re-creation: ", e));
|
||||
}
|
||||
|
||||
|
||||
@ -45,9 +45,7 @@ describe("persistence > one-to-many", function() {
|
||||
|
||||
// clean up database before each test
|
||||
function reloadDatabase() {
|
||||
return connection.driver
|
||||
.clearDatabase()
|
||||
.then(() => connection.syncSchema())
|
||||
return connection.syncSchema(true)
|
||||
.catch(e => console.log("Error during schema re-creation: ", e));
|
||||
}
|
||||
|
||||
|
||||
@ -41,9 +41,7 @@ describe("insertion", function() {
|
||||
|
||||
// clean up database before each test
|
||||
function reloadDatabase() {
|
||||
return connection.driver
|
||||
.clearDatabase()
|
||||
.then(() => connection.syncSchema())
|
||||
return connection.syncSchema(true)
|
||||
.catch(e => console.log("Error during schema re-creation: ", e));
|
||||
}
|
||||
|
||||
|
||||
@ -50,9 +50,7 @@ describe("one-to-one", function() {
|
||||
|
||||
// clean up database before each test
|
||||
function reloadDatabase() {
|
||||
return connection.driver
|
||||
.clearDatabase()
|
||||
.then(() => connection.syncSchema());
|
||||
return connection.syncSchema(true);
|
||||
}
|
||||
|
||||
let postRepository: Repository<Post>,
|
||||
|
||||
@ -47,9 +47,7 @@ describe("many-to-one", function() {
|
||||
|
||||
// clean up database before each test
|
||||
function reloadDatabase() {
|
||||
return connection.driver
|
||||
.clearDatabase()
|
||||
.then(() => connection.syncSchema());
|
||||
return connection.syncSchema(true);
|
||||
}
|
||||
|
||||
let postRepository: Repository<Post>,
|
||||
|
||||
@ -49,9 +49,7 @@ describe("many-to-many", function() {
|
||||
|
||||
// clean up database before each test
|
||||
function reloadDatabase() {
|
||||
return connection.driver
|
||||
.clearDatabase()
|
||||
.then(() => connection.syncSchema());
|
||||
return connection.syncSchema(true);
|
||||
}
|
||||
|
||||
let postRepository: Repository<Post>,
|
||||
|
||||
@ -32,9 +32,7 @@ export function setupConnection(entities: Function[], callback?: (connection: Co
|
||||
|
||||
export function reloadDatabase(connection: Connection) {
|
||||
return function () {
|
||||
return connection.driver
|
||||
.clearDatabase()
|
||||
.then(() => connection.syncSchema())
|
||||
return connection.syncSchema(true)
|
||||
.catch(e => console.log("Error during schema re-creation: ", e));
|
||||
};
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user