refactoring entity metadata stuff

This commit is contained in:
Umed Khudoiberdiev 2017-05-16 13:00:57 +05:00
parent bd01c5fc4f
commit 545b1fc0dc
68 changed files with 225 additions and 336 deletions

View File

@ -3,7 +3,6 @@ import {Repository} from "../repository/Repository";
import {EntitySubscriberInterface} from "../subscriber/EntitySubscriberInterface";
import {RepositoryNotFoundError} from "./error/RepositoryNotFoundError";
import {ObjectType} from "../common/ObjectType";
import {EntityListenerMetadata} from "../metadata/EntityListenerMetadata";
import {EntityManager} from "../entity-manager/EntityManager";
import {importClassesFromDirectories, importJsonsFromDirectories} from "../util/DirectoryExportedClassesLoader";
import {getFromContainer, getMetadataArgsStorage} from "../index";
@ -96,11 +95,6 @@ export class Connection {
*/
private readonly entityRepositories: Object[] = [];
/**
* Entity listeners that are registered for this connection.
*/
private readonly entityListeners: EntityListenerMetadata[] = [];
/**
* Entity subscribers that are registered for this connection.
*/
@ -580,7 +574,7 @@ export class Connection {
* Gets custom entity repository marked with @EntityRepository decorator.
*/
getCustomRepository<T>(customRepository: ObjectType<T>): T {
const entityRepositoryMetadataArgs = getMetadataArgsStorage().entityRepositories.toArray().find(repository => {
const entityRepositoryMetadataArgs = getMetadataArgsStorage().entityRepositories.find(repository => {
return repository.target === (customRepository instanceof Function ? customRepository : (customRepository as any).constructor);
});
if (!entityRepositoryMetadataArgs)
@ -634,7 +628,7 @@ export class Connection {
* If given custom repository does not manage any entity then undefined will be returned.
*/
getCustomRepositoryTarget<T>(customRepository: any): Function|string|undefined {
const entityRepositoryMetadataArgs = getMetadataArgsStorage().entityRepositories.toArray().find(repository => {
const entityRepositoryMetadataArgs = getMetadataArgsStorage().entityRepositories.find(repository => {
return repository.target === (customRepository instanceof Function ? customRepository : (customRepository as any).constructor);
});
if (!entityRepositoryMetadataArgs)
@ -671,7 +665,6 @@ export class Connection {
public buildMetadatas() {
this.entitySubscribers.length = 0;
this.entityListeners.length = 0;
this.repositoryAggregators.length = 0;
this.entityMetadatas.length = 0;
@ -682,20 +675,13 @@ export class Connection {
// take imported event subscribers
if (this.subscriberClasses && this.subscriberClasses.length && !PlatformTools.getEnvVariable("SKIP_SUBSCRIBERS_LOADING")) {
getMetadataArgsStorage()
.entitySubscribers
.filterByTargets(this.subscriberClasses)
.toArray()
.filterSubscribers(this.subscriberClasses)
.map(metadata => getFromContainer(metadata.target))
.forEach(subscriber => this.entitySubscribers.push(subscriber));
}
// take imported entity listeners
if (this.entityClasses && this.entityClasses.length) {
getMetadataArgsStorage()
.entityListeners
.filterByTargets(this.entityClasses)
.toArray()
.forEach(metadata => this.entityListeners.push(new EntityListenerMetadata(metadata)));
// build entity metadatas from metadata args storage (collected from decorators)
new EntityMetadataBuilder(this, getMetadataArgsStorage())
@ -731,9 +717,7 @@ export class Connection {
// try to find used naming strategy in the list of loaded naming strategies
const namingMetadata = getMetadataArgsStorage()
.namingStrategies
.filterByTargets(this.namingStrategyClasses)
.toArray()
.filterNamingStrategies(this.namingStrategyClasses)
.find(strategy => {
if (typeof this.usedNamingStrategy === "string") {
return strategy.name === this.usedNamingStrategy;
@ -764,7 +748,7 @@ export class Connection {
* Creates a new entity broadcaster using in this connection.
*/
protected createBroadcaster() {
return new Broadcaster(this, this.entitySubscribers, this.entityListeners);
return new Broadcaster(this, this.entitySubscribers);
}
/**

View File

@ -11,6 +11,6 @@ export function DiscriminatorValue(value: any): Function {
target: target,
value: value
};
getMetadataArgsStorage().discriminatorValues.add(args);
getMetadataArgsStorage().discriminatorValues.push(args);
};
}

View File

@ -22,6 +22,6 @@ export function Embedded<T>(typeFunction: (type?: any) => ObjectType<T>, options
prefix: options && options.prefix !== undefined ? options.prefix : undefined,
type: typeFunction
};
getMetadataArgsStorage().embeddeds.add(args);
getMetadataArgsStorage().embeddeds.push(args);
};
}

View File

@ -29,6 +29,6 @@ export function EntityRepository(entityOrOptions?: Function|{ useContainer?: boo
entity: entity,
useContainer: !!(options && options.useContainer)
};
getMetadataArgsStorage().entityRepositories.add(args);
getMetadataArgsStorage().entityRepositories.push(args);
};
}

View File

@ -51,6 +51,6 @@ export function Index(nameOrFieldsOrOptions: string|string[]|((object: any) => a
columns: propertyName ? [propertyName] : fields,
unique: options && options.unique ? true : false
};
getMetadataArgsStorage().indices.add(args);
getMetadataArgsStorage().indices.push(args);
};
}

View File

@ -14,6 +14,6 @@ export function NamingStrategy(name?: string): Function {
target: target,
name: strategyName
};
getMetadataArgsStorage().namingStrategies.add(args);
getMetadataArgsStorage().namingStrategies.push(args);
};
}

View File

@ -76,6 +76,6 @@ export function Column(typeOrOptions?: ColumnType|ColumnOptions, options?: Colum
mode: "regular",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -27,6 +27,6 @@ export function CreateDateColumn(options?: ColumnOptions): Function {
mode: "createDate",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -24,7 +24,7 @@ export function DiscriminatorColumn(discriminatorOptions: { name: string, type:
propertyName: discriminatorOptions.name,
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -23,6 +23,6 @@ export function ObjectIdColumn<T>(options?: ColumnOptions): Function {
mode: "objectId",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -68,7 +68,7 @@ export function PrimaryColumn(typeOrOptions?: ColumnType|ColumnOptions, options?
mode: "regular",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -37,7 +37,7 @@ export function PrimaryGeneratedColumn(options?: ColumnOptions): Function {
mode: "regular",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -26,7 +26,7 @@ export function UpdateDateColumn(options?: ColumnOptions): Function {
mode: "updateDate",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -29,7 +29,7 @@ export function VersionColumn(options?: ColumnOptions): Function {
mode: "version",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -14,6 +14,6 @@ export function AbstractEntity() {
name: undefined,
type: "abstract"
};
getMetadataArgsStorage().tables.add(args);
getMetadataArgsStorage().tables.push(args);
};
}

View File

@ -14,6 +14,6 @@ export function ClassEntityChild(tableName?: string, options?: EntityOptions) {
orderBy: options && options.orderBy ? options.orderBy : undefined,
skipSchemaSync: !!(options && options.skipSchemaSync === true)
};
getMetadataArgsStorage().tables.add(args);
getMetadataArgsStorage().tables.push(args);
};
}

View File

@ -14,6 +14,6 @@ export function ClosureEntity(name?: string, options?: EntityOptions) {
orderBy: options && options.orderBy ? options.orderBy : undefined,
skipSchemaSync: !!(options && options.skipSchemaSync === true)
};
getMetadataArgsStorage().tables.add(args);
getMetadataArgsStorage().tables.push(args);
};
}

View File

@ -13,6 +13,6 @@ export function EmbeddableEntity(): Function {
type: "embeddable",
orderBy: undefined
};
getMetadataArgsStorage().tables.add(args);
getMetadataArgsStorage().tables.push(args);
};
}

View File

@ -16,6 +16,6 @@ export function Entity(name?: string, options?: EntityOptions) {
engine: options && options.engine ? options.engine : undefined,
skipSchemaSync: !!(options && options.skipSchemaSync === true)
};
getMetadataArgsStorage().tables.add(args);
getMetadataArgsStorage().tables.push(args);
};
}

View File

@ -12,6 +12,6 @@ export function SingleEntityChild() {
type: "single-table-child",
orderBy: undefined
};
getMetadataArgsStorage().tables.add(args);
getMetadataArgsStorage().tables.push(args);
};
}

View File

@ -10,6 +10,6 @@ export function TableInheritance(type: "single-table"|"class-table") {
target: target,
type: type
};
getMetadataArgsStorage().inheritances.add(args);
getMetadataArgsStorage().inheritances.push(args);
};
}

View File

@ -13,6 +13,6 @@ export function AfterInsert() {
propertyName: propertyName,
type: EventListenerTypes.AFTER_INSERT
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -12,6 +12,6 @@ export function AfterLoad() {
propertyName: propertyName,
type: EventListenerTypes.AFTER_LOAD
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -12,6 +12,6 @@ export function AfterRemove() {
propertyName: propertyName,
type: EventListenerTypes.AFTER_REMOVE
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -12,6 +12,6 @@ export function AfterUpdate() {
propertyName: propertyName,
type: EventListenerTypes.AFTER_UPDATE
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -12,6 +12,6 @@ export function BeforeInsert() {
propertyName: propertyName,
type: EventListenerTypes.BEFORE_INSERT
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -12,6 +12,6 @@ export function BeforeRemove() {
propertyName: propertyName,
type: EventListenerTypes.BEFORE_REMOVE
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -12,6 +12,6 @@ export function BeforeUpdate() {
propertyName: propertyName,
type: EventListenerTypes.BEFORE_UPDATE
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -10,6 +10,6 @@ export function EventSubscriber() {
const args: EntitySubscriberMetadataArgs = {
target: target
};
getMetadataArgsStorage().entitySubscribers.add(args);
getMetadataArgsStorage().entitySubscribers.push(args);
};
}

View File

@ -1,4 +1,4 @@
import {OnDeleteType} from "../../metadata/ForeignKeyMetadata";
import {OnDeleteType} from "../../metadata/types/OnDeleteType";
// todo: add ON_UPDATE

View File

@ -38,7 +38,7 @@ export function JoinColumn(optionsOrOptionsArray?: JoinColumnOptions|JoinColumnO
name: options.name,
referencedColumnName: options.referencedColumnName
};
getMetadataArgsStorage().joinColumns.add(args);
getMetadataArgsStorage().joinColumns.push(args);
});
};
}

View File

@ -35,7 +35,7 @@ export function JoinTable(options?: JoinTableOptions|JoinTableMultipleColumnsOpt
joinColumns: (options && (options as JoinTableOptions).joinColumn ? [(options as JoinTableOptions).joinColumn!] : (options as JoinTableMultipleColumnsOptions).joinColumns) as any,
inverseJoinColumns: (options && (options as JoinTableOptions).inverseJoinColumn ? [(options as JoinTableOptions).inverseJoinColumn!] : (options as JoinTableMultipleColumnsOptions).inverseJoinColumns) as any,
};
getMetadataArgsStorage().joinTables.add(args);
getMetadataArgsStorage().joinTables.push(args);
};
}

View File

@ -55,7 +55,7 @@ export function ManyToMany<T>(typeFunction: (type?: any) => ObjectType<T>,
inverseSideProperty: inverseSideProperty,
options: options
};
getMetadataArgsStorage().relations.add(args);
getMetadataArgsStorage().relations.push(args);
};
}

View File

@ -55,6 +55,6 @@ export function ManyToOne<T>(typeFunction: (type?: any) => ObjectType<T>,
inverseSideProperty: inverseSideProperty,
options: options
};
getMetadataArgsStorage().relations.add(args);
getMetadataArgsStorage().relations.push(args);
};
}

View File

@ -31,7 +31,7 @@ export function OneToMany<T>(typeFunction: (type?: any) => ObjectType<T>, invers
inverseSideProperty: inverseSide,
options: options
};
getMetadataArgsStorage().relations.add(args);
getMetadataArgsStorage().relations.push(args);
};
}

View File

@ -52,6 +52,6 @@ export function OneToOne<T>(typeFunction: (type?: any) => ObjectType<T>,
inverseSideProperty: inverseSideProperty,
options: options
};
getMetadataArgsStorage().relations.add(args);
getMetadataArgsStorage().relations.push(args);
};
}

View File

@ -14,7 +14,7 @@ export function RelationCount<T>(relation: string|((object: T) => any), alias?:
alias: alias,
queryBuilderFactory: queryBuilderFactory
};
getMetadataArgsStorage().relationCounts.add(args);
getMetadataArgsStorage().relationCounts.push(args);
};
}

View File

@ -14,7 +14,7 @@ export function RelationId<T>(relation: string|((object: T) => any), alias?: str
alias: alias,
queryBuilderFactory: queryBuilderFactory
};
getMetadataArgsStorage().relationIds.add(args);
getMetadataArgsStorage().relationIds.push(args);
};
}

View File

@ -22,9 +22,7 @@ export function Transaction(connectionName: string = "default"): Function {
// gets all @TransactionEntityManager() decorator usages for this method
const indices = getMetadataArgsStorage()
.transactionEntityManagers
.filterByTarget(target.constructor)
.toArray()
.filterTransactionEntityManagers(target.constructor)
.filter(transactionEntityManager => transactionEntityManager.methodName === methodName)
.map(transactionEntityManager => transactionEntityManager.index);

View File

@ -11,6 +11,6 @@ export function TransactionEntityManager(): Function {
methodName: methodName,
index: index,
};
getMetadataArgsStorage().transactionEntityManagers.add(args);
getMetadataArgsStorage().transactionEntityManagers.push(args);
};
}

View File

@ -28,7 +28,7 @@ export function TreeChildren(options?: { cascadeInsert?: boolean, cascadeUpdate?
type: () => object.constructor,
options: options
};
getMetadataArgsStorage().relations.add(args);
getMetadataArgsStorage().relations.push(args);
};
}

View File

@ -22,7 +22,7 @@ export function TreeLevelColumn(): Function {
mode: "treeLevel",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -27,7 +27,7 @@ export function TreeParent(options?: { cascadeInsert?: boolean, cascadeUpdate?:
type: () => object.constructor,
options: options
};
getMetadataArgsStorage().relations.add(args);
getMetadataArgsStorage().relations.push(args);
};
}

View File

@ -1,10 +1,10 @@
import {TableType} from "../metadata/types/TableTypes";
import {OrderByCondition} from "../find-options/OrderByCondition";
import {OnDeleteType} from "../metadata/ForeignKeyMetadata";
import {JoinColumnOptions} from "../decorator/options/JoinColumnOptions";
import {ColumnType} from "../metadata/types/ColumnTypes";
import {RelationType} from "../metadata/types/RelationTypes";
import {JoinTableMultipleColumnsOptions} from "../decorator/options/JoinTableMuplipleColumnsOptions";
import {OnDeleteType} from "../metadata/types/OnDeleteType";
export interface EntitySchema {

View File

@ -1,13 +1,13 @@
import {EntitySchema} from "./EntitySchema";
import {MetadataArgsStorage} from "../metadata-args/MetadataArgsStorage";
import {TableMetadataArgs} from "../metadata-args/TableMetadataArgs";
import {ColumnMode} from "../metadata/ColumnMetadata";
import {ColumnMetadataArgs} from "../metadata-args/ColumnMetadataArgs";
import {RelationMetadataArgs} from "../metadata-args/RelationMetadataArgs";
import {JoinColumnMetadataArgs} from "../metadata-args/JoinColumnMetadataArgs";
import {JoinTableMetadataArgs} from "../metadata-args/JoinTableMetadataArgs";
import {JoinTableOptions} from "../decorator/options/JoinTableOptions";
import {JoinTableMultipleColumnsOptions} from "../decorator/options/JoinTableMuplipleColumnsOptions";
import {ColumnMode} from "../metadata/types/ColumnMode";
export class EntitySchemaTransformer {
@ -28,7 +28,7 @@ export class EntitySchemaTransformer {
type: tableSchema.type || "regular",
orderBy: tableSchema.orderBy
};
metadataArgsStorage.tables.add(table);
metadataArgsStorage.tables.push(table);
// add columns metadata args from the schema
Object.keys(schema.columns).forEach(columnName => {
@ -64,7 +64,7 @@ export class EntitySchemaTransformer {
}
};
metadataArgsStorage.columns.add(column);
metadataArgsStorage.columns.push(column);
});
// add relation metadata args from the schema
@ -90,7 +90,7 @@ export class EntitySchemaTransformer {
}
};
metadataArgsStorage.relations.add(relation);
metadataArgsStorage.relations.push(relation);
// add join column
if (relationSchema.joinColumn) {
@ -99,7 +99,7 @@ export class EntitySchemaTransformer {
target: schema.target || schema.name,
propertyName: relationName
};
metadataArgsStorage.joinColumns.add(joinColumn);
metadataArgsStorage.joinColumns.push(joinColumn);
} else {
const joinColumn: JoinColumnMetadataArgs = {
target: schema.target || schema.name,
@ -107,7 +107,7 @@ export class EntitySchemaTransformer {
name: relationSchema.joinColumn.name,
referencedColumnName: relationSchema.joinColumn.referencedColumnName
};
metadataArgsStorage.joinColumns.add(joinColumn);
metadataArgsStorage.joinColumns.push(joinColumn);
}
}
@ -118,7 +118,7 @@ export class EntitySchemaTransformer {
target: schema.target || schema.name,
propertyName: relationName
};
metadataArgsStorage.joinTables.add(joinTable);
metadataArgsStorage.joinTables.push(joinTable);
} else {
const joinTable: JoinTableMetadataArgs = {
target: schema.target || schema.name,
@ -127,7 +127,7 @@ export class EntitySchemaTransformer {
joinColumns: ((relationSchema.joinTable as JoinTableOptions).joinColumn ? [(relationSchema.joinTable as JoinTableOptions).joinColumn!] : (relationSchema.joinTable as JoinTableMultipleColumnsOptions).joinColumns) as any,
inverseJoinColumns: ((relationSchema.joinTable as JoinTableOptions).inverseJoinColumn ? [(relationSchema.joinTable as JoinTableOptions).inverseJoinColumn!] : (relationSchema.joinTable as JoinTableMultipleColumnsOptions).inverseJoinColumns) as any,
};
metadataArgsStorage.joinTables.add(joinTable);
metadataArgsStorage.joinTables.push(joinTable);
}
}
});

View File

@ -1,5 +1,5 @@
import {ColumnOptions} from "../decorator/options/ColumnOptions";
import {ColumnMode} from "../metadata/ColumnMetadata";
import {ColumnMode} from "../metadata/types/ColumnMode";
/**
* Arguments for ColumnMetadata class.

View File

@ -1,5 +1,3 @@
import {TargetMetadataArgsCollection} from "./collection/TargetMetadataArgsCollection";
import {PropertyMetadataArgsCollection} from "./collection/PropertyMetadataArgsCollection";
import {RelationMetadataArgs} from "./RelationMetadataArgs";
import {ColumnMetadataArgs} from "./ColumnMetadataArgs";
import {RelationCountMetadataArgs} from "./RelationCountMetadataArgs";
@ -16,40 +14,34 @@ import {InheritanceMetadataArgs} from "./InheritanceMetadataArgs";
import {DiscriminatorValueMetadataArgs} from "./DiscriminatorValueMetadataArgs";
import {EntityRepositoryMetadataArgs} from "./EntityRepositoryMetadataArgs";
import {TransactionEntityMetadataArgs} from "./TransactionEntityMetadataArgs";
import {MetadataUtils} from "./MetadataUtils";
import {ColumnMetadata} from "../metadata/ColumnMetadata";
/**
* Storage all metadatas of all available types: tables, fields, subscribers, relations, etc.
* Each metadata represents some specifications of what it represents.
* Storage all metadatas args of all available types: tables, columns, subscribers, relations, etc.
* Each metadata args represents some specifications of what it represents.
* MetadataArgs used to create a real Metadata objects.
*/
export class MetadataArgsStorage {
// todo: type in function validation, inverse side function validation
// todo: check on build for duplicate names, since naming checking was removed from MetadataStorage
// todo: duplicate name checking for: table, relation, column, index, naming strategy, join tables/columns?
// todo: check for duplicate targets too since this check has been removed too
// -------------------------------------------------------------------------
// Properties
// -------------------------------------------------------------------------
readonly tables = new TargetMetadataArgsCollection<TableMetadataArgs>();
readonly entityRepositories = new TargetMetadataArgsCollection<EntityRepositoryMetadataArgs>();
readonly transactionEntityManagers = new TargetMetadataArgsCollection<TransactionEntityMetadataArgs>();
readonly namingStrategies = new TargetMetadataArgsCollection<NamingStrategyMetadataArgs>();
readonly entitySubscribers = new TargetMetadataArgsCollection<EntitySubscriberMetadataArgs>();
readonly indices = new PropertyMetadataArgsCollection<IndexMetadataArgs>();
readonly columns = new PropertyMetadataArgsCollection<ColumnMetadataArgs>();
readonly relations = new PropertyMetadataArgsCollection<RelationMetadataArgs>();
readonly joinColumns = new PropertyMetadataArgsCollection<JoinColumnMetadataArgs>();
readonly joinTables = new PropertyMetadataArgsCollection<JoinTableMetadataArgs>();
readonly entityListeners = new PropertyMetadataArgsCollection<EntityListenerMetadataArgs>();
readonly relationCounts = new PropertyMetadataArgsCollection<RelationCountMetadataArgs>();
readonly relationIds = new PropertyMetadataArgsCollection<RelationIdMetadataArgs>();
readonly embeddeds = new PropertyMetadataArgsCollection<EmbeddedMetadataArgs>();
readonly inheritances = new TargetMetadataArgsCollection<InheritanceMetadataArgs>();
readonly discriminatorValues = new TargetMetadataArgsCollection<DiscriminatorValueMetadataArgs>();
readonly tables: TableMetadataArgs[] = [];
readonly entityRepositories: EntityRepositoryMetadataArgs[] = [];
readonly transactionEntityManagers: TransactionEntityMetadataArgs[] = [];
readonly namingStrategies: NamingStrategyMetadataArgs[] = [];
readonly entitySubscribers: EntitySubscriberMetadataArgs[] = [];
readonly indices: IndexMetadataArgs[] = [];
readonly columns: ColumnMetadataArgs[] = [];
readonly relations: RelationMetadataArgs[] = [];
readonly joinColumns: JoinColumnMetadataArgs[] = [];
readonly joinTables: JoinTableMetadataArgs[] = [];
readonly entityListeners: EntityListenerMetadataArgs[] = [];
readonly relationCounts: RelationCountMetadataArgs[] = [];
readonly relationIds: RelationIdMetadataArgs[] = [];
readonly embeddeds: EmbeddedMetadataArgs[] = [];
readonly inheritances: InheritanceMetadataArgs[] = [];
readonly discriminatorValues: DiscriminatorValueMetadataArgs[] = [];
// -------------------------------------------------------------------------
// Public Methods
@ -58,7 +50,7 @@ export class MetadataArgsStorage {
filterTables(target?: Function|string): TableMetadataArgs[];
filterTables(target?: (Function|string)[]): TableMetadataArgs[];
filterTables(target?: (Function|string)|(Function|string)[]): TableMetadataArgs[] {
return this.tables.toArray().filter(table => {
return this.tables.filter(table => {
return target instanceof Array ? target.indexOf(table.target) !== -1 : table.target === target;
});
}
@ -66,7 +58,7 @@ export class MetadataArgsStorage {
filterColumns(target: Function|string): ColumnMetadataArgs[];
filterColumns(target: (Function|string)[]): ColumnMetadataArgs[];
filterColumns(target: (Function|string)|(Function|string)[]): ColumnMetadataArgs[] {
return this.columns.toArray().filter(column => {
return this.columns.filter(column => {
return target instanceof Array ? target.indexOf(column.target) !== -1 : column.target === target;
});
}
@ -74,7 +66,7 @@ export class MetadataArgsStorage {
filterRelations(target: Function|string): RelationMetadataArgs[];
filterRelations(target: (Function|string)[]): RelationMetadataArgs[];
filterRelations(target: (Function|string)|(Function|string)[]): RelationMetadataArgs[] {
return this.relations.toArray().filter(relation => {
return this.relations.filter(relation => {
return target instanceof Array ? target.indexOf(relation.target) !== -1 : relation.target === target;
});
}
@ -82,7 +74,7 @@ export class MetadataArgsStorage {
filterRelationIds(target: Function|string): RelationIdMetadataArgs[];
filterRelationIds(target: (Function|string)[]): RelationIdMetadataArgs[];
filterRelationIds(target: (Function|string)|(Function|string)[]): RelationIdMetadataArgs[] {
return this.relationIds.toArray().filter(relationId => {
return this.relationIds.filter(relationId => {
return target instanceof Array ? target.indexOf(relationId.target) !== -1 : relationId.target === target;
});
}
@ -90,7 +82,7 @@ export class MetadataArgsStorage {
filterRelationCounts(target: Function|string): RelationCountMetadataArgs[];
filterRelationCounts(target: (Function|string)[]): RelationCountMetadataArgs[];
filterRelationCounts(target: (Function|string)|(Function|string)[]): RelationCountMetadataArgs[] {
return this.relationCounts.toArray().filter(relationCount => {
return this.relationCounts.filter(relationCount => {
return target instanceof Array ? target.indexOf(relationCount.target) !== -1 : relationCount.target === target;
});
}
@ -98,7 +90,15 @@ export class MetadataArgsStorage {
filterIndices(target: Function|string): IndexMetadataArgs[];
filterIndices(target: (Function|string)[]): IndexMetadataArgs[];
filterIndices(target: (Function|string)|(Function|string)[]): IndexMetadataArgs[] {
return this.indices.toArray().filter(index => {
return this.indices.filter(index => {
return target instanceof Array ? target.indexOf(index.target) !== -1 : index.target === target;
});
}
filterListeners(target: Function|string): EntityListenerMetadataArgs[];
filterListeners(target: (Function|string)[]): EntityListenerMetadataArgs[];
filterListeners(target: (Function|string)|(Function|string)[]): EntityListenerMetadataArgs[] {
return this.entityListeners.filter(index => {
return target instanceof Array ? target.indexOf(index.target) !== -1 : index.target === target;
});
}
@ -106,20 +106,45 @@ export class MetadataArgsStorage {
filterEmbeddeds(target: Function|string): EmbeddedMetadataArgs[];
filterEmbeddeds(target: (Function|string)[]): EmbeddedMetadataArgs[];
filterEmbeddeds(target: (Function|string)|(Function|string)[]): EmbeddedMetadataArgs[] {
return this.embeddeds.toArray().filter(embedded => {
return this.embeddeds.filter(embedded => {
return target instanceof Array ? target.indexOf(embedded.target) !== -1 : embedded.target === target;
});
}
findJoinTable(target: Function|string, propertyName: string): JoinTableMetadataArgs|undefined {
return this.joinTables.toArray().find(joinTable => {
return this.joinTables.find(joinTable => {
return joinTable.target === target && joinTable.propertyName === propertyName;
});
}
filterJoinColumns(target: Function|string, propertyName: string): JoinColumnMetadataArgs[] {
return this.joinColumns.toArray().filter(joinColumn => {
return this.joinColumns.filter(joinColumn => {
return joinColumn.target === target && joinColumn.propertyName === propertyName;
});
}
filterSubscribers(target: Function|string): EntitySubscriberMetadataArgs[];
filterSubscribers(target: (Function|string)[]): EntitySubscriberMetadataArgs[];
filterSubscribers(target: (Function|string)|(Function|string)[]): EntitySubscriberMetadataArgs[] {
return this.entitySubscribers.filter(subscriber => {
return target instanceof Array ? target.indexOf(subscriber.target) !== -1 : subscriber.target === target;
});
}
filterNamingStrategies(target: Function|string): NamingStrategyMetadataArgs[];
filterNamingStrategies(target: (Function|string)[]): NamingStrategyMetadataArgs[];
filterNamingStrategies(target: (Function|string)|(Function|string)[]): NamingStrategyMetadataArgs[] {
return this.namingStrategies.filter(subscriber => {
return target instanceof Array ? target.indexOf(subscriber.target) !== -1 : subscriber.target === target;
});
}
filterTransactionEntityManagers(target: Function|string): TransactionEntityMetadataArgs[];
filterTransactionEntityManagers(target: (Function|string)[]): TransactionEntityMetadataArgs[];
filterTransactionEntityManagers(target: (Function|string)|(Function|string)[]): TransactionEntityMetadataArgs[] {
return this.transactionEntityManagers.filter(subscriber => {
return target instanceof Array ? target.indexOf(subscriber.target) !== -1 : subscriber.target === target;
});
}
}

View File

@ -1,6 +1,6 @@
import {RelationType} from "../metadata/types/RelationTypes";
import {RelationOptions} from "../decorator/options/RelationOptions";
import {PropertyTypeInFunction, RelationTypeInFunction} from "../metadata/RelationMetadata";
import {PropertyTypeInFunction} from "../metadata/types/PropertyTypeInFunction";
/**
* Arguments for RelationMetadata class.

View File

@ -1,27 +0,0 @@
import {TargetMetadataArgsCollection} from "./TargetMetadataArgsCollection";
export class PropertyMetadataArgsCollection<T extends { target?: Function|string, propertyName?: string }> extends TargetMetadataArgsCollection<T> {
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
filterRepeatedMetadatas(existsMetadatas: T[]): this {
return this.filter(metadata => {
return !existsMetadatas.find(fieldFromDocument => fieldFromDocument.propertyName === metadata.propertyName);
});
}
findByProperty(propertyName: string) {
return this.items.find(item => item.propertyName === propertyName);
}
filterByProperty(propertyName: string): T[] {
return this.items.filter(item => item.propertyName === propertyName);
}
hasWithProperty(propertyName: string) {
return !!this.findByProperty(propertyName);
}
}

View File

@ -1,69 +0,0 @@
import {MetadataAlreadyExistsError} from "../../metadata-builder/error/MetadataAlreadyExistsError";
export class TargetMetadataArgsCollection<T extends { target?: Function|string }> {
// -------------------------------------------------------------------------
// Protected Properties
// -------------------------------------------------------------------------
protected items: T[] = [];
// -------------------------------------------------------------------------
// Public Properties
// -------------------------------------------------------------------------
get length() {
return this.items.length;
}
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
filter(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): this {
const collection = new (<any> this.constructor)();
this.items.filter(callbackfn).forEach(metadata => collection.add(metadata));
return collection;
}
filterByTarget(cls?: Function|string): this {
// if no class specified then simply return empty collection
if (!cls)
return new (<any> this.constructor)();
return this.filterByTargets([cls]);
}
filterByTargets(classes: Array<Function|string>): this { // Function[]|string[] ?
return this.filter(metadata => {
if (!metadata.target) return false;
return classes.indexOf(metadata.target) !== -1;
});
}
add(metadata: T, checkForDuplicateTargets = false) {
if (checkForDuplicateTargets) {
if (!metadata.target || !(metadata.target instanceof Function))
throw new Error(`Target is not set in the given metadata.`);
if (this.hasWithTarget(metadata.target))
throw new MetadataAlreadyExistsError((<any> metadata.constructor).name, metadata.target);
}
this.items.push(metadata);
}
toArray() {
return this.items.map(item => item);
}
// -------------------------------------------------------------------------
// Private Methods
// -------------------------------------------------------------------------
private hasWithTarget(constructor: Function): boolean {
return !!this.items.find(metadata => metadata.target === constructor);
}
}

View File

@ -7,12 +7,13 @@ import {MetadataArgsStorage} from "../metadata-args/MetadataArgsStorage";
import {EmbeddedMetadataArgs} from "../metadata-args/EmbeddedMetadataArgs";
import {RelationIdMetadata} from "../metadata/RelationIdMetadata";
import {RelationCountMetadata} from "../metadata/RelationCountMetadata";
import {MetadataUtils} from "../metadata-args/MetadataUtils";
import {MetadataUtils} from "./MetadataUtils";
import {TableMetadataArgs} from "../metadata-args/TableMetadataArgs";
import {JunctionEntityMetadataBuilder} from "./JunctionEntityMetadataBuilder";
import {ClosureJunctionEntityMetadataBuilder} from "./ClosureJunctionEntityMetadataBuilder";
import {RelationJoinColumnBuilder} from "./RelationJoinColumnBuilder";
import {Connection} from "../connection/Connection";
import {EntityListenerMetadata} from "../metadata/EntityListenerMetadata";
/**
* Builds EntityMetadata objects and all its sub-metadatas.
@ -58,7 +59,7 @@ export class EntityMetadataBuilder {
build(entityClasses?: Function[]): EntityMetadata[] {
// if entity classes to filter entities by are given then do filtering, otherwise use all
const allTables = entityClasses ? this.metadataArgsStorage.filterTables(entityClasses) : this.metadataArgsStorage.tables.toArray();
const allTables = entityClasses ? this.metadataArgsStorage.filterTables(entityClasses) : this.metadataArgsStorage.tables;
// filter out table metadata args for those we really create entity metadatas and tables in the db
const realTables = allTables.filter(table => table.type === "regular" || table.type === "closure" || table.type === "class-table-child");
@ -172,6 +173,9 @@ export class EntityMetadataBuilder {
entityMetadata.indices = this.metadataArgsStorage.filterIndices(inheritanceTree).map(args => {
return new IndexMetadata({ entityMetadata, args });
});
entityMetadata.listeners = this.metadataArgsStorage.filterListeners(inheritanceTree).map(args => {
return new EntityListenerMetadata(args);
});
return entityMetadata;
}

View File

@ -12,6 +12,11 @@ import {DepGraph} from "../util/DepGraph";
// todo: tree decorators can be used only on closure table (validation)
// todo: throw error if parent tree metadata was not specified in a closure table
// todo: MetadataArgsStorage: type in function validation, inverse side function validation
// todo: MetadataArgsStorage: check on build for duplicate names, since naming checking was removed from MetadataStorage
// todo: MetadataArgsStorage: duplicate name checking for: table, relation, column, index, naming strategy, join tables/columns?
// todo: MetadataArgsStorage: check for duplicate targets too since this check has been removed too
/**
* Validates built entity metadatas.
*/

View File

@ -5,14 +5,7 @@ import {RelationMetadata} from "./RelationMetadata";
import {ObjectLiteral} from "../common/ObjectLiteral";
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
import {ColumnMetadataArgs} from "../metadata-args/ColumnMetadataArgs";
/**
* Kinda type of the column. Not a type in the database, but locally used type to determine what kind of column
* we are working with.
* For example, "primary" means that it will be a primary column, or "createDate" means that it will create a create
* date column.
*/
export type ColumnMode = "regular"|"virtual"|"createDate"|"updateDate"|"version"|"treeChildrenCount"|"treeLevel"|"discriminator"|"parentId"|"objectId"|"array";
import {ColumnMode} from "./types/ColumnMode";
/**
* This metadata contains all information about entity's column.

View File

@ -1,5 +1,6 @@
import {EventListenerType} from "./types/EventListenerTypes";
import {EntityListenerMetadataArgs} from "../metadata-args/EntityListenerMetadataArgs";
import {ObjectLiteral} from "../common/ObjectLiteral";
/**
* This metadata contains all information about entity's listeners.
@ -7,23 +8,23 @@ import {EntityListenerMetadataArgs} from "../metadata-args/EntityListenerMetadat
export class EntityListenerMetadata {
// ---------------------------------------------------------------------
// Readonly Properties
// Properties
// ---------------------------------------------------------------------
/**
* Target class to which metadata is applied.
*/
readonly target: Function|string;
target: Function|string;
/**
* Target's property name to which this metadata is applied.
*/
readonly propertyName: string;
propertyName: string;
/**
* The type of the listener.
*/
readonly type: EventListenerType;
type: EventListenerType;
// ---------------------------------------------------------------------
// Constructor
@ -35,5 +36,16 @@ export class EntityListenerMetadata {
this.type = args.type;
}
// ---------------------------------------------------------------------
// Public Methods
// ---------------------------------------------------------------------
/**
* Checks if entity listener is allowed to be executed on the given entity.
*/
isAllowed(entity: ObjectLiteral) { // todo: create in entity metadata method like isInherited?
return this.target === entity.constructor || // todo: .constructor won't work for entity schemas
(this.target instanceof Function && entity.constructor.prototype instanceof this.target); // todo: also need to implement entity schema inheritance
}
}

View File

@ -1,5 +1,5 @@
import {ColumnMetadata} from "./ColumnMetadata";
import {PropertyTypeInFunction, RelationMetadata} from "./RelationMetadata";
import {RelationMetadata} from "./RelationMetadata";
import {IndexMetadata} from "./IndexMetadata";
import {ForeignKeyMetadata} from "./ForeignKeyMetadata";
import {EmbeddedMetadata} from "./EmbeddedMetadata";
@ -12,6 +12,8 @@ import {OrderByCondition} from "../find-options/OrderByCondition";
import {OrmUtils} from "../util/OrmUtils";
import {TableMetadataArgs} from "../metadata-args/TableMetadataArgs";
import {Connection} from "../connection/Connection";
import {EntityListenerMetadata} from "./EntityListenerMetadata";
import {PropertyTypeInFunction} from "./types/PropertyTypeInFunction";
/**
* Contains all entity metadata.
@ -156,6 +158,11 @@ export class EntityMetadata {
*/
embeddeds: EmbeddedMetadata[] = [];
/**
* Entity listener metadatas.
*/
listeners: EntityListenerMetadata[] = [];
/**
* If this entity metadata's table using one of the inheritance patterns,
* then this will contain what pattern it uses.
@ -179,9 +186,9 @@ export class EntityMetadata {
generatedColumn?: ColumnMetadata;
/**
* Gets the primary columns.
* Gets the object id column used with mongodb database.
*/
primaryColumns: ColumnMetadata[] = [];
objectIdColumn?: ColumnMetadata;
/**
* Gets entity column which contains a create date value.
@ -203,14 +210,20 @@ export class EntityMetadata {
*/
discriminatorColumn?: ColumnMetadata;
/**
* Special column that stores tree level in tree entities.
*/
treeLevelColumn?: ColumnMetadata;
parentIdColumns: ColumnMetadata[] = [];
/**
* Gets the primary columns.
*/
primaryColumns: ColumnMetadata[] = [];
/**
* Gets the object id column used with mongodb database.
* Id columns in the parent table (used in table inheritance).
*/
objectIdColumn?: ColumnMetadata;
parentIdColumns: ColumnMetadata[] = [];
/**
* Gets only one-to-one relations of the entity.
@ -556,6 +569,10 @@ export class EntityMetadata {
/**
* Creates a special object - all columns and relations of the object (plus columns and relations from embeds)
* in a special format - { propertyName: propertyName }.
*
* example: Post{ id: number, name: string, counterEmbed: { count: number }, category: Category }.
* This method will create following object:
* { id: "id", counterEmbed: { count: "counterEmbed.count" }, category: "category" }
*/
createPropertiesMap(): { [name: string]: string|any } {
const map: { [name: string]: string|any } = {};

View File

@ -1,17 +0,0 @@
import {EntitySubscriberMetadataArgs} from "../metadata-args/EntitySubscriberMetadataArgs";
/**
* Contains metadata information about ORM event subscribers.
*/
export class EntitySubscriberMetadata {
/**
* Target class to which metadata is applied.
*/
readonly target: Function|string;
constructor(args: EntitySubscriberMetadataArgs) {
this.target = args.target;
}
}

View File

@ -1,12 +1,7 @@
import {ColumnMetadata} from "./ColumnMetadata";
import {EntityMetadata} from "./EntityMetadata";
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
import {RelationMetadata} from "./RelationMetadata";
/**
* ON_DELETE type to be used to specify delete strategy when some relation is being deleted from the database.
*/
export type OnDeleteType = "RESTRICT"|"CASCADE"|"SET NULL";
import {OnDeleteType} from "./types/OnDeleteType";
/**
* Contains all information about entity's foreign key.
@ -27,29 +22,21 @@ export class ForeignKeyMetadata {
*/
referencedEntityMetadata: EntityMetadata;
// -------------------------------------------------------------------------
// Public Readonly Properties
// -------------------------------------------------------------------------
/**
* Array of columns of this foreign key.
*/
columns: ColumnMetadata[];
columns: ColumnMetadata[] = [];
/**
* Array of referenced columns.
*/
referencedColumns: ColumnMetadata[];
referencedColumns: ColumnMetadata[] = [];
/**
* What to do with a relation on deletion of the row containing a foreign key.
*/
onDelete?: OnDeleteType;
// -------------------------------------------------------------------------
// Accessors
// -------------------------------------------------------------------------
/**
* Gets the table name to which this foreign key is applied.
*/
@ -68,12 +55,12 @@ export class ForeignKeyMetadata {
/**
* Gets array of column names.
*/
columnNames: string[];
columnNames: string[] = [];
/**
* Gets array of referenced column names.
*/
referencedColumnNames: string[];
referencedColumnNames: string[] = [];
// ---------------------------------------------------------------------
// Constructor
@ -96,6 +83,10 @@ export class ForeignKeyMetadata {
this.build(options.namingStrategy);
}
// ---------------------------------------------------------------------
// Public Methods
// ---------------------------------------------------------------------
build(namingStrategy: NamingStrategyInterface) {
this.columnNames = this.columns.map(column => column.databaseName);
this.referencedColumnNames = this.referencedColumns.map(column => column.databaseName);

View File

@ -1,6 +1,5 @@
import {EntityMetadata} from "./EntityMetadata";
import {IndexMetadataArgs} from "../metadata-args/IndexMetadataArgs";
import {RelationCountMetadataArgs} from "../metadata-args/RelationCountMetadataArgs";
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
import {ColumnMetadata} from "./ColumnMetadata";
@ -49,6 +48,11 @@ export class IndexMetadata {
*/
name: string;
/**
* Gets the table name on which index is applied.
*/
tableName: string;
// ---------------------------------------------------------------------
// Constructor
// ---------------------------------------------------------------------
@ -71,16 +75,7 @@ export class IndexMetadata {
}
// ---------------------------------------------------------------------
// Accessors
// ---------------------------------------------------------------------
/**
* Gets the table name on which index is applied.
*/
tableName: string;
// ---------------------------------------------------------------------
// Build Methods
// Public Build Methods
// ---------------------------------------------------------------------
build(namingStrategy: NamingStrategyInterface): this {

View File

@ -1,13 +0,0 @@
import {TargetMetadata} from "./TargetMetadata";
/**
* This represents metadata of some object's property.
*/
export interface PropertyMetadata extends TargetMetadata {
/**
* Target's property name to which this metadata is applied.
*/
readonly propertyName: string;
}

View File

@ -1,22 +1,13 @@
import {RelationType} from "./types/RelationTypes";
import {EntityMetadata} from "./EntityMetadata";
import {ForeignKeyMetadata, OnDeleteType} from "./ForeignKeyMetadata";
import {ForeignKeyMetadata} from "./ForeignKeyMetadata";
import {ObjectLiteral} from "../common/ObjectLiteral";
import {ColumnMetadata} from "./ColumnMetadata";
import {EmbeddedMetadata} from "./EmbeddedMetadata";
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
import {RelationMetadataArgs} from "../metadata-args/RelationMetadataArgs";
/**
* Function that returns a type of the field. Returned value must be a class used on the relation.
*/
export type RelationTypeInFunction = ((type?: any) => Function)|Function|string; // todo: |string ?
/**
* Contains the name of the property of the object, or the function that returns this name.
*/
export type PropertyTypeInFunction<T> = string|((t: T) => string|any);
import {OnDeleteType} from "./types/OnDeleteType";
import {PropertyTypeInFunction} from "./types/PropertyTypeInFunction";
/**
* Contains all information about some entity's relation.

View File

@ -1,11 +0,0 @@
/**
* This represents metadata of some object.
*/
export interface TargetMetadata {
/**
* Target class to which metadata is applied.
*/
readonly target: Function|string;
}

View File

@ -0,0 +1,7 @@
/**
* Kinda type of the column. Not a type in the database, but locally used type to determine what kind of column
* we are working with.
* For example, "primary" means that it will be a primary column, or "createDate" means that it will create a create
* date column.
*/
export type ColumnMode = "regular"|"virtual"|"createDate"|"updateDate"|"version"|"treeChildrenCount"|"treeLevel"|"discriminator"|"parentId"|"objectId"|"array";

View File

@ -0,0 +1,5 @@
/**
* ON_DELETE type to be used to specify delete strategy when some relation is being deleted from the database.
*/
export type OnDeleteType = "RESTRICT"|"CASCADE"|"SET NULL";

View File

@ -0,0 +1,4 @@
/**
* Contains the name of the property of the object, or the function that returns this name.
*/
export type PropertyTypeInFunction<T> = string|((t: T) => string|any);

View File

@ -0,0 +1,5 @@
/**
* Function that returns a type of the field. Returned value must be a class used on the relation.
*/
export type RelationTypeInFunction = ((type?: any) => Function)|Function|string; // todo: |string ?

View File

@ -16,8 +16,7 @@ export class Broadcaster {
// -------------------------------------------------------------------------
constructor(private connection: Connection,
private subscriberMetadatas: EntitySubscriberInterface<any>[],
private entityListeners: EntityListenerMetadata[]) {
private subscriberMetadatas: EntitySubscriberInterface<any>[]) {
}
// -------------------------------------------------------------------------
@ -54,8 +53,8 @@ export class Broadcaster {
*/
async broadcastBeforeInsertEvent(entityManager: EntityManager, subject: Subject): Promise<void> {
const listeners = this.entityListeners
.filter(listener => listener.type === EventListenerTypes.BEFORE_INSERT && this.isAllowedListener(listener, subject.entity))
const listeners = subject.metadata.listeners
.filter(listener => listener.type === EventListenerTypes.BEFORE_INSERT && listener.isAllowed(subject.entity))
.map(entityListener => subject.entity[entityListener.propertyName]()); // getValue() ?
const subscribers = this.subscriberMetadatas
@ -76,8 +75,8 @@ export class Broadcaster {
*/
async broadcastBeforeUpdateEvent(entityManager: EntityManager, subject: Subject): Promise<void> { // todo: send relations too?
const listeners = this.entityListeners
.filter(listener => listener.type === EventListenerTypes.BEFORE_UPDATE && this.isAllowedListener(listener, subject.entity))
const listeners = subject.metadata.listeners
.filter(listener => listener.type === EventListenerTypes.BEFORE_UPDATE && listener.isAllowed(subject.entity))
.map(entityListener => subject.entity[entityListener.propertyName]());
const subscribers = this.subscriberMetadatas
@ -101,8 +100,8 @@ export class Broadcaster {
*/
async broadcastBeforeRemoveEvent(entityManager: EntityManager, subject: Subject): Promise<void> {
const listeners = this.entityListeners
.filter(listener => listener.type === EventListenerTypes.BEFORE_REMOVE && this.isAllowedListener(listener, subject.entity))
const listeners = subject.metadata.listeners
.filter(listener => listener.type === EventListenerTypes.BEFORE_REMOVE && listener.isAllowed(subject.entity))
.map(entityListener => subject.databaseEntity[entityListener.propertyName]());
const subscribers = this.subscriberMetadatas
@ -125,8 +124,8 @@ export class Broadcaster {
*/
async broadcastAfterInsertEvent(entityManager: EntityManager, subject: Subject): Promise<void> {
const listeners = this.entityListeners
.filter(listener => listener.type === EventListenerTypes.AFTER_INSERT && this.isAllowedListener(listener, subject.entity))
const listeners = subject.metadata.listeners
.filter(listener => listener.type === EventListenerTypes.AFTER_INSERT && listener.isAllowed(subject.entity))
.map(entityListener => subject.entity[entityListener.propertyName]());
const subscribers = this.subscriberMetadatas
@ -147,8 +146,8 @@ export class Broadcaster {
*/
async broadcastAfterUpdateEvent(entityManager: EntityManager, subject: Subject): Promise<void> {
const listeners = this.entityListeners
.filter(listener => listener.type === EventListenerTypes.AFTER_UPDATE && this.isAllowedListener(listener, subject.entity))
const listeners = subject.metadata.listeners
.filter(listener => listener.type === EventListenerTypes.AFTER_UPDATE && listener.isAllowed(subject.entity))
.map(entityListener => subject.entity[entityListener.propertyName]());
const subscribers = this.subscriberMetadatas
@ -172,8 +171,8 @@ export class Broadcaster {
*/
async broadcastAfterRemoveEvent(entityManager: EntityManager, subject: Subject): Promise<void> {
const listeners = this.entityListeners
.filter(listener => listener.type === EventListenerTypes.AFTER_REMOVE && this.isAllowedListener(listener, subject.entity))
const listeners = subject.metadata.listeners
.filter(listener => listener.type === EventListenerTypes.AFTER_REMOVE && listener.isAllowed(subject.entity))
.map(entityListener => subject.entity[entityListener.propertyName]());
const subscribers = this.subscriberMetadatas
@ -223,8 +222,8 @@ export class Broadcaster {
return promises;
}, [] as Promise<void>[]);
const listeners = this.entityListeners
.filter(listener => listener.type === EventListenerTypes.AFTER_LOAD && this.isAllowedListener(listener, entity))
const listeners = this.connection.getMetadata(target).listeners
.filter(listener => listener.type === EventListenerTypes.AFTER_LOAD && listener.isAllowed(entity))
.map(listener => entity[listener.propertyName]());
const subscribers = this.subscriberMetadatas
@ -238,15 +237,6 @@ export class Broadcaster {
// Protected Methods
// -------------------------------------------------------------------------
/**
* Checks if entity listener is allowed to be executed on the given entity.
*/
protected isAllowedListener(listener: EntityListenerMetadata, entity: ObjectLiteral) {
// todo: create in entity metadata method like isInherited
return listener.target === entity.constructor || // todo: .constructor won't work for entity schemas
(listener.target instanceof Function && entity.constructor.prototype instanceof listener.target); // todo: also need to implement entity schema inheritance
}
/**
* Checks if subscriber's methods can be executed by checking if its don't listen to the particular entity,
* or listens our entity.

View File

@ -2,7 +2,7 @@ import "reflect-metadata";
import {Post} from "./entity/Post";
import {ContentModule} from "./entity/ContentModule";
import {Unit} from "./entity/Unit";
import {MetadataUtils} from "../../../../src/metadata-args/MetadataUtils";
import {MetadataUtils} from "../../../../src/metadata-builder/MetadataUtils";
describe("metadata builder > MetadataArgsUtils", () => {