mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
refactored connection and connection manager classes
This commit is contained in:
parent
eb828c109c
commit
713037f8b4
@ -107,7 +107,7 @@ let connectionOptions: ConnectionOptions = {
|
||||
};
|
||||
|
||||
// create a new connection with mysql driver
|
||||
connectionManager.createConnection(new MysqlDriver(), connectionOptions);
|
||||
connectionManager.createConnection(new MysqlDriver(connectionOptions));
|
||||
|
||||
// import all entities from specific directory
|
||||
connectionManager.importEntitiesFromDirectories(__dirname + "/entities");
|
||||
|
||||
@ -27,8 +27,8 @@ export class ConnectionManager {
|
||||
* Creates a new connection based on the given connection options and registers a new connection in the manager.
|
||||
*/
|
||||
create(options: CreateConnectionOptions): Connection {
|
||||
const driver = this.createDriver(options.driver);
|
||||
const connection = this.createConnection(options.connectionName || "default", driver, options.connection);
|
||||
const driver = this.createDriver(options.driver, options.connection);
|
||||
const connection = this.createConnection(options.connectionName || "default", driver);
|
||||
|
||||
if (options.entitySchemaDirectories && options.entitySchemaDirectories.length > 0)
|
||||
connection.importEntitySchemaFromDirectories(options.entitySchemaDirectories);
|
||||
@ -66,12 +66,12 @@ export class ConnectionManager {
|
||||
/**
|
||||
* Creates a new connection and pushes a connection to the array.
|
||||
*/
|
||||
createConnection(name: string, driver: Driver, options: ConnectionOptions) {
|
||||
createConnection(name: string, driver: Driver) {
|
||||
const existConnection = this.connections.find(connection => connection.name === name);
|
||||
if (existConnection)
|
||||
this.connections.splice(this.connections.indexOf(existConnection), 1);
|
||||
|
||||
const connection = new Connection(name, driver, options);
|
||||
const connection = new Connection(name, driver);
|
||||
this.connections.push(connection);
|
||||
return connection;
|
||||
}
|
||||
@ -94,12 +94,12 @@ export class ConnectionManager {
|
||||
// Private Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private createDriver(driverName: string): Driver {
|
||||
private createDriver(driverName: string, options: ConnectionOptions): Driver {
|
||||
switch (driverName) {
|
||||
case "mysql":
|
||||
return new MysqlDriver();
|
||||
return new MysqlDriver(options);
|
||||
case "postgres":
|
||||
return new PostgresDriver();
|
||||
return new PostgresDriver(options);
|
||||
default:
|
||||
throw new MissingDriverError(driverName);
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ import {ConnectionOptions} from "./ConnectionOptions";
|
||||
import {Repository} from "../repository/Repository";
|
||||
import {EntitySubscriberInterface} from "../subscriber/EntitySubscriberInterface";
|
||||
import {RepositoryNotFoundError} from "./error/RepositoryNotFoundError";
|
||||
import {EntityMetadata} from "../metadata/EntityMetadata";
|
||||
import {ConstructorFunction} from "../common/ConstructorFunction";
|
||||
import {EntityListenerMetadata} from "../metadata/EntityListenerMetadata";
|
||||
import {EntityManager} from "../entity-manager/EntityManager";
|
||||
@ -23,9 +22,7 @@ import {TreeReactiveRepository} from "../repository/TreeReactiveRepository";
|
||||
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
|
||||
import {NamingStrategyNotFoundError} from "./error/NamingStrategyNotFoundError";
|
||||
import {EntityManagerFactory} from "../entity-manager/EntityManagerFactory";
|
||||
import {RepositoryFactory} from "../repository/RepositoryFactory";
|
||||
import {SchemaCreatorFactory} from "../schema-creator/SchemaCreatorFactory";
|
||||
import {ReactiveRepositoryNotFoundError} from "./error/ReactiveRepositoryNotFoundError";
|
||||
import {RepositoryNotTreeError} from "./error/RepositoryNotTreeError";
|
||||
import {EntitySchema} from "../metadata/entity-schema/EntitySchema";
|
||||
import {CannotSyncNotConnectedError} from "./error/CannotSyncNotConnectedError";
|
||||
@ -36,6 +33,8 @@ import {CannotGetEntityManagerNotConnectedError} from "./error/CannotGetEntityMa
|
||||
import {LazyRelationsWrapper} from "../repository/LazyRelationsWrapper";
|
||||
import {SpecificRepository} from "../repository/SpecificRepository";
|
||||
import {SpecificReactiveRepository} from "../repository/ReactiveSpecificRepository";
|
||||
import {RepositoryForMetadata} from "../repository/RepositoryForMetadata";
|
||||
import {EntityMetadata} from "../metadata/EntityMetadata";
|
||||
|
||||
/**
|
||||
* A single connection instance to the database.
|
||||
@ -62,6 +61,11 @@ export class Connection {
|
||||
*/
|
||||
public readonly entityMetadatas = new EntityMetadataCollection();
|
||||
|
||||
/**
|
||||
* Used to broadcast connection events.
|
||||
*/
|
||||
public readonly broadcaster: Broadcaster;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private Properties
|
||||
// -------------------------------------------------------------------------
|
||||
@ -77,30 +81,15 @@ export class Connection {
|
||||
private readonly _reactiveEntityManager: ReactiveEntityManager;
|
||||
|
||||
/**
|
||||
* Used to initialize lazy relations.
|
||||
*/
|
||||
private readonly lazyRelationsWrapper: LazyRelationsWrapper;
|
||||
|
||||
/**
|
||||
* All entity listener metadatas that are registered for this connection.
|
||||
* Entity listeners that are registered for this connection.
|
||||
*/
|
||||
private readonly entityListeners: EntityListenerMetadata[] = [];
|
||||
|
||||
/**
|
||||
* All subscribers that are registered for this connection.
|
||||
* Entity subscribers that are registered for this connection.
|
||||
*/
|
||||
private readonly entitySubscribers: EntitySubscriberInterface<any>[] = [];
|
||||
|
||||
/**
|
||||
* Used to broadcast connection events.
|
||||
*/
|
||||
private readonly broadcaster: Broadcaster;
|
||||
|
||||
/**
|
||||
* Connection options.
|
||||
*/
|
||||
private readonly options: ConnectionOptions;
|
||||
|
||||
/**
|
||||
* Registered entity classes to be used for this connection.
|
||||
*/
|
||||
@ -121,26 +110,6 @@ export class Connection {
|
||||
*/
|
||||
private readonly namingStrategyClasses: Function[] = [];
|
||||
|
||||
/**
|
||||
* All connection's repositories.
|
||||
*/
|
||||
private readonly repositories: Repository<any>[] = [];
|
||||
|
||||
/**
|
||||
* All connection's reactive repositories.
|
||||
*/
|
||||
private readonly reactiveRepositories: ReactiveRepository<any>[] = [];
|
||||
|
||||
/**
|
||||
* All connection's specific repositories.
|
||||
*/
|
||||
private readonly specificRepositories: SpecificRepository<any>[] = [];
|
||||
|
||||
/**
|
||||
* All connection's specific reactive repositories.
|
||||
*/
|
||||
private readonly specificReactiveRepositories: SpecificReactiveRepository<any>[] = [];
|
||||
|
||||
/**
|
||||
* Naming strategy to be used in this connection.
|
||||
*/
|
||||
@ -151,19 +120,21 @@ export class Connection {
|
||||
*/
|
||||
private _isConnected = false;
|
||||
|
||||
/**
|
||||
* Stores all registered metadatas with their repositories.
|
||||
*/
|
||||
private readonly repositoryForMetadatas: RepositoryForMetadata[] = [];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(name: string, driver: Driver, options: ConnectionOptions) {
|
||||
constructor(name: string, driver: Driver) {
|
||||
this.name = name;
|
||||
this.driver = driver;
|
||||
this.driver.connectionOptions = options;
|
||||
this.options = options;
|
||||
this._entityManager = getFromContainer(EntityManagerFactory).createEntityManager(this);
|
||||
this._reactiveEntityManager = getFromContainer(EntityManagerFactory).createReactiveEntityManager(this);
|
||||
this.broadcaster = getFromContainer(BroadcasterFactory).createBroadcaster(this.entityMetadatas, this.entitySubscribers, this.entityListeners);
|
||||
this.lazyRelationsWrapper = new LazyRelationsWrapper(this.driver, this.entityMetadatas, this.broadcaster);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -171,14 +142,14 @@ export class Connection {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns true if connection to the database already established for this connection.
|
||||
* Indicates if connection to the database already established for this connection.
|
||||
*/
|
||||
get isConnected() {
|
||||
return this._isConnected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entity manager allows to work with any entity of your connection.
|
||||
* Entity manager allows to work with any entity of this connection.
|
||||
*/
|
||||
get entityManager() {
|
||||
if (!this.isConnected)
|
||||
@ -189,7 +160,7 @@ export class Connection {
|
||||
|
||||
/**
|
||||
* Entity manager allows to work with any entity of your connection.
|
||||
* This version of entity manager is reactive - works with Observables instead of promises.
|
||||
* This version of entity manager is reactive - works with Observables instead of Promises.
|
||||
*/
|
||||
get reactiveEntityManager() {
|
||||
if (!this.isConnected)
|
||||
@ -218,8 +189,12 @@ export class Connection {
|
||||
// set connected status for the current connection
|
||||
this._isConnected = true;
|
||||
|
||||
// drop the schema if special option is set
|
||||
if (this.driver.connectionOptions.dropSchemaOnConnection)
|
||||
await this.driver.clearDatabase();
|
||||
|
||||
// second build schema
|
||||
if (this.options.autoSchemaCreate === true)
|
||||
if (this.driver.connectionOptions.autoSchemaCreate === true)
|
||||
await this.syncSchema();
|
||||
|
||||
return this;
|
||||
@ -352,7 +327,7 @@ export class Connection {
|
||||
/**
|
||||
* Gets the entity metadata of the given entity target.
|
||||
*/
|
||||
getMetadata(entity: Function|string) {
|
||||
getMetadata(entity: Function|string): EntityMetadata {
|
||||
return this.entityMetadatas.findByTarget(entity);
|
||||
}
|
||||
|
||||
@ -377,11 +352,11 @@ export class Connection {
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
|
||||
const metadata = this.entityMetadatas.findByTarget(entityClassOrName);
|
||||
const repository = this.repositories.find(repository => Repository.ownsMetadata(repository, metadata));
|
||||
if (!repository)
|
||||
const repositoryAggregate = this.repositoryForMetadatas.find(metadataRepository => metadataRepository.metadata === metadata);
|
||||
if (!repositoryAggregate)
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
|
||||
return repository;
|
||||
return repositoryAggregate.repository;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -405,14 +380,14 @@ export class Connection {
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
|
||||
const metadata = this.entityMetadatas.findByTarget(entityClassOrName);
|
||||
const repository = this.repositories.find(repository => Repository.ownsMetadata(repository, metadata));
|
||||
if (!repository)
|
||||
const repositoryAggregate = this.repositoryForMetadatas.find(metadataRepository => metadataRepository.metadata === metadata);
|
||||
if (!repositoryAggregate)
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
|
||||
if (!metadata.table.isClosure)
|
||||
throw new RepositoryNotTreeError(entityClassOrName);
|
||||
|
||||
return <TreeRepository<Entity>> repository;
|
||||
return repositoryAggregate.repository as TreeRepository<Entity>;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -436,11 +411,11 @@ export class Connection {
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
|
||||
const metadata = this.entityMetadatas.findByTarget(entityClassOrName);
|
||||
const repository = this.specificRepositories.find(repository => SpecificRepository.ownsMetadata(repository, metadata));
|
||||
if (!repository)
|
||||
const repositoryAggregate = this.repositoryForMetadatas.find(metadataRepository => metadataRepository.metadata === metadata);
|
||||
if (!repositoryAggregate)
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
|
||||
return repository;
|
||||
return repositoryAggregate.specificRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -464,11 +439,11 @@ export class Connection {
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
|
||||
const metadata = this.entityMetadatas.findByTarget(entityClassOrName);
|
||||
const repository = this.specificReactiveRepositories.find(repository => SpecificReactiveRepository.ownsMetadata(repository, metadata));
|
||||
if (!repository)
|
||||
const repositoryAggregate = this.repositoryForMetadatas.find(metadataRepository => metadataRepository.metadata === metadata);
|
||||
if (!repositoryAggregate)
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
|
||||
return repository;
|
||||
return repositoryAggregate.specificReactiveRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -492,11 +467,11 @@ export class Connection {
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
|
||||
const metadata = this.entityMetadatas.findByTarget(entityClassOrName);
|
||||
const repository = this.reactiveRepositories.find(repository => ReactiveRepository.ownsMetadata(repository, metadata));
|
||||
if (!repository)
|
||||
throw new ReactiveRepositoryNotFoundError(this.name, entityClassOrName);
|
||||
const repositoryAggregate = this.repositoryForMetadatas.find(metadataRepository => metadataRepository.metadata === metadata);
|
||||
if (!repositoryAggregate)
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
|
||||
return repository;
|
||||
return repositoryAggregate.reactiveRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -520,14 +495,14 @@ export class Connection {
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
|
||||
const metadata = this.entityMetadatas.findByTarget(entityClassOrName);
|
||||
const repository = this.reactiveRepositories.find(repository => ReactiveRepository.ownsMetadata(repository, metadata));
|
||||
if (!repository)
|
||||
const repositoryAggregate = this.repositoryForMetadatas.find(metadataRepository => metadataRepository.metadata === metadata);
|
||||
if (!repositoryAggregate)
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
|
||||
if (!metadata.table.isClosure)
|
||||
throw new RepositoryNotTreeError(entityClassOrName);
|
||||
|
||||
return <TreeReactiveRepository<Entity>> repository;
|
||||
return repositoryAggregate.reactiveRepository as TreeReactiveRepository<Entity>;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -540,6 +515,7 @@ export class Connection {
|
||||
private buildMetadatas() {
|
||||
|
||||
const namingStrategy = this.createNamingStrategy();
|
||||
const lazyRelationsWrapper = new LazyRelationsWrapper(this.driver, this.entityMetadatas, this.broadcaster);
|
||||
|
||||
// take imported event subscribers
|
||||
if (this.subscriberClasses && this.subscriberClasses.length) {
|
||||
@ -561,20 +537,20 @@ export class Connection {
|
||||
// build entity metadatas from metadata args storage (collected from decorators)
|
||||
if (this.entityClasses && this.entityClasses.length) {
|
||||
getFromContainer(EntityMetadataBuilder)
|
||||
.buildFromMetadataArgsStorage(this.lazyRelationsWrapper, namingStrategy, this.entityClasses)
|
||||
.buildFromMetadataArgsStorage(lazyRelationsWrapper, namingStrategy, this.entityClasses)
|
||||
.forEach(metadata => {
|
||||
this.entityMetadatas.push(metadata);
|
||||
this.createRepository(metadata);
|
||||
this.repositoryForMetadatas.push(new RepositoryForMetadata(this, metadata));
|
||||
});
|
||||
}
|
||||
|
||||
// build entity metadatas from given entity schemas
|
||||
if (this.entitySchemas && this.entitySchemas.length) {
|
||||
getFromContainer(EntityMetadataBuilder)
|
||||
.buildFromSchemas(this.lazyRelationsWrapper, namingStrategy, this.entitySchemas)
|
||||
.buildFromSchemas(lazyRelationsWrapper, namingStrategy, this.entitySchemas)
|
||||
.forEach(metadata => {
|
||||
this.entityMetadatas.push(metadata);
|
||||
this.createRepository(metadata);
|
||||
this.repositoryForMetadatas.push(new RepositoryForMetadata(this, metadata));
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -608,29 +584,4 @@ export class Connection {
|
||||
return getFromContainer<NamingStrategyInterface>(namingMetadata.target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates repository and reactive repository for the given entity metadata.
|
||||
*/
|
||||
private createRepository(metadata: EntityMetadata): void {
|
||||
const repositoryFactory = getFromContainer(RepositoryFactory);
|
||||
let repository: Repository<any>, reactiveRepository: ReactiveRepository<any>;
|
||||
|
||||
if (metadata.table.isClosure) {
|
||||
repository = repositoryFactory.createTreeRepository(this, this.broadcaster, this.entityMetadatas, metadata);
|
||||
reactiveRepository = repositoryFactory.createReactiveTreeRepository(repository as TreeRepository<any>);
|
||||
} else {
|
||||
repository = repositoryFactory.createRepository(this, this.broadcaster, this.entityMetadatas, metadata);
|
||||
reactiveRepository = repositoryFactory.createReactiveRepository(repository);
|
||||
}
|
||||
|
||||
this.repositories.push(repository);
|
||||
this.reactiveRepositories.push(reactiveRepository);
|
||||
|
||||
const specificRepository = repositoryFactory.createSpecificRepository(this, metadata, repository);
|
||||
this.specificRepositories.push(specificRepository);
|
||||
|
||||
const specificReactiveRepository = repositoryFactory.createSpecificReactiveRepository(specificRepository);
|
||||
this.specificReactiveRepositories.push(specificReactiveRepository);
|
||||
}
|
||||
|
||||
}
|
||||
@ -33,6 +33,13 @@ export interface ConnectionOptions {
|
||||
*/
|
||||
database?: string;
|
||||
|
||||
/**
|
||||
* Drops the schema each time connection is being established.
|
||||
* Be careful with this option and don't use this in production - otherwise you'll loose all your production data.
|
||||
* This option is useful during debug and development.
|
||||
*/
|
||||
dropSchemaOnConnection?: boolean;
|
||||
|
||||
/**
|
||||
* Indicates if database schema should be auto created every time application launch.
|
||||
*/
|
||||
|
||||
@ -18,11 +18,6 @@ export class MysqlDriver extends BaseDriver implements Driver {
|
||||
// Public Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Connection used in this driver.
|
||||
*/
|
||||
connectionOptions: ConnectionOptions;
|
||||
|
||||
readonly isResultsLowercase = false;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -38,7 +33,7 @@ export class MysqlDriver extends BaseDriver implements Driver {
|
||||
* Connection to mysql database.
|
||||
*/
|
||||
private mysqlConnection: any;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Getter Methods
|
||||
// -------------------------------------------------------------------------
|
||||
@ -75,7 +70,7 @@ export class MysqlDriver extends BaseDriver implements Driver {
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(mysql?: any) {
|
||||
constructor(public connectionOptions: ConnectionOptions, mysql?: any) {
|
||||
super();
|
||||
|
||||
// if driver dependency is not given explicitly, then try to load it via "require"
|
||||
|
||||
@ -15,11 +15,6 @@ export class PostgresDriver extends BaseDriver implements Driver {
|
||||
// Public Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Connection used in this driver.
|
||||
*/
|
||||
connectionOptions: ConnectionOptions;
|
||||
|
||||
readonly isResultsLowercase = true;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -35,7 +30,7 @@ export class PostgresDriver extends BaseDriver implements Driver {
|
||||
* Connection to postgres database.
|
||||
*/
|
||||
private postgresConnection: any;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Getter Methods
|
||||
// -------------------------------------------------------------------------
|
||||
@ -72,7 +67,7 @@ export class PostgresDriver extends BaseDriver implements Driver {
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(postgres?: any) {
|
||||
constructor(public connectionOptions: ConnectionOptions, postgres?: any) {
|
||||
super();
|
||||
|
||||
// if driver dependency is not given explicitly, then try to load it via "require"
|
||||
|
||||
@ -14,7 +14,7 @@ export class EntityMetadataCollection extends Array<EntityMetadata> {
|
||||
return !!this.find(metadata => metadata.target === target || (typeof target === "string" && metadata.targetName === target));
|
||||
}
|
||||
|
||||
findByTarget(target: Function|string) {
|
||||
findByTarget(target: Function|string): EntityMetadata {
|
||||
const metadata = this.find(metadata => metadata.target === target || (typeof target === "string" && metadata.targetName === target));
|
||||
if (!metadata)
|
||||
throw new EntityMetadataNotFound(target);
|
||||
|
||||
@ -236,12 +236,4 @@ export class ReactiveRepository<Entity> {
|
||||
return Rx.Observable.fromPromise(this.repository.transaction(runInTransaction));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Static Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
static ownsMetadata(reactiveRepository: ReactiveRepository<any>, metadata: EntityMetadata) {
|
||||
return Repository.ownsMetadata(reactiveRepository.repository, metadata);
|
||||
}
|
||||
|
||||
}
|
||||
@ -79,15 +79,4 @@ export class SpecificReactiveRepository<Entity extends ObjectLiteral> {
|
||||
return Rx.Observable.fromPromise(this.repository.removeByIds(ids));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Static Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Checks if given repository owns given metadata.
|
||||
*/
|
||||
static ownsMetadata(repository: SpecificReactiveRepository<any>, metadata: EntityMetadata) {
|
||||
return SpecificRepository.ownsMetadata(repository.repository, metadata);
|
||||
}
|
||||
|
||||
}
|
||||
@ -21,7 +21,6 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
// Private Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
protected driver: Driver;
|
||||
protected persistOperationExecutor: PersistOperationExecutor;
|
||||
protected entityPersistOperationBuilder: EntityPersistOperationBuilder;
|
||||
protected plainObjectToEntityTransformer: PlainObjectToNewEntityTransformer;
|
||||
@ -32,12 +31,9 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(protected connection: Connection,
|
||||
protected broadcaster: Broadcaster,
|
||||
protected entityMetadatas: EntityMetadataCollection,
|
||||
protected metadata: EntityMetadata) {
|
||||
this.driver = connection.driver;
|
||||
this.persistOperationExecutor = new PersistOperationExecutor(connection.driver, entityMetadatas, this.broadcaster);
|
||||
this.entityPersistOperationBuilder = new EntityPersistOperationBuilder(entityMetadatas);
|
||||
this.persistOperationExecutor = new PersistOperationExecutor(connection.driver, connection.entityMetadatas, this.connection.broadcaster); // todo: better to pass connection?
|
||||
this.entityPersistOperationBuilder = new EntityPersistOperationBuilder(connection.entityMetadatas);
|
||||
this.plainObjectToEntityTransformer = new PlainObjectToNewEntityTransformer();
|
||||
this.plainObjectToDatabaseEntityTransformer = new PlainObjectToDatabaseEntityTransformer();
|
||||
}
|
||||
@ -70,7 +66,7 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
* Creates a new query builder that can be used to build a sql query.
|
||||
*/
|
||||
createQueryBuilder(alias: string): QueryBuilder<Entity> {
|
||||
return new QueryBuilder(this.driver, this.entityMetadatas, this.broadcaster)
|
||||
return new QueryBuilder(this.connection.driver, this.connection.entityMetadatas, this.connection.broadcaster) // todo: better to pass connection?
|
||||
.select(alias)
|
||||
.from(this.metadata.target, alias);
|
||||
}
|
||||
@ -315,7 +311,7 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
* Executes a raw SQL query and returns a raw database results.
|
||||
*/
|
||||
async query(query: string): Promise<any> {
|
||||
return this.driver.query(query);
|
||||
return this.connection.driver.query(query);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -323,15 +319,15 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
*/
|
||||
async transaction(runInTransaction: () => Promise<any>|any): Promise<any> {
|
||||
let runInTransactionResult: any;
|
||||
return this.driver
|
||||
return this.connection.driver
|
||||
.beginTransaction()
|
||||
.then(() => runInTransaction())
|
||||
.then(result => {
|
||||
runInTransactionResult = result;
|
||||
return this.driver.commitTransaction();
|
||||
return this.connection.driver.commitTransaction();
|
||||
})
|
||||
.catch(err => {
|
||||
return this.driver.rollbackTransaction()
|
||||
return this.connection.driver.rollbackTransaction()
|
||||
.then(() => {
|
||||
throw err;
|
||||
})
|
||||
@ -377,7 +373,7 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
.filter(entityWithId => entityWithId.id !== null && entityWithId.id !== undefined)
|
||||
.filter(entityWithId => !dbEntities.find(dbEntity => dbEntity.entityTarget === entityWithId.entityTarget && dbEntity.id === entityWithId.id))
|
||||
.map(entityWithId => {
|
||||
const metadata = this.entityMetadatas.findByTarget(entityWithId.entityTarget);
|
||||
const metadata = this.connection.entityMetadatas.findByTarget(entityWithId.entityTarget);
|
||||
const repository = this.connection.getRepository(entityWithId.entityTarget as any); // todo: fix type
|
||||
return repository.findOneById(entityWithId.id).then(loadedEntity => {
|
||||
if (!loadedEntity) return undefined;
|
||||
@ -430,15 +426,4 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
});
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Static Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Checks if given repository owns given metadata.
|
||||
*/
|
||||
static ownsMetadata(repository: Repository<any>, metadata: EntityMetadata) {
|
||||
return repository.metadata === metadata;
|
||||
}
|
||||
|
||||
}
|
||||
@ -17,18 +17,12 @@ export class RepositoryFactory {
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
createRepository(connection: Connection,
|
||||
broadcaster: Broadcaster,
|
||||
allMetadatas: EntityMetadataCollection,
|
||||
metadata: EntityMetadata) {
|
||||
return new Repository<any>(connection, broadcaster, allMetadatas, metadata);
|
||||
createRepository(connection: Connection, metadata: EntityMetadata) {
|
||||
return new Repository<any>(connection, metadata);
|
||||
}
|
||||
|
||||
createTreeRepository(connection: Connection,
|
||||
broadcaster: Broadcaster,
|
||||
allMetadatas: EntityMetadataCollection,
|
||||
metadata: EntityMetadata) {
|
||||
return new TreeRepository<any>(connection, broadcaster, allMetadatas, metadata);
|
||||
createTreeRepository(connection: Connection, metadata: EntityMetadata) {
|
||||
return new TreeRepository<any>(connection, metadata);
|
||||
}
|
||||
|
||||
createReactiveRepository(repository: Repository<any>) {
|
||||
|
||||
66
src/repository/RepositoryForMetadata.ts
Normal file
66
src/repository/RepositoryForMetadata.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import {Repository} from "./Repository";
|
||||
import {EntityMetadata} from "../metadata/EntityMetadata";
|
||||
import {ReactiveRepository} from "./ReactiveRepository";
|
||||
import {SpecificRepository} from "./SpecificRepository";
|
||||
import {SpecificReactiveRepository} from "./ReactiveSpecificRepository";
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {getFromContainer} from "../index";
|
||||
import {RepositoryFactory} from "./RepositoryFactory";
|
||||
import {TreeRepository} from "./TreeRepository";
|
||||
|
||||
/**
|
||||
* Aggregates all repositories of the specific metadata.
|
||||
*/
|
||||
export class RepositoryForMetadata {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Readonly properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Entity which owns repositories.
|
||||
*/
|
||||
public readonly metadata: EntityMetadata;
|
||||
|
||||
/**
|
||||
* All connection's repositories.
|
||||
*/
|
||||
public readonly repository: Repository<any>;
|
||||
|
||||
/**
|
||||
* All connection's reactive repositories.
|
||||
*/
|
||||
public readonly reactiveRepository: ReactiveRepository<any>;
|
||||
|
||||
/**
|
||||
* All connection's specific repositories.
|
||||
*/
|
||||
public readonly specificRepository: SpecificRepository<any>;
|
||||
|
||||
/**
|
||||
* All connection's specific reactive repositories.
|
||||
*/
|
||||
public readonly specificReactiveRepository: SpecificReactiveRepository<any>;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(connection: Connection, metadata: EntityMetadata) {
|
||||
const repositoryFactory = getFromContainer(RepositoryFactory);
|
||||
|
||||
this.metadata = metadata;
|
||||
|
||||
if (metadata.table.isClosure) {
|
||||
this.repository = repositoryFactory.createTreeRepository(connection, metadata);
|
||||
this.reactiveRepository = repositoryFactory.createReactiveTreeRepository(this.repository as TreeRepository<any>);
|
||||
} else {
|
||||
this.repository = repositoryFactory.createRepository(connection, metadata);
|
||||
this.reactiveRepository = repositoryFactory.createReactiveRepository(this.repository);
|
||||
}
|
||||
|
||||
this.specificRepository = repositoryFactory.createSpecificRepository(connection, metadata, this.repository);
|
||||
this.specificReactiveRepository = repositoryFactory.createSpecificReactiveRepository(this.specificRepository);
|
||||
}
|
||||
|
||||
}
|
||||
@ -358,15 +358,4 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
});
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Static Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Checks if given repository owns given metadata.
|
||||
*/
|
||||
static ownsMetadata(specificRepository: SpecificRepository<any>, metadata: EntityMetadata) {
|
||||
return Repository.ownsMetadata(specificRepository.repository, metadata);
|
||||
}
|
||||
|
||||
}
|
||||
@ -39,16 +39,16 @@ describe("ConnectionManager", () => {
|
||||
|
||||
it("should create a connection with the given connection name and driver", () => {
|
||||
const connectionManager = new ConnectionManager();
|
||||
const connection = connectionManager.createConnection("newConnection", new MysqlDriver(), createTestingConnectionOptions("mysql"));
|
||||
const connection = connectionManager.createConnection("newConnection", new MysqlDriver(createTestingConnectionOptions("mysql")));
|
||||
connection.name.should.be.equal("newConnection");
|
||||
connection.driver.should.be.instanceOf(MysqlDriver);
|
||||
});
|
||||
|
||||
it("should replace old connection with the given name if it exist", () => {
|
||||
const connectionManager = new ConnectionManager();
|
||||
const connection = connectionManager.createConnection("newConnection", new MysqlDriver(), createTestingConnectionOptions("mysql"));
|
||||
const connection = connectionManager.createConnection("newConnection", new MysqlDriver(createTestingConnectionOptions("mysql")));
|
||||
connectionManager.get("newConnection").should.be.equal(connection);
|
||||
const againConnection = connectionManager.createConnection("newConnection", new MysqlDriver(), createTestingConnectionOptions("mysql"));
|
||||
const againConnection = connectionManager.createConnection("newConnection", new MysqlDriver(createTestingConnectionOptions("mysql")));
|
||||
connectionManager.get("newConnection").should.be.equal(againConnection);
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user