mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
refactored connection manager and connection parts
This commit is contained in:
parent
5a0d054d77
commit
e00c5ffed3
33
sample/sample12-custom-naming-strategy/app.ts
Normal file
33
sample/sample12-custom-naming-strategy/app.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import {createConnection, CreateConnectionOptions} from "../../src/typeorm";
|
||||
import {Post} from "./entity/Post";
|
||||
import {CustomNamingStrategy} from "./naming-strategy/CustomNamingStrategy";
|
||||
|
||||
const options: CreateConnectionOptions = {
|
||||
driver: "mysql",
|
||||
connection: {
|
||||
host: "192.168.99.100",
|
||||
port: 3306,
|
||||
username: "root",
|
||||
password: "admin",
|
||||
database: "test",
|
||||
autoSchemaCreate: true,
|
||||
namingStrategy: "custom_strategy"
|
||||
},
|
||||
entities: [Post],
|
||||
namingStrategies: [CustomNamingStrategy]
|
||||
};
|
||||
|
||||
createConnection(options).then(connection => {
|
||||
|
||||
let post = new Post();
|
||||
post.text = "Hello how are you?";
|
||||
post.title = "hello";
|
||||
|
||||
let postRepository = connection.getRepository<Post>(Post);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.then(post => console.log("Post has been saved"))
|
||||
.catch(error => console.log("Cannot save. Error: ", error));
|
||||
|
||||
}, error => console.log("Cannot connect: ", error));
|
||||
19
sample/sample12-custom-naming-strategy/entity/Post.ts
Normal file
19
sample/sample12-custom-naming-strategy/entity/Post.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import {PrimaryColumn, Column} from "../../../src/columns";
|
||||
import {Table} from "../../../src/tables";
|
||||
|
||||
@Table("sample1_post")
|
||||
export class Post {
|
||||
|
||||
@PrimaryColumn("int", { autoIncrement: true })
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Column()
|
||||
text: string;
|
||||
|
||||
@Column()
|
||||
likesCount: number;
|
||||
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
import * as _ from "lodash";
|
||||
import {NamingStrategyInterface} from "../../../src/naming-strategy/NamingStrategy";
|
||||
import {NamingStrategy} from "../../../src/decorator/NamingStrategy";
|
||||
|
||||
@NamingStrategy("custom_strategy")
|
||||
export class CustomNamingStrategy implements NamingStrategyInterface {
|
||||
|
||||
tableName(className: string): string {
|
||||
return _.snakeCase(className);
|
||||
}
|
||||
|
||||
columnName(propertyName: string): string {
|
||||
return _.snakeCase(propertyName);
|
||||
}
|
||||
|
||||
relationName(propertyName: string): string {
|
||||
return _.snakeCase(propertyName);
|
||||
}
|
||||
|
||||
}
|
||||
93
src/connection-manager/ConnectionManager.ts
Normal file
93
src/connection-manager/ConnectionManager.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {ConnectionNotFoundError} from "./error/ConnectionNotFoundError";
|
||||
import {MysqlDriver} from "../driver/MysqlDriver";
|
||||
import {CreateConnectionOptions} from "./CreateConnectionOptions";
|
||||
import {ConnectionOptions} from "../connection/ConnectionOptions";
|
||||
import {Driver} from "../driver/Driver";
|
||||
import {MissingDriverError} from "./error/MissingDriverError";
|
||||
|
||||
/**
|
||||
* Connection manager holds all connections made to the databases and providers helper management functions
|
||||
* for all exist connections.
|
||||
*/
|
||||
export class ConnectionManager {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private connections: Connection[] = [];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates a new connection based on the given connection options and registers a new connection in the manager.
|
||||
*/
|
||||
create(options: CreateConnectionOptions): Promise<Connection> {
|
||||
const driver = this.createDriver(options.driver);
|
||||
const connection = this.createConnection(options.connectionName || "default", driver, options.connection);
|
||||
|
||||
if (options.entityDirectories && options.entityDirectories.length > 0)
|
||||
connection.importEntitiesFromDirectories(options.entityDirectories);
|
||||
|
||||
if (options.entities)
|
||||
connection.importEntities(options.entities);
|
||||
|
||||
if (options.subscriberDirectories && options.subscriberDirectories.length > 0)
|
||||
connection.importSubscribersFromDirectories(options.subscriberDirectories);
|
||||
|
||||
if (options.subscribers)
|
||||
connection.importSubscribers(options.subscribers);
|
||||
|
||||
if (options.namingStrategyDirectories && options.namingStrategyDirectories.length > 0)
|
||||
connection.importNamingStrategiesFromDirectories(options.namingStrategyDirectories);
|
||||
|
||||
if (options.namingStrategies)
|
||||
connection.importNamingStrategies(options.namingStrategies);
|
||||
|
||||
return connection.connect().then(() => connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets registered connection with the given name. If connection name is not given then it will get a default
|
||||
* connection.
|
||||
*/
|
||||
get(name: string = "default"): Connection {
|
||||
if (!name) name = "default";
|
||||
|
||||
const connection = this.connections.find(connection => connection.name === name);
|
||||
if (!connection)
|
||||
throw new ConnectionNotFoundError(name);
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private createDriver(driverName: string) {
|
||||
switch (driverName) {
|
||||
case "mysql":
|
||||
return new MysqlDriver();
|
||||
default:
|
||||
throw new MissingDriverError(driverName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new connection and pushes a connection to the array.
|
||||
*/
|
||||
createConnection(name: string, driver: Driver, options: ConnectionOptions) {
|
||||
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> driver, options);
|
||||
this.connections.push(connection);
|
||||
return connection;
|
||||
}
|
||||
|
||||
}
|
||||
53
src/connection-manager/CreateConnectionOptions.ts
Normal file
53
src/connection-manager/CreateConnectionOptions.ts
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
import {ConnectionOptions} from "../connection/ConnectionOptions";
|
||||
|
||||
/**
|
||||
* All options to help to create a new connection.
|
||||
*/
|
||||
export interface CreateConnectionOptions {
|
||||
|
||||
/**
|
||||
* Driver type. Mysql is the only driver supported at this moment.
|
||||
*/
|
||||
driver: "mysql";
|
||||
|
||||
/**
|
||||
* Database connection options.
|
||||
*/
|
||||
connection: ConnectionOptions;
|
||||
|
||||
/**
|
||||
* Connection name. By default its called "default". Different connections must have different names.
|
||||
*/
|
||||
connectionName?: string;
|
||||
|
||||
/**
|
||||
* Entities to be loaded for the new connection.
|
||||
*/
|
||||
entities?: Function[];
|
||||
|
||||
/**
|
||||
* Subscribers to be loaded for the new connection.
|
||||
*/
|
||||
subscribers?: Function[];
|
||||
|
||||
/**
|
||||
* Naming strategies to be loaded.
|
||||
*/
|
||||
namingStrategies?: Function[];
|
||||
|
||||
/**
|
||||
* List of directories from where entities will be loaded.
|
||||
*/
|
||||
entityDirectories?: string[];
|
||||
|
||||
/**
|
||||
* List of directories from where subscribers will be loaded.
|
||||
*/
|
||||
subscriberDirectories?: string[];
|
||||
|
||||
/**
|
||||
* List of directories from where naming strategies will be loaded.
|
||||
*/
|
||||
namingStrategyDirectories?: string[];
|
||||
}
|
||||
12
src/connection-manager/error/MissingDriverError.ts
Normal file
12
src/connection-manager/error/MissingDriverError.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class MissingDriverError extends Error {
|
||||
name = "MissingDriverError";
|
||||
|
||||
constructor(driverName: string) {
|
||||
super();
|
||||
this.message = `Wrong driver ${driverName} given. Supported drivers are: "mysql"`;
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,11 +5,19 @@ import {EventSubscriberInterface} from "../subscriber/EventSubscriberInterface";
|
||||
import {RepositoryNotFoundError} from "./error/RepositoryNotFoundError";
|
||||
import {EntityMetadata} from "../metadata-builder/metadata/EntityMetadata";
|
||||
import {SchemaCreator} from "../schema-creator/SchemaCreator";
|
||||
import {MetadataNotFoundError} from "./error/MetadataNotFoundError";
|
||||
import {ConstructorFunction} from "../common/ConstructorFunction";
|
||||
import {EntityListenerMetadata} from "../metadata-builder/metadata/EntityListenerMetadata";
|
||||
import {EntityManager} from "../repository/EntityManager";
|
||||
import {importClassesFromDirectories} from "../util/DirectoryExportedClassesLoader";
|
||||
import {defaultMetadataStorage, getContainer} from "../typeorm";
|
||||
import {EntityMetadataBuilder} from "../metadata-builder/EntityMetadataBuilder";
|
||||
import {DefaultNamingStrategy} from "../naming-strategy/DefaultNamingStrategy";
|
||||
import {EntityMetadataArray} from "../metadata-builder/metadata/EntityMetadataArray";
|
||||
import {NamingStrategyMetadata} from "../metadata-builder/metadata/NamingStrategyMetadata";
|
||||
|
||||
/**
|
||||
* Temporary type to store and link both repository and its metadata.
|
||||
*/
|
||||
type RepositoryAndMetadata = { repository: Repository<any>, metadata: EntityMetadata };
|
||||
|
||||
/**
|
||||
@ -27,11 +35,6 @@ export class Connection {
|
||||
// Readonly properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Database connection options.
|
||||
*/
|
||||
readonly options: ConnectionOptions;
|
||||
|
||||
/**
|
||||
* Gets EntityManager of this connection.
|
||||
*/
|
||||
@ -47,11 +50,6 @@ export class Connection {
|
||||
*/
|
||||
readonly driver: Driver;
|
||||
|
||||
/**
|
||||
* All entity metadatas that are registered for this connection.
|
||||
*/
|
||||
private readonly entityMetadatas: EntityMetadata[] = [];
|
||||
|
||||
/**
|
||||
* All entity listener metadatas that are registered for this connection.
|
||||
*/
|
||||
@ -60,7 +58,41 @@ export class Connection {
|
||||
/**
|
||||
* All subscribers that are registered for this connection.
|
||||
*/
|
||||
readonly subscribers: EventSubscriberInterface<any>[] = [];
|
||||
readonly subscriberMetadatas: EventSubscriberInterface<any>[] = [];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Connection options.
|
||||
*/
|
||||
private readonly options: ConnectionOptions;
|
||||
|
||||
/**
|
||||
* All entity metadatas that are registered for this connection.
|
||||
*/
|
||||
private readonly entityMetadatas = new EntityMetadataArray();
|
||||
|
||||
/**
|
||||
* All naming strategy metadatas that are registered for this connection.
|
||||
*/
|
||||
private readonly namingStrategyMetadatas: NamingStrategyMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Registered entity classes to be used for this connection.
|
||||
*/
|
||||
private readonly entityClasses: Function[] = [];
|
||||
|
||||
/**
|
||||
* Registered subscriber classes to be used for this connection.
|
||||
*/
|
||||
private readonly subscriberClasses: Function[] = [];
|
||||
|
||||
/**
|
||||
* Registered naming strategy classes to be used for this connection.
|
||||
*/
|
||||
private readonly namingStrategyClasses: Function[] = [];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
@ -74,17 +106,6 @@ export class Connection {
|
||||
this.entityManager = new EntityManager(this);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Accessors
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* All repositories that are registered for this connection.
|
||||
*/
|
||||
get repositories(): Repository<any>[] {
|
||||
return this.repositoryAndMetadatas.map(repoAndMeta => repoAndMeta.repository);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
@ -94,6 +115,11 @@ export class Connection {
|
||||
*/
|
||||
connect(): Promise<void> {
|
||||
return this.driver.connect().then(() => {
|
||||
|
||||
// build all metadata
|
||||
this.registerMetadatas();
|
||||
|
||||
// second build schema
|
||||
if (this.options.autoSchemaCreate === true)
|
||||
return this.createSchema();
|
||||
|
||||
@ -101,14 +127,6 @@ export class Connection {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates database schema for all entities registered in this connection.
|
||||
*/
|
||||
createSchema() {
|
||||
const schemaCreator = new SchemaCreator(this, this.entityMetadatas);
|
||||
return schemaCreator.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this connection.
|
||||
*/
|
||||
@ -116,12 +134,20 @@ export class Connection {
|
||||
return this.driver.disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates database schema for all entities registered in this connection.
|
||||
*/
|
||||
createSchema() {
|
||||
const schemaBuilder = this.driver.createSchemaBuilder();
|
||||
const schemaCreator = new SchemaCreator(schemaBuilder, this.entityMetadatas);
|
||||
return schemaCreator.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets repository for the given entity class.
|
||||
*/
|
||||
getRepository<Entity>(entityClass: ConstructorFunction<Entity>|Function): Repository<Entity> {
|
||||
// const metadata = this.getEntityMetadata(entityClass);
|
||||
const metadata = this.entityMetadatas.find(metadata => metadata.target === entityClass);
|
||||
const metadata = this.entityMetadatas.findByTarget(entityClass);
|
||||
const repoMeta = this.repositoryAndMetadatas.find(repoMeta => repoMeta.metadata === metadata);
|
||||
if (!repoMeta)
|
||||
throw new RepositoryNotFoundError(entityClass);
|
||||
@ -130,34 +156,97 @@ export class Connection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers entity metadatas for the current connection.
|
||||
* Imports entities from the given paths (directories) for the current connection.
|
||||
*/
|
||||
addEntityMetadatas(metadatas: EntityMetadata[]): Connection {
|
||||
this.entityMetadatas.push(...metadatas);
|
||||
this.repositoryAndMetadatas = this.repositoryAndMetadatas.concat(metadatas.map(metadata => this.createRepoMeta(metadata)));
|
||||
importEntitiesFromDirectories(paths: string[]): void {
|
||||
this.importEntities(importClassesFromDirectories(paths));
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports subscribers from the given paths (directories) for the current connection.
|
||||
*/
|
||||
importSubscribersFromDirectories(paths: string[]): void {
|
||||
this.importSubscribers(importClassesFromDirectories(paths));
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports naming strategies from the given paths (directories) for the current connection.
|
||||
*/
|
||||
importNamingStrategiesFromDirectories(paths: string[]): void {
|
||||
this.importEntities(importClassesFromDirectories(paths));
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports entities for the current connection.
|
||||
*/
|
||||
importEntities(entities: Function[]): this {
|
||||
this.entityClasses.push(...entities);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers entity listener metadatas for the current connection.
|
||||
* Imports entities for the given connection. If connection name is not given then default connection is used.
|
||||
*/
|
||||
addEntityListenerMetadatas(metadatas: EntityListenerMetadata[]): Connection {
|
||||
this.entityListeners.push(...metadatas);
|
||||
importSubscribers(subscriberClasses: Function[]): this {
|
||||
this.subscriberClasses.push(...subscriberClasses);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers subscribers for the current connection.
|
||||
* Imports entities for the current connection.
|
||||
*/
|
||||
addSubscribers(subscribers: EventSubscriberInterface<any>[]): Connection {
|
||||
this.subscribers.push(...subscribers);
|
||||
importNamingStrategies(strategies: Function[]): this {
|
||||
this.namingStrategyClasses.push(...strategies);
|
||||
return this;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private registerMetadatas() {
|
||||
|
||||
// first register naming strategies
|
||||
const metadatas = defaultMetadataStorage().findNamingStrategiesForClasses(this.namingStrategyClasses);
|
||||
this.namingStrategyMetadatas.push(...metadatas);
|
||||
|
||||
// second register subscriber metadatas
|
||||
const subscribers = defaultMetadataStorage()
|
||||
.findEventSubscribersForClasses(this.subscriberClasses)
|
||||
.map(metadata => this.createContainerInstance(metadata.target));
|
||||
this.subscriberMetadatas.push(...subscribers);
|
||||
|
||||
// third register entity and entity listener metadatas
|
||||
const entityMetadataBuilder = new EntityMetadataBuilder(this.createNamingStrategy());
|
||||
const entityMetadatas = entityMetadataBuilder.build(this.entityClasses);
|
||||
const entityListenerMetadatas = defaultMetadataStorage().findEntityListenersForClasses(this.entityClasses);
|
||||
|
||||
this.entityMetadatas.push(...entityMetadatas);
|
||||
this.entityListeners.push(...entityListenerMetadatas);
|
||||
this.repositoryAndMetadatas.push(...entityMetadatas.map(metadata => this.createRepoMeta(metadata)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the naming strategy
|
||||
*/
|
||||
private createNamingStrategy() {
|
||||
if (!this.options.namingStrategy)
|
||||
return new DefaultNamingStrategy();
|
||||
|
||||
const namingMetadata = this.namingStrategyMetadatas.find(strategy => strategy.name === this.options.namingStrategy);
|
||||
return this.createContainerInstance(namingMetadata.target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the given constructor. If IOC Container is registered in the ORM
|
||||
*/
|
||||
private createContainerInstance(constructor: Function) {
|
||||
return getContainer() ? getContainer().get(constructor) : new (<any> constructor)();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a temporary object RepositoryAndMetadata to store mapping between repository and metadata.
|
||||
*/
|
||||
private createRepoMeta(metadata: EntityMetadata): RepositoryAndMetadata {
|
||||
return {
|
||||
metadata: metadata,
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
import {Connection} from "./Connection";
|
||||
import {Driver} from "../driver/Driver";
|
||||
import {ConnectionOptions} from "./ConnectionOptions";
|
||||
|
||||
/**
|
||||
* Array for the connections.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export class ConnectionArray extends Array<Connection> {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates a new connection and pushes a connection to the array.
|
||||
*/
|
||||
createAndPush(name: string, driver: Driver, options: ConnectionOptions) {
|
||||
this.removeByName(name);
|
||||
const connection = new Connection(name, <Driver> driver, options);
|
||||
this.push(connection);
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets connection with a given name.
|
||||
*/
|
||||
getWithName(name: string) {
|
||||
return this.find(connection => connection.name === name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if connection with a given name exist.
|
||||
*/
|
||||
hasWithName(name: string) {
|
||||
return !!this.getWithName(name);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private removeByName(name: string) {
|
||||
const existConnection = this.find(connection => connection.name === name);
|
||||
if (existConnection)
|
||||
this.splice(this.indexOf(existConnection), 1);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,166 +0,0 @@
|
||||
import {Connection} from "./Connection";
|
||||
import {defaultMetadataStorage} from "../metadata-builder/MetadataStorage";
|
||||
import {Driver} from "../driver/Driver";
|
||||
import {DefaultNamingStrategy} from "../naming-strategy/DefaultNamingStrategy";
|
||||
import {ConnectionNotFoundError} from "./error/ConnectionNotFoundError";
|
||||
import {EntityMetadataBuilder} from "../metadata-builder/EntityMetadataBuilder";
|
||||
import {importClassesFromDirectories} from "../util/DirectoryExportedClassesLoader";
|
||||
import {ConnectionOptions} from "tls";
|
||||
import {NamingStrategy} from "../naming-strategy/NamingStrategy";
|
||||
import {CannotSetNamingStrategyError} from "./error/CannotSetNamingStrategyError";
|
||||
import {ConnectionArray} from "./ConnectionArray";
|
||||
|
||||
/**
|
||||
* Connection manager holds all connections made to the databases and providers helper management functions
|
||||
* for all exist connections.
|
||||
*/
|
||||
export class ConnectionManager {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private connections = new ConnectionArray();
|
||||
private _entityMetadataBuilder: EntityMetadataBuilder;
|
||||
private _namingStrategy: NamingStrategy;
|
||||
private _container: { get(someClass: any): any };
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Accessors
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Sets a container that can be used in custom user subscribers. This allows to inject services in subscribers.
|
||||
*/
|
||||
set container(container: { get(someClass: Function): any }) {
|
||||
this._container = container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the naming strategy to be used instead of DefaultNamingStrategy.
|
||||
*/
|
||||
set namingStrategy(namingStrategy: NamingStrategy) {
|
||||
|
||||
// if entity metadata builder already initialized then strategy already is used there, and setting a new naming
|
||||
// strategy is pointless
|
||||
if (this._entityMetadataBuilder)
|
||||
throw new CannotSetNamingStrategyError();
|
||||
|
||||
this._namingStrategy = namingStrategy;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates and adds a new connection with given driver.
|
||||
*/
|
||||
createConnection(driver: Driver, options: ConnectionOptions): Connection;
|
||||
createConnection(name: string|undefined, driver: Driver, options: ConnectionOptions): Connection;
|
||||
createConnection(nameOrDriver: string|undefined|Driver, driverOrOptions?: Driver|ConnectionOptions, maybeOptions?: ConnectionOptions): Connection {
|
||||
const name = typeof nameOrDriver === "string" ? nameOrDriver : "default";
|
||||
const driver = typeof nameOrDriver === "object" ? <Driver> nameOrDriver : <Driver> driverOrOptions;
|
||||
const options = typeof nameOrDriver === "object" ? <ConnectionOptions> driverOrOptions : <ConnectionOptions> maybeOptions;
|
||||
|
||||
return this.connections.createAndPush(name, driver, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets registered connection with the given name. If connection name is not given then it will get a default
|
||||
* connection.
|
||||
*/
|
||||
getConnection(name: string = "default"): Connection {
|
||||
if (!name) name = "default";
|
||||
|
||||
if (!this.connections.hasWithName(name))
|
||||
throw new ConnectionNotFoundError(name);
|
||||
|
||||
return this.connections.getWithName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports entities from the given paths (directories) for the given connection. If connection name is not given
|
||||
* then default connection is used.
|
||||
*/
|
||||
importEntitiesFromDirectories(paths: string[]): void;
|
||||
importEntitiesFromDirectories(connectionName: string|undefined, paths: string[]): void;
|
||||
importEntitiesFromDirectories(connectionNameOrPaths: string|string[]|undefined, maybePaths?: string[]): void {
|
||||
const connectionName = typeof connectionNameOrPaths === "string" ? connectionNameOrPaths : "default";
|
||||
const paths = maybePaths ? <string[]> maybePaths : <string[]> connectionNameOrPaths;
|
||||
|
||||
this.importEntities(connectionName, importClassesFromDirectories(paths));
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports subscribers from the given paths (directories) for the given connection. If connection name is not given
|
||||
* then default connection is used.
|
||||
*/
|
||||
importSubscribersFromDirectories(paths: string[]): void;
|
||||
importSubscribersFromDirectories(connectionName: string|undefined, paths: string[]): void;
|
||||
importSubscribersFromDirectories(connectionNameOrPaths: string|string[]|undefined, maybePaths?: string[]): void {
|
||||
const connectionName = typeof connectionNameOrPaths === "string" ? connectionNameOrPaths : "default";
|
||||
const paths = maybePaths ? <string[]> maybePaths : <string[]> connectionNameOrPaths;
|
||||
|
||||
this.importSubscribers(connectionName, importClassesFromDirectories(paths));
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports entities for the given connection. If connection name is not given then default connection is used.
|
||||
*/
|
||||
importEntities(entities: Function[]): void;
|
||||
importEntities(connectionName: string|undefined, entities: Function[]): void;
|
||||
importEntities(connectionNameOrEntities: string|undefined|Function[], maybeEntities?: Function[]): void {
|
||||
const connectionName = typeof connectionNameOrEntities === "string" ? connectionNameOrEntities : "default";
|
||||
const entities = maybeEntities ? <Function[]> maybeEntities : <Function[]> connectionNameOrEntities;
|
||||
|
||||
// console.log("entities", entities);
|
||||
|
||||
const entityMetadatas = this.entityMetadataBuilder.build(entities);
|
||||
const entityListenerMetadatas = defaultMetadataStorage.findEntityListenersForClasses(entities);
|
||||
|
||||
this.getConnection(connectionName)
|
||||
.addEntityMetadatas(entityMetadatas)
|
||||
.addEntityListenerMetadatas(entityListenerMetadatas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports entities for the given connection. If connection name is not given then default connection is used.
|
||||
*/
|
||||
importSubscribers(subscriberClasses: Function[]): void;
|
||||
importSubscribers(connectionName: string|undefined, subscriberClasses: Function[]): void;
|
||||
importSubscribers(connectionNameOrSubscriberClasses: string|undefined|Function[], maybeSubscriberClasses?: Function[]): void {
|
||||
const connectionName = typeof connectionNameOrSubscriberClasses === "string" ? connectionNameOrSubscriberClasses : "default";
|
||||
const subscriberClasses = maybeSubscriberClasses ? <Function[]> maybeSubscriberClasses : <Function[]> connectionNameOrSubscriberClasses;
|
||||
|
||||
const subscribers = defaultMetadataStorage
|
||||
.findEventSubscribersForClasses(subscriberClasses)
|
||||
.map(metadata => this.createContainerInstance(metadata.target));
|
||||
|
||||
this.getConnection(connectionName).addSubscribers(subscribers);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* We need to lazily initialize EntityMetadataBuilder because naming strategy can be set before we use entityMetadataBuilder.
|
||||
*/
|
||||
private get entityMetadataBuilder() {
|
||||
if (!this._entityMetadataBuilder) {
|
||||
const namingStrategy = this._namingStrategy ? this._namingStrategy : new DefaultNamingStrategy();
|
||||
this._entityMetadataBuilder = new EntityMetadataBuilder(defaultMetadataStorage, namingStrategy);
|
||||
}
|
||||
|
||||
return this._entityMetadataBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the given constructor.
|
||||
*/
|
||||
private createContainerInstance(constructor: Function) {
|
||||
return this._container ? this._container.get(constructor) : new (<any> constructor)();
|
||||
}
|
||||
|
||||
}
|
||||
@ -38,6 +38,11 @@ export interface ConnectionOptions {
|
||||
*/
|
||||
autoSchemaCreate?: boolean;
|
||||
|
||||
/**
|
||||
* Name of the naming strategy to be used on this connection.
|
||||
*/
|
||||
namingStrategy?: string;
|
||||
|
||||
/**
|
||||
* Logging options.
|
||||
*/
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class BroadcasterNotFoundError extends Error {
|
||||
name = "BroadcasterNotFoundError";
|
||||
|
||||
constructor(entityClassOrName: string|Function) {
|
||||
super();
|
||||
const name = entityClassOrName instanceof Function ? (<any> entityClassOrName).name : entityClassOrName;
|
||||
this.message = `No broadcaster for "${name}" was found. Looks like this entity is not registered in your connection?`;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class CannotSetNamingStrategyError extends Error {
|
||||
name = "CannotSetNamingStrategyError";
|
||||
message = "Cannot set naming strategy. Naming strategy must be set right after ConnectionManager is created, and before any entity importing is done.";
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class MetadataNotFoundError extends Error {
|
||||
name = "MetadataNotFoundError";
|
||||
|
||||
constructor(entityClass: Function) {
|
||||
super();
|
||||
this.message = `No metadata for ${entityClass} has been found!`;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class SchemaNotFoundError extends Error {
|
||||
name = "SchemaNotFoundError";
|
||||
|
||||
constructor(entityClassOrName: string|Function) {
|
||||
super();
|
||||
const name = entityClassOrName instanceof Function ? (<any> entityClassOrName).name : entityClassOrName;
|
||||
this.message = `No schema for "${name}" was found. Looks like this entity is not registered in your connection?`;
|
||||
}
|
||||
|
||||
}
|
||||
13
src/decorator/NamingStrategy.ts
Normal file
13
src/decorator/NamingStrategy.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import "reflect-metadata";
|
||||
import {NamingStrategyMetadata} from "../metadata-builder/metadata/NamingStrategyMetadata";
|
||||
import {defaultMetadataStorage} from "../typeorm";
|
||||
|
||||
/**
|
||||
* Decorator registers a new naming strategy to be used in naming things.
|
||||
*/
|
||||
export function NamingStrategy(name?: string): Function {
|
||||
return function (target: Function) {
|
||||
const strategyName = name ? name : (<any> target).name;
|
||||
defaultMetadataStorage().addNamingStrategyMetadata(new NamingStrategyMetadata(target, strategyName));
|
||||
};
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
import {ColumnOptions} from "../../metadata-builder/options/ColumnOptions";
|
||||
import {ColumnTypeUndefinedError} from "../error/ColumnTypeUndefinedError";
|
||||
import {AutoIncrementOnlyForPrimaryError} from "../error/AutoIncrementOnlyForPrimaryError";
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {ColumnMetadata} from "../../metadata-builder/metadata/ColumnMetadata";
|
||||
import {ColumnType, ColumnTypes} from "../../metadata-builder/types/ColumnTypes";
|
||||
import "reflect-metadata";
|
||||
@ -53,7 +53,7 @@ export function Column(typeOrOptions?: ColumnType|ColumnOptions, options?: Colum
|
||||
throw new AutoIncrementOnlyForPrimaryError(object, propertyName);
|
||||
|
||||
// create and register a new column metadata
|
||||
defaultMetadataStorage.addColumnMetadata(new ColumnMetadata({
|
||||
defaultMetadataStorage().addColumnMetadata(new ColumnMetadata({
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
propertyType: reflectedType,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {ColumnOptions} from "../../metadata-builder/options/ColumnOptions";
|
||||
import {ColumnType, ColumnTypes} from "../../metadata-builder/types/ColumnTypes";
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {ColumnMetadata} from "../../metadata-builder/metadata/ColumnMetadata";
|
||||
import "reflect-metadata";
|
||||
|
||||
@ -20,7 +20,7 @@ export function CreateDateColumn(options?: ColumnOptions): Function {
|
||||
columnOptions.type = ColumnTypes.DATETIME;
|
||||
|
||||
// create and register a new column metadata
|
||||
defaultMetadataStorage.addColumnMetadata(new ColumnMetadata({
|
||||
defaultMetadataStorage().addColumnMetadata(new ColumnMetadata({
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
propertyType: reflectedType,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {ColumnOptions} from "../../metadata-builder/options/ColumnOptions";
|
||||
import {ColumnType, ColumnTypes} from "../../metadata-builder/types/ColumnTypes";
|
||||
import {ColumnTypeUndefinedError} from "../error/ColumnTypeUndefinedError";
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {ColumnMetadata} from "../../metadata-builder/metadata/ColumnMetadata";
|
||||
import {PrimaryColumnCannotBeNullableError} from "../error/PrimaryColumnCannotBeNullableError";
|
||||
import "reflect-metadata";
|
||||
@ -56,7 +56,7 @@ export function PrimaryColumn(typeOrOptions?: ColumnType|ColumnOptions, options?
|
||||
throw new PrimaryColumnCannotBeNullableError(object, propertyName);
|
||||
|
||||
// create and register a new column metadata
|
||||
defaultMetadataStorage.addColumnMetadata(new ColumnMetadata({
|
||||
defaultMetadataStorage().addColumnMetadata(new ColumnMetadata({
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
propertyType: reflectedType,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {ColumnOptions} from "../../metadata-builder/options/ColumnOptions";
|
||||
import {ColumnType, ColumnTypes} from "../../metadata-builder/types/ColumnTypes";
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {ColumnMetadata} from "../../metadata-builder/metadata/ColumnMetadata";
|
||||
import "reflect-metadata";
|
||||
|
||||
@ -20,7 +20,7 @@ export function UpdateDateColumn(options?: ColumnOptions): Function {
|
||||
columnOptions.type = ColumnTypes.DATETIME;
|
||||
|
||||
// create and register a new column metadata
|
||||
defaultMetadataStorage.addColumnMetadata(new ColumnMetadata({
|
||||
defaultMetadataStorage().addColumnMetadata(new ColumnMetadata({
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
propertyType: reflectedType,
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import {CompoundIndexMetadata} from "../../metadata-builder/metadata/CompoundIndexMetadata";
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
|
||||
/**
|
||||
* Compound indexes must be set on entity classes and must specify fields to be indexed.
|
||||
*/
|
||||
export function CompoundIndex(fields: string[]) {
|
||||
return function (cls: Function) {
|
||||
defaultMetadataStorage.addCompoundIndexMetadata(new CompoundIndexMetadata(cls, fields));
|
||||
defaultMetadataStorage().addCompoundIndexMetadata(new CompoundIndexMetadata(cls, fields));
|
||||
};
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {IndexMetadata} from "../../metadata-builder/metadata/IndexMetadata";
|
||||
|
||||
/**
|
||||
@ -6,6 +6,6 @@ import {IndexMetadata} from "../../metadata-builder/metadata/IndexMetadata";
|
||||
*/
|
||||
export function Index(name?: string) {
|
||||
return function (object: Object, propertyName: string) {
|
||||
defaultMetadataStorage.addIndexMetadata(new IndexMetadata(object.constructor, propertyName, name));
|
||||
defaultMetadataStorage().addIndexMetadata(new IndexMetadata(object.constructor, propertyName, name));
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {EventListenerTypes} from "../../metadata-builder/types/EventListenerTypes";
|
||||
import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityListenerMetadata";
|
||||
|
||||
@ -7,7 +7,7 @@ import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityList
|
||||
*/
|
||||
export function AfterInsert() {
|
||||
return function (object: Object, propertyName: string) {
|
||||
defaultMetadataStorage.addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
defaultMetadataStorage().addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
object.constructor,
|
||||
propertyName,
|
||||
EventListenerTypes.AFTER_INSERT
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {EventListenerTypes} from "../../metadata-builder/types/EventListenerTypes";
|
||||
import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityListenerMetadata";
|
||||
|
||||
@ -7,7 +7,7 @@ import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityList
|
||||
*/
|
||||
export function AfterLoad() {
|
||||
return function (object: Object, propertyName: string) {
|
||||
defaultMetadataStorage.addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
defaultMetadataStorage().addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
object.constructor,
|
||||
propertyName,
|
||||
EventListenerTypes.AFTER_LOAD
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {EventListenerTypes} from "../../metadata-builder/types/EventListenerTypes";
|
||||
import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityListenerMetadata";
|
||||
|
||||
@ -7,7 +7,7 @@ import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityList
|
||||
*/
|
||||
export function AfterRemove() {
|
||||
return function (object: Object, propertyName: string) {
|
||||
defaultMetadataStorage.addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
defaultMetadataStorage().addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
object.constructor,
|
||||
propertyName,
|
||||
EventListenerTypes.AFTER_REMOVE
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {EventListenerTypes} from "../../metadata-builder/types/EventListenerTypes";
|
||||
import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityListenerMetadata";
|
||||
|
||||
@ -7,7 +7,7 @@ import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityList
|
||||
*/
|
||||
export function AfterUpdate() {
|
||||
return function (object: Object, propertyName: string) {
|
||||
defaultMetadataStorage.addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
defaultMetadataStorage().addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
object.constructor,
|
||||
propertyName,
|
||||
EventListenerTypes.AFTER_UPDATE
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {EventListenerTypes} from "../../metadata-builder/types/EventListenerTypes";
|
||||
import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityListenerMetadata";
|
||||
|
||||
@ -7,7 +7,7 @@ import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityList
|
||||
*/
|
||||
export function BeforeInsert() {
|
||||
return function (object: Object, propertyName: string) {
|
||||
defaultMetadataStorage.addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
defaultMetadataStorage().addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
object.constructor,
|
||||
propertyName,
|
||||
EventListenerTypes.BEFORE_INSERT
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {EventListenerTypes} from "../../metadata-builder/types/EventListenerTypes";
|
||||
import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityListenerMetadata";
|
||||
|
||||
@ -7,7 +7,7 @@ import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityList
|
||||
*/
|
||||
export function BeforeRemove() {
|
||||
return function (object: Object, propertyName: string) {
|
||||
defaultMetadataStorage.addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
defaultMetadataStorage().addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
object.constructor,
|
||||
propertyName,
|
||||
EventListenerTypes.BEFORE_REMOVE
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {EventListenerTypes} from "../../metadata-builder/types/EventListenerTypes";
|
||||
import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityListenerMetadata";
|
||||
|
||||
@ -7,7 +7,7 @@ import {EntityListenerMetadata} from "../../metadata-builder/metadata/EntityList
|
||||
*/
|
||||
export function BeforeUpdate() {
|
||||
return function (object: Object, propertyName: string) {
|
||||
defaultMetadataStorage.addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
defaultMetadataStorage().addEntityListenerMetadata(new EntityListenerMetadata(
|
||||
object.constructor,
|
||||
propertyName,
|
||||
EventListenerTypes.BEFORE_UPDATE
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {EventSubscriberMetadata} from "../../metadata-builder/metadata/EventSubscriberMetadata";
|
||||
|
||||
/**
|
||||
@ -7,6 +7,6 @@ import {EventSubscriberMetadata} from "../../metadata-builder/metadata/EventSubs
|
||||
*/
|
||||
export function EventSubscriber() {
|
||||
return function (target: Function) {
|
||||
defaultMetadataStorage.addEventSubscriberMetadata(new EventSubscriberMetadata(target));
|
||||
defaultMetadataStorage().addEventSubscriberMetadata(new EventSubscriberMetadata(target));
|
||||
};
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
import {RelationMetadata} from "../../metadata-builder/metadata/RelationMetadata";
|
||||
import {RelationOptions} from "../../metadata-builder/options/RelationOptions";
|
||||
import {RelationTypes} from "../../metadata-builder/types/RelationTypes";
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {ConstructorFunction} from "../../common/ConstructorFunction";
|
||||
|
||||
/**
|
||||
@ -39,7 +39,7 @@ export function ManyToMany<T>(typeFunction: (type?: any) => ConstructorFunction<
|
||||
|
||||
const relationOptions = options ? options : {} as RelationOptions;
|
||||
|
||||
defaultMetadataStorage.addRelationMetadata(new RelationMetadata({
|
||||
defaultMetadataStorage().addRelationMetadata(new RelationMetadata({
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
relationType: RelationTypes.MANY_TO_MANY,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {RelationMetadata} from "../../metadata-builder/metadata/RelationMetadata";
|
||||
import {RelationOptions} from "../../metadata-builder/options/RelationOptions";
|
||||
import {RelationTypes} from "../../metadata-builder/types/RelationTypes";
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {ConstructorFunction} from "../../common/ConstructorFunction";
|
||||
|
||||
/**
|
||||
@ -39,7 +39,7 @@ export function ManyToManyInverse<T>(typeFunction: (type?: any) => ConstructorFu
|
||||
|
||||
const relationOptions = options ? options : {} as RelationOptions;
|
||||
|
||||
defaultMetadataStorage.addRelationMetadata(new RelationMetadata({
|
||||
defaultMetadataStorage().addRelationMetadata(new RelationMetadata({
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
relationType: RelationTypes.MANY_TO_MANY,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {RelationMetadata} from "../../metadata-builder/metadata/RelationMetadata";
|
||||
import {RelationOptions} from "../../metadata-builder/options/RelationOptions";
|
||||
import {RelationTypes} from "../../metadata-builder/types/RelationTypes";
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {ConstructorFunction} from "../../common/ConstructorFunction";
|
||||
|
||||
/**
|
||||
@ -39,7 +39,7 @@ export function ManyToOne<T>(typeFunction: (type?: any) => ConstructorFunction<T
|
||||
|
||||
const relationOptions = options ? options : {} as RelationOptions;
|
||||
|
||||
defaultMetadataStorage.addRelationMetadata(new RelationMetadata({
|
||||
defaultMetadataStorage().addRelationMetadata(new RelationMetadata({
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
relationType: RelationTypes.MANY_TO_ONE,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {RelationMetadata} from "../../metadata-builder/metadata/RelationMetadata";
|
||||
import {RelationOptions} from "../../metadata-builder/options/RelationOptions";
|
||||
import {RelationTypes} from "../../metadata-builder/types/RelationTypes";
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {ConstructorFunction} from "../../common/ConstructorFunction";
|
||||
|
||||
/**
|
||||
@ -36,7 +36,7 @@ export function OneToMany<T>(typeFunction: (type?: any) => ConstructorFunction<T
|
||||
|
||||
const relationOptions = options ? options : {} as RelationOptions;
|
||||
|
||||
defaultMetadataStorage.addRelationMetadata(new RelationMetadata({
|
||||
defaultMetadataStorage().addRelationMetadata(new RelationMetadata({
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
relationType: RelationTypes.ONE_TO_MANY,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {RelationMetadata} from "../../metadata-builder/metadata/RelationMetadata";
|
||||
import {RelationOptions} from "../../metadata-builder/options/RelationOptions";
|
||||
import {RelationTypes} from "../../metadata-builder/types/RelationTypes";
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {ConstructorFunction} from "../../common/ConstructorFunction";
|
||||
|
||||
/**
|
||||
@ -36,7 +36,7 @@ export function OneToOne<T>(typeFunction: (type?: any) => ConstructorFunction<T>
|
||||
|
||||
const relationOptions = options ? options : {} as RelationOptions;
|
||||
|
||||
defaultMetadataStorage.addRelationMetadata(new RelationMetadata({
|
||||
defaultMetadataStorage().addRelationMetadata(new RelationMetadata({
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
relationType: RelationTypes.ONE_TO_ONE,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {RelationMetadata} from "../../metadata-builder/metadata/RelationMetadata";
|
||||
import {RelationOptions} from "../../metadata-builder/options/RelationOptions";
|
||||
import {RelationTypes} from "../../metadata-builder/types/RelationTypes";
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {ConstructorFunction} from "../../common/ConstructorFunction";
|
||||
|
||||
/**
|
||||
@ -39,7 +39,7 @@ export function OneToOneInverse<T>(typeFunction: (type?: any) => ConstructorFunc
|
||||
|
||||
const relationOptions = options ? options : {} as RelationOptions;
|
||||
|
||||
defaultMetadataStorage.addRelationMetadata(new RelationMetadata({
|
||||
defaultMetadataStorage().addRelationMetadata(new RelationMetadata({
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
relationType: RelationTypes.ONE_TO_ONE,
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import {TableMetadata} from "../../metadata-builder/metadata/TableMetadata";
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
|
||||
/**
|
||||
* Allows to use columns and relations data from the inherited metadata.
|
||||
*/
|
||||
export function AbstractTable() {
|
||||
return function (cls: Function) {
|
||||
defaultMetadataStorage.addTableMetadata(new TableMetadata(cls, true));
|
||||
defaultMetadataStorage().addTableMetadata(new TableMetadata(cls, true));
|
||||
};
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
|
||||
import {defaultMetadataStorage} from "../../typeorm";
|
||||
import {TableMetadata} from "../../metadata-builder/metadata/TableMetadata";
|
||||
|
||||
/**
|
||||
@ -7,6 +7,6 @@ import {TableMetadata} from "../../metadata-builder/metadata/TableMetadata";
|
||||
*/
|
||||
export function Table(name?: string) {
|
||||
return function (cls: Function) {
|
||||
defaultMetadataStorage.addTableMetadata(new TableMetadata(cls, name));
|
||||
defaultMetadataStorage().addTableMetadata(new TableMetadata(cls, name));
|
||||
};
|
||||
}
|
||||
|
||||
@ -2,11 +2,12 @@ import {MetadataStorage} from "./MetadataStorage";
|
||||
import {PropertyMetadata} from "./metadata/PropertyMetadata";
|
||||
import {TableMetadata} from "./metadata/TableMetadata";
|
||||
import {EntityMetadata} from "./metadata/EntityMetadata";
|
||||
import {NamingStrategy} from "../naming-strategy/NamingStrategy";
|
||||
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategy";
|
||||
import {ColumnMetadata} from "./metadata/ColumnMetadata";
|
||||
import {ColumnOptions} from "./options/ColumnOptions";
|
||||
import {ForeignKeyMetadata} from "./metadata/ForeignKeyMetadata";
|
||||
import {JunctionTableMetadata} from "./metadata/JunctionTableMetadata";
|
||||
import {defaultMetadataStorage} from "../typeorm";
|
||||
|
||||
/**
|
||||
* Aggregates all metadata: table, column, relation into one collection grouped by tables for a given set of classes.
|
||||
@ -17,12 +18,13 @@ export class EntityMetadataBuilder {
|
||||
|
||||
// todo: type in function validation, inverse side function validation
|
||||
|
||||
private metadataStorage: MetadataStorage = defaultMetadataStorage();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(private metadataStorage: MetadataStorage,
|
||||
private namingStrategy: NamingStrategy) {
|
||||
constructor(private namingStrategy: NamingStrategyInterface) {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -7,12 +7,11 @@ import {CompoundIndexMetadata} from "./metadata/CompoundIndexMetadata";
|
||||
import {ColumnMetadata} from "./metadata/ColumnMetadata";
|
||||
import {EventSubscriberMetadata} from "./metadata/EventSubscriberMetadata";
|
||||
import {EntityListenerMetadata} from "./metadata/EntityListenerMetadata";
|
||||
import {NamingStrategyMetadata} from "./metadata/NamingStrategyMetadata";
|
||||
|
||||
/**
|
||||
* Storage all metadatas of all available types: tables, fields, subscribers, relations, etc.
|
||||
* Each metadata represents some specifications of what it represents.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export class MetadataStorage {
|
||||
|
||||
@ -20,45 +19,14 @@ export class MetadataStorage {
|
||||
// Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private _tableMetadatas: TableMetadata[] = [];
|
||||
private _eventSubscriberMetadatas: EventSubscriberMetadata[] = [];
|
||||
private _columnMetadatas: ColumnMetadata[] = [];
|
||||
private _indexMetadatas: IndexMetadata[] = [];
|
||||
private _entityListenerMetadatas: EntityListenerMetadata[] = [];
|
||||
private _compoundIndexMetadatas: CompoundIndexMetadata[] = [];
|
||||
private _relationMetadatas: RelationMetadata[] = [];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Getter Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
get tableMetadatas(): TableMetadata[] {
|
||||
return this._tableMetadatas;
|
||||
}
|
||||
|
||||
get eventSubscriberMetadatas(): EventSubscriberMetadata[] {
|
||||
return this._eventSubscriberMetadatas;
|
||||
}
|
||||
|
||||
get columnMetadatas(): ColumnMetadata[] {
|
||||
return this._columnMetadatas;
|
||||
}
|
||||
|
||||
get indexMetadatas(): IndexMetadata[] {
|
||||
return this._indexMetadatas;
|
||||
}
|
||||
|
||||
get entityListenerMetadatas(): EntityListenerMetadata[] {
|
||||
return this._entityListenerMetadatas;
|
||||
}
|
||||
|
||||
get compoundIndexMetadatas(): CompoundIndexMetadata[] {
|
||||
return this._compoundIndexMetadatas;
|
||||
}
|
||||
|
||||
get relationMetadatas(): RelationMetadata[] {
|
||||
return this._relationMetadatas;
|
||||
}
|
||||
private tableMetadatas: TableMetadata[] = [];
|
||||
private eventSubscriberMetadatas: EventSubscriberMetadata[] = [];
|
||||
private columnMetadatas: ColumnMetadata[] = [];
|
||||
private indexMetadatas: IndexMetadata[] = [];
|
||||
private entityListenerMetadatas: EntityListenerMetadata[] = [];
|
||||
private compoundIndexMetadatas: CompoundIndexMetadata[] = [];
|
||||
private namingStrategyMetadatas: NamingStrategyMetadata[] = [];
|
||||
private relationMetadatas: RelationMetadata[] = [];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Adder Methods
|
||||
@ -118,6 +86,13 @@ export class MetadataStorage {
|
||||
this.compoundIndexMetadatas.push(metadata);
|
||||
}
|
||||
|
||||
addNamingStrategyMetadata(metadata: NamingStrategyMetadata) {
|
||||
if (this.hasNamingStrategyMetadataWithObjectConstructor(metadata.target))
|
||||
throw new MetadataAlreadyExistsError("NamingStrategy", metadata.target);
|
||||
|
||||
this.namingStrategyMetadatas.push(metadata);
|
||||
}
|
||||
|
||||
addEntityListenerMetadata(metadata: EntityListenerMetadata) {
|
||||
if (this.hasFieldMetadataOnProperty(metadata.target, metadata.propertyName))
|
||||
throw new MetadataAlreadyExistsError("EventListener", metadata.target);
|
||||
@ -161,6 +136,15 @@ export class MetadataStorage {
|
||||
return this.relationMetadatas.filter(metadata => classes.indexOf(metadata.target) !== -1);
|
||||
}
|
||||
|
||||
findNamingStrategy(name: string): NamingStrategyMetadata {
|
||||
// todo: throw error if naming strategy is not found.
|
||||
return this.namingStrategyMetadatas.find(metadata => metadata.name === name);
|
||||
}
|
||||
|
||||
findNamingStrategiesForClasses(classes: Function[]): NamingStrategyMetadata[] {
|
||||
return this.namingStrategyMetadatas.filter(metadata => classes.indexOf(metadata.target) !== -1);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private Methods
|
||||
// -------------------------------------------------------------------------
|
||||
@ -173,6 +157,10 @@ export class MetadataStorage {
|
||||
return !!this.compoundIndexMetadatas.find(metadata => metadata.target === constructor);
|
||||
}
|
||||
|
||||
private hasNamingStrategyMetadataWithObjectConstructor(constructor: Function): boolean {
|
||||
return !!this.namingStrategyMetadatas.find(metadata => metadata.target === constructor);
|
||||
}
|
||||
|
||||
private hasEventSubscriberWithObjectConstructor(constructor: Function): boolean {
|
||||
return !!this.eventSubscriberMetadatas.find(metadata => metadata.target === constructor);
|
||||
}
|
||||
@ -197,9 +185,4 @@ export class MetadataStorage {
|
||||
return !!this.relationMetadatas.find(metadata => metadata.target === constructor && metadata.name === name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Default metadata storage used as singleton and can be used to storage all metadatas in the system.
|
||||
*/
|
||||
export const defaultMetadataStorage = new MetadataStorage();
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import {PropertyMetadata} from "./PropertyMetadata";
|
||||
import {ColumnOptions} from "../options/ColumnOptions";
|
||||
import {NamingStrategy} from "../../naming-strategy/NamingStrategy";
|
||||
import {NamingStrategyInterface} from "../../naming-strategy/NamingStrategy";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
|
||||
/**
|
||||
@ -61,7 +61,7 @@ export class ColumnMetadata extends PropertyMetadata {
|
||||
/**
|
||||
* Naming strategy to be used to generate column name.
|
||||
*/
|
||||
namingStrategy: NamingStrategy;
|
||||
namingStrategy: NamingStrategyInterface;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Readonly Properties
|
||||
|
||||
18
src/metadata-builder/metadata/EntityMetadataArray.ts
Normal file
18
src/metadata-builder/metadata/EntityMetadataArray.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import {EntityMetadata} from "./EntityMetadata";
|
||||
|
||||
/**
|
||||
* Array for the entity metadatas.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export class EntityMetadataArray extends Array<EntityMetadata> {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
findByTarget(target: Function) {
|
||||
return this.find(metadata => metadata.target === target);
|
||||
}
|
||||
|
||||
}
|
||||
29
src/metadata-builder/metadata/NamingStrategyMetadata.ts
Normal file
29
src/metadata-builder/metadata/NamingStrategyMetadata.ts
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* This metadata interface contains all information about naming strategy.
|
||||
*/
|
||||
export class NamingStrategyMetadata {
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Readonly Properties
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class to which this decorator is applied.
|
||||
*/
|
||||
readonly target: Function;
|
||||
|
||||
/**
|
||||
* Naming strategy name.
|
||||
*/
|
||||
readonly name: string;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
constructor(target: Function, name: string) {
|
||||
this.target = target;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
import {PropertyMetadata} from "./PropertyMetadata";
|
||||
import {RelationTypes, RelationType} from "../types/RelationTypes";
|
||||
import {RelationOptions} from "../options/RelationOptions";
|
||||
import {NamingStrategy} from "../../naming-strategy/NamingStrategy";
|
||||
import {NamingStrategyInterface} from "../../naming-strategy/NamingStrategy";
|
||||
import {EntityMetadata} from "./EntityMetadata";
|
||||
import {OnDeleteType} from "./ForeignKeyMetadata";
|
||||
|
||||
@ -69,7 +69,7 @@ export class RelationMetadata extends PropertyMetadata {
|
||||
/**
|
||||
* Naming strategy used to generate and normalize column name.
|
||||
*/
|
||||
namingStrategy: NamingStrategy;
|
||||
namingStrategy: NamingStrategyInterface;
|
||||
|
||||
/**
|
||||
* Related entity metadata.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {NamingStrategy} from "../../naming-strategy/NamingStrategy";
|
||||
import {NamingStrategyInterface} from "../../naming-strategy/NamingStrategy";
|
||||
|
||||
/**
|
||||
* This metadata interface contains all information about specific table.
|
||||
@ -12,7 +12,7 @@ export class TableMetadata {
|
||||
/**
|
||||
* Naming strategy used to generate and normalize table name.
|
||||
*/
|
||||
namingStrategy: NamingStrategy;
|
||||
namingStrategy: NamingStrategyInterface;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Readonly Properties
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import {NamingStrategy} from "./NamingStrategy";
|
||||
import {NamingStrategyInterface} from "./NamingStrategy";
|
||||
import * as _ from "lodash";
|
||||
|
||||
/**
|
||||
* Naming strategy that is used by default.
|
||||
*/
|
||||
export class DefaultNamingStrategy implements NamingStrategy {
|
||||
export class DefaultNamingStrategy implements NamingStrategyInterface {
|
||||
|
||||
tableName(className: string): string {
|
||||
return _.snakeCase(className);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
* Naming strategy defines how auto-generated names for such things like table name, or table column gonna be
|
||||
* generated.
|
||||
*/
|
||||
export interface NamingStrategy {
|
||||
export interface NamingStrategyInterface {
|
||||
|
||||
/**
|
||||
* Gets the table name from the given class name.
|
||||
|
||||
@ -448,7 +448,7 @@ export class QueryBuilder<Entity> {
|
||||
protected createSelectExpression() {
|
||||
// todo throw exception if selects or from is missing
|
||||
|
||||
let alias: string, tableName: string;
|
||||
let alias: string = "", tableName: string;
|
||||
const allSelects: string[] = [];
|
||||
|
||||
if (this.fromEntity) {
|
||||
|
||||
@ -147,7 +147,7 @@ export class MysqlSchemaBuilder extends SchemaBuilder {
|
||||
|
||||
private normalizeType(column: ColumnMetadata) {
|
||||
|
||||
let realType: string;
|
||||
let realType: string = "";
|
||||
if (typeof column.type === "string") {
|
||||
realType = column.type.toLowerCase();
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {TableMetadata} from "../metadata-builder/metadata/TableMetadata";
|
||||
import {ColumnMetadata} from "../metadata-builder/metadata/ColumnMetadata";
|
||||
import {ForeignKeyMetadata} from "../metadata-builder/metadata/ForeignKeyMetadata";
|
||||
import {EntityMetadata} from "../metadata-builder/metadata/EntityMetadata";
|
||||
import {SchemaBuilder} from "../schema-builder/SchemaBuilder";
|
||||
import {EntityMetadataArray} from "../metadata-builder/metadata/EntityMetadataArray";
|
||||
|
||||
/**
|
||||
* Creates indexes based on the given metadata.
|
||||
@ -12,20 +12,12 @@ import {SchemaBuilder} from "../schema-builder/SchemaBuilder";
|
||||
*/
|
||||
export class SchemaCreator {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private connection: Connection;
|
||||
private schemaBuilder: SchemaBuilder;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(connection: Connection, private entityMetadatas: EntityMetadata[]) {
|
||||
this.connection = connection;
|
||||
this.schemaBuilder = connection.driver.createSchemaBuilder();
|
||||
constructor(private schemaBuilder: SchemaBuilder,
|
||||
private entityMetadatas: EntityMetadataArray) {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -26,7 +26,7 @@ export class Broadcaster {
|
||||
broadcastBeforeInsertEvent(entity: any): Promise<void> {
|
||||
|
||||
const subscribers = this.connection
|
||||
.subscribers
|
||||
.subscriberMetadatas
|
||||
.filter(subscriber => this.isAllowedSubscribers(subscriber, entity))
|
||||
.filter(subscriber => !!subscriber.beforeInsert)
|
||||
.map(subscriber => subscriber.beforeInsert({ entity: entity }));
|
||||
@ -42,7 +42,7 @@ export class Broadcaster {
|
||||
broadcastBeforeUpdateEvent(entity: any, updatedColumns: ColumnMetadata[]): Promise<void> {
|
||||
|
||||
const subscribers = this.connection
|
||||
.subscribers
|
||||
.subscriberMetadatas
|
||||
.filter(subscriber => this.isAllowedSubscribers(subscriber, entity))
|
||||
.filter(subscriber => !!subscriber.beforeUpdate)
|
||||
.map(subscriber => subscriber.beforeUpdate({ entity: entity, updatedColumns: updatedColumns }));
|
||||
@ -58,7 +58,7 @@ export class Broadcaster {
|
||||
broadcastBeforeRemoveEvent(entity: any, entityId: any): Promise<void> {
|
||||
|
||||
const subscribers = this.connection
|
||||
.subscribers
|
||||
.subscriberMetadatas
|
||||
.filter(subscriber => this.isAllowedSubscribers(subscriber, entity))
|
||||
.filter(subscriber => !!subscriber.beforeRemove)
|
||||
.map(subscriber => subscriber.beforeRemove({ entity: entity, entityId: entityId }));
|
||||
@ -74,7 +74,7 @@ export class Broadcaster {
|
||||
broadcastAfterInsertEvent(entity: any): Promise<void> {
|
||||
|
||||
const subscribers = this.connection
|
||||
.subscribers
|
||||
.subscriberMetadatas
|
||||
.filter(subscriber => this.isAllowedSubscribers(subscriber, entity))
|
||||
.filter(subscriber => !!subscriber.afterInsert)
|
||||
.map(subscriber => subscriber.afterInsert({ entity: entity }));
|
||||
@ -90,7 +90,7 @@ export class Broadcaster {
|
||||
broadcastAfterUpdateEvent(entity: any, updatedColumns: ColumnMetadata[]): Promise<void> {
|
||||
|
||||
const subscribers = this.connection
|
||||
.subscribers
|
||||
.subscriberMetadatas
|
||||
.filter(subscriber => this.isAllowedSubscribers(subscriber, entity))
|
||||
.filter(subscriber => !!subscriber.afterUpdate)
|
||||
.map(subscriber => subscriber.afterUpdate({ entity: entity, updatedColumns: updatedColumns }));
|
||||
@ -106,7 +106,7 @@ export class Broadcaster {
|
||||
broadcastAfterRemoveEvent(entity: any, entityId: any): Promise<void> {
|
||||
|
||||
const subscribers = this.connection
|
||||
.subscribers
|
||||
.subscriberMetadatas
|
||||
.filter(subscriber => this.isAllowedSubscribers(subscriber, entity))
|
||||
.filter(subscriber => !!subscriber.afterRemove)
|
||||
.map(subscriber => subscriber.afterRemove({ entity: entity, entityId: entityId }));
|
||||
@ -137,7 +137,7 @@ export class Broadcaster {
|
||||
});
|
||||
|
||||
this.connection
|
||||
.subscribers
|
||||
.subscriberMetadatas
|
||||
.filter(subscriber => this.isAllowedSubscribers(subscriber, entity))
|
||||
.filter(subscriber => !!subscriber.afterLoad)
|
||||
.forEach(subscriber => promises.push(<any> subscriber.afterLoad(entity)));
|
||||
|
||||
133
src/typeorm.ts
133
src/typeorm.ts
@ -3,91 +3,92 @@
|
||||
*/
|
||||
|
||||
import {ConnectionOptions} from "./connection/ConnectionOptions";
|
||||
import {ConnectionManager} from "./connection/ConnectionManager";
|
||||
import {ConnectionManager} from "./connection-manager/ConnectionManager";
|
||||
import {Connection} from "./connection/Connection";
|
||||
import {MysqlDriver} from "./driver/MysqlDriver";
|
||||
import {MetadataStorage} from "./metadata-builder/MetadataStorage";
|
||||
import {CreateConnectionOptions} from "./connection-manager/CreateConnectionOptions";
|
||||
|
||||
const connectionManager = new ConnectionManager();
|
||||
// -------------------------------------------------------------------------
|
||||
// Global Container
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* All options to help to create a new connection.
|
||||
* Container to be used by TypeORM for inversion control.
|
||||
*/
|
||||
export interface CreateConnectionOptions {
|
||||
let container: { get(someClass: any): any };
|
||||
|
||||
/**
|
||||
* Driver type. Mysql is the only driver supported at this moment.
|
||||
*/
|
||||
driver: "mysql";
|
||||
|
||||
/**
|
||||
* Database connection options.
|
||||
*/
|
||||
connection: ConnectionOptions;
|
||||
|
||||
/**
|
||||
* Connection name. By default its called "default". Different connections must have different names.
|
||||
*/
|
||||
connectionName?: string;
|
||||
|
||||
/**
|
||||
* Entities to be loaded for the new connection.
|
||||
*/
|
||||
entities?: Function[];
|
||||
|
||||
/**
|
||||
* Subscribers to be loaded for the new connection.
|
||||
*/
|
||||
subscribers?: Function[];
|
||||
|
||||
/**
|
||||
* List of directories from where entities will be loaded.
|
||||
*/
|
||||
entityDirectories?: string[];
|
||||
|
||||
/**
|
||||
* List of directories from where subscribers will be loaded.
|
||||
*/
|
||||
subscriberDirectories?: string[];
|
||||
/**
|
||||
* Sets container to be used by TypeORM.
|
||||
*
|
||||
* @param iocContainer
|
||||
*/
|
||||
export function useContainer(iocContainer: { get(someClass: any): any }) {
|
||||
container = iocContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new connection with the database.
|
||||
*/
|
||||
export function createConnection(options: CreateConnectionOptions): Promise<Connection> {
|
||||
export function getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
let connection: Connection;
|
||||
switch (options.driver) {
|
||||
case "mysql":
|
||||
connection = connectionManager.createConnection(options.connectionName, new MysqlDriver(), options.connection);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Wrong driver ${options.driver} given. Supported drivers are: "mysql"`);
|
||||
// -------------------------------------------------------------------------
|
||||
// Global Metadata Storage
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Default metadata storage used as singleton and can be used to storage all metadatas in the system.
|
||||
*/
|
||||
let metadataStorage: MetadataStorage;
|
||||
|
||||
export function defaultMetadataStorage() {
|
||||
if (!metadataStorage && container) {
|
||||
metadataStorage = container.get(MetadataStorage);
|
||||
|
||||
} else if (!metadataStorage) {
|
||||
metadataStorage = new MetadataStorage();
|
||||
}
|
||||
|
||||
if (options.entityDirectories && options.entityDirectories.length > 0)
|
||||
connectionManager.importEntitiesFromDirectories(options.connectionName, options.entityDirectories);
|
||||
|
||||
if (options.entities)
|
||||
connectionManager.importEntities(options.connectionName, options.entities);
|
||||
|
||||
if (options.subscriberDirectories && options.subscriberDirectories.length > 0)
|
||||
connectionManager.importSubscribersFromDirectories(options.connectionName, options.subscriberDirectories);
|
||||
|
||||
if (options.subscribers)
|
||||
connectionManager.importSubscribers(options.subscribers);
|
||||
|
||||
return connection.connect().then(() => connection);
|
||||
|
||||
return metadataStorage;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Global Connection Manager
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Default export. Global connection manager.
|
||||
*/
|
||||
export default connectionManager;
|
||||
let connectionManager: ConnectionManager;
|
||||
|
||||
/**
|
||||
* Gets a ConnectionManager which creates connections.
|
||||
*/
|
||||
export function getConnectionManager() {
|
||||
if (!connectionManager && container) {
|
||||
connectionManager = container.get(ConnectionManager);
|
||||
|
||||
} else if (!connectionManager) {
|
||||
connectionManager = new ConnectionManager();
|
||||
}
|
||||
|
||||
return connectionManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to quickly create a connection based on the given options. Uses ConnectionManager.
|
||||
*/
|
||||
export function createConnection(options: CreateConnectionOptions) {
|
||||
return getConnectionManager().create(options);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Commonly Used exports
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
// export everything commonly used
|
||||
export {Connection} from "./connection/Connection";
|
||||
export {ConnectionManager} from "./connection/ConnectionManager";
|
||||
export {ConnectionOptions} from "./connection/ConnectionOptions";
|
||||
export {ConnectionManager} from "./connection-manager/ConnectionManager";
|
||||
export {CreateConnectionOptions} from "./connection-manager/CreateConnectionOptions";
|
||||
export {Driver} from "./driver/Driver";
|
||||
export {MysqlDriver} from "./driver/MysqlDriver";
|
||||
export {QueryBuilder} from "./query-builder/QueryBuilder";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user