refactored metadata args

This commit is contained in:
Umed Khudoiberdiev 2016-05-25 11:06:57 +05:00
parent fc7def3934
commit 4ed27902b9
56 changed files with 342 additions and 384 deletions

View File

@ -17,7 +17,7 @@ export class CustomNamingStrategy implements NamingStrategyInterface {
return _.snakeCase(propertyName);
}
indexName(target: Function, name: string, columns: string[]): string {
indexName(target: Function, name: string|undefined, columns: string[]): string {
if (name)
return name;

View File

@ -348,20 +348,20 @@ export class Connection {
// take imported naming strategy metadatas
getMetadataArgsStorage()
.namingStrategyMetadatas
.namingStrategies
.filterByClasses(this.namingStrategyClasses)
.forEach(metadata => this.namingStrategyMetadatas.push(new NamingStrategyMetadata(metadata)));
// take imported event subscribers
getMetadataArgsStorage()
.eventSubscriberMetadatas
.eventSubscribers
.filterByClasses(this.subscriberClasses)
.map(metadata => getFromContainer(metadata.target))
.forEach(subscriber => this.eventSubscribers.push(subscriber));
// take imported entity listeners
getMetadataArgsStorage()
.entityListenerMetadatas
.entityListeners
.filterByClasses(this.entityClasses)
.forEach(metadata => this.entityListeners.push(new EntityListenerMetadata(metadata)));

View File

@ -7,10 +7,10 @@ import {NamingStrategyMetadataArgs} from "../metadata/args/NamingStrategyMetadat
export function NamingStrategy(name?: string): Function {
return function (target: Function) {
const strategyName = name ? name : (<any> target).name;
const metadata: NamingStrategyMetadataArgs = {
const args: NamingStrategyMetadataArgs = {
target: target,
name: strategyName
};
getMetadataArgsStorage().namingStrategyMetadatas.add(metadata);
getMetadataArgsStorage().namingStrategies.add(args);
};
}

View File

@ -53,12 +53,13 @@ export function Column(typeOrOptions?: ColumnType|ColumnOptions, options?: Colum
throw new AutoIncrementOnlyForPrimaryError(object, propertyName);
// create and register a new column metadata
const metadata: ColumnMetadataArgs = {
const args: ColumnMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
propertyType: reflectedType,
mode: "regular",
options: options
};
getMetadataArgsStorage().columnMetadatas.add(metadata);
getMetadataArgsStorage().columns.add(args);
};
}

View File

@ -20,14 +20,14 @@ export function CreateDateColumn(options?: ColumnOptions): Function {
options.type = ColumnTypes.DATETIME;
// create and register a new column metadata
const metadata: ColumnMetadataArgs = {
const args: ColumnMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
propertyType: reflectedType,
mode: "createDate",
options: options
};
getMetadataArgsStorage().columnMetadatas.add(metadata);
getMetadataArgsStorage().columns.add(args);
};
}

View File

@ -55,14 +55,14 @@ export function PrimaryColumn(typeOrOptions?: ColumnType|ColumnOptions, options?
throw new PrimaryColumnCannotBeNullableError(object, propertyName);
// create and register a new column metadata
const metadata: ColumnMetadataArgs = {
const args: ColumnMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
propertyType: reflectedType,
isPrimaryKey: true,
mode: "primary",
options: options
};
getMetadataArgsStorage().columnMetadatas.add(metadata);
getMetadataArgsStorage().columns.add(args);
};
}

View File

@ -11,12 +11,12 @@ export function RelationsCountColumn<T>(relation: string|((object: T) => any)):
// const reflectedType = ColumnTypes.typeToString((<any> Reflect).getMetadata("design:type", object, propertyName));
// create and register a new column metadata
const metadata: RelationsCountMetadataArgs = {
const args: RelationsCountMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
relation: relation
};
getMetadataArgsStorage().relationCountMetadatas.add(metadata);
getMetadataArgsStorage().relationCounts.add(args);
};
}

View File

@ -19,14 +19,14 @@ export function UpdateDateColumn(options?: ColumnOptions): Function {
options.type = ColumnTypes.DATETIME;
// create and register a new column metadata
const metadata: ColumnMetadataArgs = {
const args: ColumnMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
propertyType: reflectedType,
mode: "updateDate",
options: options
};
getMetadataArgsStorage().columnMetadatas.add(metadata);
getMetadataArgsStorage().columns.add(args);
};
}

View File

@ -21,14 +21,14 @@ export function VersionColumn(options?: ColumnOptions): Function {
// todo: check if reflectedType is number too
// create and register a new column metadata
const metadata: ColumnMetadataArgs = {
const args: ColumnMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
propertyType: reflectedType,
mode: "version",
options: options
};
getMetadataArgsStorage().columnMetadatas.add(metadata);
getMetadataArgsStorage().columns.add(args);
};
}

View File

@ -1,14 +1,30 @@
import {getMetadataArgsStorage} from "../../index";
import {CompositeIndexOptions} from "../../metadata/options/CompositeIndexOptions";
import {CompositeIndexMetadataArgs} from "../../metadata/args/CompositeIndexMetadataArgs";
import {IndexMetadataArgs} from "../../metadata/args/IndexMetadataArgs";
/**
* Composite indexes must be set on entity classes and must specify fields to be indexed.
* Composite index must be set on entity classes and must specify entity's fields to be indexed.
*/
export function CompositeIndex(name: string, fields: string[], options?: CompositeIndexOptions): Function;
/**
* Composite index must be set on entity classes and must specify entity's fields to be indexed.
*/
export function CompositeIndex(fields: string[], options?: CompositeIndexOptions): Function;
/**
* Composite index must be set on entity classes and must specify entity's fields to be indexed.
*/
export function CompositeIndex(fields: (object: any) => any[], options?: CompositeIndexOptions): Function;
/**
* Composite index must be set on entity classes and must specify entity's fields to be indexed.
*/
export function CompositeIndex(name: string, fields: (object: any) => any[], options?: CompositeIndexOptions): Function;
/**
* Composite index must be set on entity classes and must specify entity's fields to be indexed.
*/
export function CompositeIndex(nameOrFields: string|string[]|((object: any) => any[]),
maybeFieldsOrOptions?: ((object: any) => any[])|CompositeIndexOptions|string[],
maybeOptions?: CompositeIndexOptions): Function {
@ -17,12 +33,12 @@ export function CompositeIndex(nameOrFields: string|string[]|((object: any) => a
const options = typeof maybeFieldsOrOptions === "object" ? <CompositeIndexOptions> maybeFieldsOrOptions : maybeOptions;
return function (cls: Function) {
const metadata: CompositeIndexMetadataArgs = {
const args: IndexMetadataArgs = {
target: cls,
name: name,
columns: fields,
options: options
unique: options && options.unique ? true : false
};
getMetadataArgsStorage().compositeIndexMetadatas.add(metadata);
getMetadataArgsStorage().indices.add(args);
};
}

View File

@ -4,13 +4,14 @@ import {IndexMetadataArgs} from "../../metadata/args/IndexMetadataArgs";
/**
* Fields that needs to be indexed must be marked with this decorator.
*/
export function Index(name?: string) {
export function Index(name?: string, options?: { unique: boolean }) {
return function (object: Object, propertyName: string) {
const metadata: IndexMetadataArgs = {
const args: IndexMetadataArgs = {
name: name,
target: object.constructor,
propertyName: propertyName,
name: name
columns: [propertyName],
unique: options && options.unique ? true : false
};
getMetadataArgsStorage().indexMetadatas.add(metadata);
getMetadataArgsStorage().indices.add(args);
};
}

View File

@ -8,11 +8,11 @@ import {EntityListenerMetadataArgs} from "../../metadata/args/EntityListenerMeta
export function AfterInsert() {
return function (object: Object, propertyName: string) {
const metadata: EntityListenerMetadataArgs = {
const args: EntityListenerMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
type: EventListenerTypes.AFTER_INSERT
};
getMetadataArgsStorage().entityListenerMetadatas.add(metadata);
getMetadataArgsStorage().entityListeners.add(args);
};
}

View File

@ -7,11 +7,11 @@ import {EntityListenerMetadataArgs} from "../../metadata/args/EntityListenerMeta
*/
export function AfterLoad() {
return function (object: Object, propertyName: string) {
const metadata: EntityListenerMetadataArgs = {
const args: EntityListenerMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
type: EventListenerTypes.AFTER_LOAD
};
getMetadataArgsStorage().entityListenerMetadatas.add(metadata);
getMetadataArgsStorage().entityListeners.add(args);
};
}

View File

@ -7,11 +7,11 @@ import {EntityListenerMetadataArgs} from "../../metadata/args/EntityListenerMeta
*/
export function AfterRemove() {
return function (object: Object, propertyName: string) {
const metadata: EntityListenerMetadataArgs = {
const args: EntityListenerMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
type: EventListenerTypes.AFTER_REMOVE
};
getMetadataArgsStorage().entityListenerMetadatas.add(metadata);
getMetadataArgsStorage().entityListeners.add(args);
};
}

View File

@ -7,11 +7,11 @@ import {EntityListenerMetadataArgs} from "../../metadata/args/EntityListenerMeta
*/
export function AfterUpdate() {
return function (object: Object, propertyName: string) {
const metadata: EntityListenerMetadataArgs = {
const args: EntityListenerMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
type: EventListenerTypes.AFTER_UPDATE
};
getMetadataArgsStorage().entityListenerMetadatas.add(metadata);
getMetadataArgsStorage().entityListeners.add(args);
};
}

View File

@ -7,11 +7,11 @@ import {EntityListenerMetadataArgs} from "../../metadata/args/EntityListenerMeta
*/
export function BeforeInsert() {
return function (object: Object, propertyName: string) {
const metadata: EntityListenerMetadataArgs = {
const args: EntityListenerMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
type: EventListenerTypes.BEFORE_INSERT
};
getMetadataArgsStorage().entityListenerMetadatas.add(metadata);
getMetadataArgsStorage().entityListeners.add(args);
};
}

View File

@ -7,11 +7,11 @@ import {EntityListenerMetadataArgs} from "../../metadata/args/EntityListenerMeta
*/
export function BeforeRemove() {
return function (object: Object, propertyName: string) {
const metadata: EntityListenerMetadataArgs = {
const args: EntityListenerMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
type: EventListenerTypes.BEFORE_REMOVE
};
getMetadataArgsStorage().entityListenerMetadatas.add(metadata);
getMetadataArgsStorage().entityListeners.add(args);
};
}

View File

@ -7,11 +7,11 @@ import {EntityListenerMetadataArgs} from "../../metadata/args/EntityListenerMeta
*/
export function BeforeUpdate() {
return function (object: Object, propertyName: string) {
const metadata: EntityListenerMetadataArgs = {
const args: EntityListenerMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
type: EventListenerTypes.BEFORE_UPDATE
};
getMetadataArgsStorage().entityListenerMetadatas.add(metadata);
getMetadataArgsStorage().entityListeners.add(args);
};
}

View File

@ -7,9 +7,9 @@ import {EventSubscriberMetadataArgs} from "../../metadata/args/EventSubscriberMe
*/
export function EventSubscriber() {
return function (target: Function) {
const metadata: EventSubscriberMetadataArgs = {
const args: EventSubscriberMetadataArgs = {
target: target
};
getMetadataArgsStorage().eventSubscriberMetadatas.add(metadata);
getMetadataArgsStorage().eventSubscribers.add(args);
};
}

View File

@ -7,12 +7,12 @@ import {JoinColumnMetadataArgs} from "../../metadata/args/JoinColumnMetadataArgs
export function JoinColumn(options?: JoinColumnOptions): Function {
return function (object: Object, propertyName: string) {
options = options || {} as JoinColumnOptions;
const metadata: JoinColumnMetadataArgs = {
const args: JoinColumnMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
options: options
};
getMetadataArgsStorage().joinColumnMetadatas.add(metadata);
getMetadataArgsStorage().joinColumns.add(args);
};
}

View File

@ -7,12 +7,12 @@ import {JoinTableMetadataArgs} from "../../metadata/args/JoinTableMetadataArgs";
export function JoinTable(options?: JoinTableOptions): Function {
return function (object: Object, propertyName: string) {
options = options || {} as JoinTableOptions;
const metadata: JoinTableMetadataArgs = {
const args: JoinTableMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
options: options
};
getMetadataArgsStorage().joinTableMetadatas.add(metadata);
getMetadataArgsStorage().joinTables.add(args);
};
}

View File

@ -40,7 +40,7 @@ export function ManyToMany<T>(typeFunction: (type?: any) => ConstructorFunction<
const reflectedType = (<any> Reflect).getMetadata("design:type", object, propertyName);
const metadata: RelationMetadataArgs = {
const args: RelationMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
propertyType: reflectedType,
@ -49,7 +49,7 @@ export function ManyToMany<T>(typeFunction: (type?: any) => ConstructorFunction<
inverseSideProperty: inverseSideProperty,
options: options
};
getMetadataArgsStorage().relationMetadatas.add(metadata);
getMetadataArgsStorage().relations.add(args);
};
}

View File

@ -40,7 +40,7 @@ export function ManyToOne<T>(typeFunction: (type?: any) => ConstructorFunction<T
const reflectedType = (<any> Reflect).getMetadata("design:type", object, propertyName);
const metadata: RelationMetadataArgs = {
const args: RelationMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
propertyType: reflectedType,
@ -49,6 +49,6 @@ export function ManyToOne<T>(typeFunction: (type?: any) => ConstructorFunction<T
inverseSideProperty: inverseSideProperty,
options: options
};
getMetadataArgsStorage().relationMetadatas.add(metadata);
getMetadataArgsStorage().relations.add(args);
};
}

View File

@ -42,7 +42,7 @@ export function OneToMany<T>(typeFunction: (type?: any) => ConstructorFunction<T
const reflectedType = (<any> Reflect).getMetadata("design:type", object, propertyName);
const metadata: RelationMetadataArgs = {
const args: RelationMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
propertyType: reflectedType,
@ -51,7 +51,7 @@ export function OneToMany<T>(typeFunction: (type?: any) => ConstructorFunction<T
inverseSideProperty: inverseSideProperty,
options: options
};
getMetadataArgsStorage().relationMetadatas.add(metadata);
getMetadataArgsStorage().relations.add(args);
};
}

View File

@ -37,7 +37,7 @@ export function OneToOne<T>(typeFunction: (type?: any) => ConstructorFunction<T>
const reflectedType = (<any> Reflect).getMetadata("design:type", object, propertyName);
const metadata: RelationMetadataArgs = {
const args: RelationMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
propertyType: reflectedType,
@ -46,6 +46,6 @@ export function OneToOne<T>(typeFunction: (type?: any) => ConstructorFunction<T>
inverseSideProperty: inverseSideProperty,
options: options
};
getMetadataArgsStorage().relationMetadatas.add(metadata);
getMetadataArgsStorage().relations.add(args);
};
}

View File

@ -6,11 +6,11 @@ import {TableMetadataArgs} from "../../metadata/args/TableMetadataArgs";
*/
export function AbstractTable() {
return function (target: Function) {
const metadata: TableMetadataArgs = {
const args: TableMetadataArgs = {
target: target,
name: undefined,
type: "abstract"
};
getMetadataArgsStorage().tableMetadatas.add(metadata);
getMetadataArgsStorage().tables.add(args);
};
}

View File

@ -7,11 +7,11 @@ import {TableMetadataArgs} from "../../metadata/args/TableMetadataArgs";
*/
export function ClosureTable(name?: string) {
return function (target: Function) {
const metadata: TableMetadataArgs = {
const args: TableMetadataArgs = {
target: target,
name: name,
type: "closure"
};
getMetadataArgsStorage().tableMetadatas.add(metadata);
getMetadataArgsStorage().tables.add(args);
};
}

View File

@ -7,11 +7,11 @@ import {TableMetadataArgs} from "../../metadata/args/TableMetadataArgs";
*/
export function Table(name?: string) {
return function (target: Function) {
const metadata: TableMetadataArgs = {
const args: TableMetadataArgs = {
target: target,
name: name,
type: "regular"
};
getMetadataArgsStorage().tableMetadatas.add(metadata);
getMetadataArgsStorage().tables.add(args);
};
}

View File

@ -13,7 +13,7 @@ export function TreeChildren(options?: RelationOptions): Function {
const reflectedType = (<any> Reflect).getMetadata("design:type", object, propertyName);
// add one-to-many relation for this
const metadata: RelationMetadataArgs = {
const args: RelationMetadataArgs = {
isTreeChildren: true,
target: object.constructor,
propertyName: propertyName,
@ -22,7 +22,7 @@ export function TreeChildren(options?: RelationOptions): Function {
type: () => object.constructor,
options: options
};
getMetadataArgsStorage().relationMetadatas.add(metadata);
getMetadataArgsStorage().relations.add(args);
};
}

View File

@ -18,14 +18,14 @@ export function TreeLevelColumn(): Function {
options.type = ColumnTypes.INTEGER;
// create and register a new column metadata
const metadata: ColumnMetadataArgs = {
const args: ColumnMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
propertyType: reflectedType,
mode: "treeLevel",
options: options
};
getMetadataArgsStorage().columnMetadatas.add(metadata);
getMetadataArgsStorage().columns.add(args);
};
}

View File

@ -11,7 +11,7 @@ export function TreeParent(options?: RelationOptions): Function {
if (!options) options = {} as RelationOptions;
const reflectedType = (<any> Reflect).getMetadata("design:type", object, propertyName);
const metadata: RelationMetadataArgs = {
const args: RelationMetadataArgs = {
isTreeParent: true,
target: object.constructor,
propertyName: propertyName,
@ -20,7 +20,7 @@ export function TreeParent(options?: RelationOptions): Function {
type: () => object.constructor,
options: options
};
getMetadataArgsStorage().relationMetadatas.add(metadata);
getMetadataArgsStorage().relations.add(args);
};
}

View File

@ -5,9 +5,6 @@ import {ColumnOptions} from "../metadata/options/ColumnOptions";
import {ForeignKeyMetadata} from "../metadata/ForeignKeyMetadata";
import {EntityMetadataValidator} from "./EntityMetadataValidator";
import {IndexMetadata} from "../metadata/IndexMetadata";
import {CompositeIndexMetadata} from "../metadata/CompositeIndexMetadata";
import {PropertyMetadataCollection} from "../metadata/collection/PropertyMetadataCollection";
import {TargetMetadataCollection} from "../metadata/collection/TargetMetadataCollection";
import {JoinColumnMetadata} from "../metadata/JoinColumnMetadata";
import {JoinColumnOptions} from "../metadata/options/JoinColumnOptions";
import {TableMetadata} from "../metadata/TableMetadata";
@ -43,7 +40,7 @@ export class EntityMetadataBuilder {
const allMetadataStorage = getMetadataArgsStorage();
// filter the only metadata we need - those which are bind to the given table classes
const allTableMetadatas = allMetadataStorage.tableMetadatas.filterByClasses(entityClasses);
const allTableMetadatas = allMetadataStorage.tables.filterByClasses(entityClasses);
const tableMetadatas = allTableMetadatas
.filterByClasses(entityClasses)
.filter(metadata => metadata.type !== "abstract");
@ -58,21 +55,15 @@ export class EntityMetadataBuilder {
const mergedMetadata = allMetadataStorage.mergeWithAbstract(allTableMetadatas, tableMetadata);
// create layouts from metadatas
const columns = mergedMetadata.columnMetadatas.map(metadata => new ColumnMetadata(metadata));
const relations = mergedMetadata.relationMetadatas.map(metadata => new RelationMetadata(metadata));
const compositeIndices = mergedMetadata.compositeIndexMetadatas.map(metadata => new CompositeIndexMetadata(metadata));
// merge indices and composite indices because simple indices actually are compose indices with only one column
// todo: no need to create index layout for this, use index metadata instead
const indices = mergedMetadata.indexMetadatas.map(metadata => new IndexMetadata(metadata));
const compositeFromSimpleIndices = this.createCompositeIndicesFromSimpleIndices(indices);
compositeIndices.push(...compositeFromSimpleIndices);
const columns = mergedMetadata.columns.map(metadata => new ColumnMetadata(metadata));
const relations = mergedMetadata.relations.map(metadata => new RelationMetadata(metadata));
const indices = mergedMetadata.indices.map(metadata => new IndexMetadata(metadata));
// todo no need to set naming strategy everywhere - childs can obtain it from their parents
// tableMetadata.namingStrategy = namingStrategy;
columns.forEach(column => column.namingStrategy = namingStrategy);
relations.forEach(relation => relation.namingStrategy = namingStrategy);
compositeIndices.forEach(index => index.namingStrategy = namingStrategy);
indices.forEach(index => index.namingStrategy = namingStrategy);
// todo: check if multiple tree parent metadatas in validator
// todo: tree decorators can be used only on closure table (validation)
@ -84,12 +75,12 @@ export class EntityMetadataBuilder {
new TableMetadata(tableMetadata),
columns,
relations,
compositeIndices
indices
);
// create entity's relations join tables
entityMetadata.manyToManyRelations.forEach(relation => {
const joinTableMetadata = mergedMetadata.joinTableMetadatas.findByProperty(relation.propertyName);
const joinTableMetadata = mergedMetadata.joinTables.findByProperty(relation.propertyName);
if (joinTableMetadata) {
const joinTable = new JoinTableMetadata(joinTableMetadata);
relation.joinTable = joinTable;
@ -99,7 +90,7 @@ export class EntityMetadataBuilder {
// create entity's relations join columns
entityMetadata.relations.forEach(relation => {
const joinColumnMetadata = mergedMetadata.joinColumnMetadatas.findByProperty(relation.propertyName);
const joinColumnMetadata = mergedMetadata.joinColumns.findByProperty(relation.propertyName);
if (joinColumnMetadata) {
const joinColumn = new JoinColumnMetadata(joinColumnMetadata);
relation.joinColumn = joinColumn;
@ -110,7 +101,7 @@ export class EntityMetadataBuilder {
// since for many-to-one relations having JoinColumn is not required on decorators level, we need to go
// throw all of them which don't have JoinColumn decorators and create it for them
entityMetadata.manyToOneRelations.forEach(relation => {
let joinColumnMetadata = mergedMetadata.joinColumnMetadatas.findByProperty(relation.propertyName);
let joinColumnMetadata = mergedMetadata.joinColumns.findByProperty(relation.propertyName);
if (!joinColumnMetadata) {
joinColumnMetadata = { target: relation.target, propertyName: relation.propertyName, options: <JoinColumnOptions> {} };
const joinColumn = new JoinColumnMetadata(joinColumnMetadata);
@ -154,7 +145,7 @@ export class EntityMetadataBuilder {
target: metadata.target,
propertyName: relation.name,
propertyType: inverseSideColumn.propertyType,
isVirtual: true,
mode: "virtual",
options: options
});
metadata.columns.push(relationalColumn);
@ -185,6 +176,7 @@ export class EntityMetadataBuilder {
target: Function, // todo: temp, fix it later
propertyName: "", // todo: temp, fix it later
propertyType: metadata.primaryColumn.type,
mode: "regular", // or virtual?
options: <ColumnOptions> {
length: metadata.primaryColumn.length,
type: metadata.primaryColumn.type,
@ -195,6 +187,7 @@ export class EntityMetadataBuilder {
target: Function, // todo: temp, fix it later
propertyName: "", // todo: temp, fix it later
propertyType: metadata.primaryColumn.type,
mode: "regular", // or virtual?
options: <ColumnOptions> {
length: metadata.primaryColumn.length,
type: metadata.primaryColumn.type,
@ -208,6 +201,7 @@ export class EntityMetadataBuilder {
target: Function, // todo: temp, fix it later
propertyName: "", // todo: temp, fix it later
propertyType: ColumnTypes.INTEGER,
mode: "regular", // or virtual?
options: {
type: ColumnTypes.INTEGER,
name: "level"
@ -252,12 +246,14 @@ export class EntityMetadataBuilder {
target: Function, // todo: temp, fix it later
propertyName: "", // todo: temp, fix it later
propertyType: column2.type,
mode: "regular", // or virtual?
options: column1options
}),
new ColumnMetadata({
target: Function, // todo: temp, fix it later
propertyName: "", // todo: temp, fix it later
propertyType: column2.type,
mode: "regular", // or virtual?
options: column2options
})
];
@ -282,16 +278,5 @@ export class EntityMetadataBuilder {
// Private Methods
// -------------------------------------------------------------------------
private createCompositeIndicesFromSimpleIndices(indices: IndexMetadata[]) {
return indices.map(index => {
return new CompositeIndexMetadata({
name: index.name,
target: index.target,
columns: [index.propertyName]
});
});
// later need to check if no duplicate keys in composite indices?
}
}

View File

@ -1,7 +1,6 @@
import {TableMetadata} from "../metadata/TableMetadata";
import {RelationMetadata} from "../metadata/RelationMetadata";
import {IndexMetadata} from "../metadata/IndexMetadata";
import {CompositeIndexMetadata} from "../metadata/CompositeIndexMetadata";
import {ColumnMetadata} from "../metadata/ColumnMetadata";
import {EventSubscriberMetadata} from "../metadata/EventSubscriberMetadata";
import {EntityListenerMetadata} from "../metadata/EntityListenerMetadata";
@ -14,7 +13,6 @@ import {RelationsCountMetadata} from "../metadata/RelationsCountMetadata";
import {RelationMetadataArgs} from "../metadata/args/RelationMetadataArgs";
import {ColumnMetadataArgs} from "../metadata/args/ColumnMetadataArgs";
import {RelationsCountMetadataArgs} from "../metadata/args/RelationsCountMetadataArgs";
import {CompositeIndexMetadataArgs} from "../metadata/args/CompositeIndexMetadataArgs";
import {IndexMetadataArgs} from "../metadata/args/IndexMetadataArgs";
import {EntityListenerMetadataArgs} from "../metadata/args/EntityListenerMetadataArgs";
import {TableMetadataArgs} from "../metadata/args/TableMetadataArgs";
@ -39,25 +37,17 @@ export class MetadataArgsStorage {
// Properties
// -------------------------------------------------------------------------
readonly tableMetadatas = new TargetMetadataCollection<TableMetadataArgs>();
readonly namingStrategyMetadatas = new TargetMetadataCollection<NamingStrategyMetadataArgs>();
readonly eventSubscriberMetadatas = new TargetMetadataCollection<EventSubscriberMetadataArgs>();
readonly compositeIndexMetadatas = new TargetMetadataCollection<CompositeIndexMetadataArgs>();
readonly columnMetadatas = new PropertyMetadataCollection<ColumnMetadataArgs>();
readonly relationMetadatas = new PropertyMetadataCollection<RelationMetadataArgs>();
readonly joinColumnMetadatas = new PropertyMetadataCollection<JoinColumnMetadataArgs>();
readonly joinTableMetadatas = new PropertyMetadataCollection<JoinTableMetadataArgs>();
readonly indexMetadatas = new PropertyMetadataCollection<IndexMetadataArgs>();
readonly entityListenerMetadatas = new PropertyMetadataCollection<EntityListenerMetadataArgs>();
readonly relationCountMetadatas = new PropertyMetadataCollection<RelationsCountMetadataArgs>();
readonly tables = new TargetMetadataCollection<TableMetadataArgs>();
readonly namingStrategies = new TargetMetadataCollection<NamingStrategyMetadataArgs>();
readonly eventSubscribers = new TargetMetadataCollection<EventSubscriberMetadataArgs>();
readonly indices = new TargetMetadataCollection<IndexMetadataArgs>();
readonly columns = new PropertyMetadataCollection<ColumnMetadataArgs>();
readonly relations = new PropertyMetadataCollection<RelationMetadataArgs>();
readonly joinColumns = new PropertyMetadataCollection<JoinColumnMetadataArgs>();
readonly joinTables = new PropertyMetadataCollection<JoinTableMetadataArgs>();
readonly entityListeners = new PropertyMetadataCollection<EntityListenerMetadataArgs>();
readonly relationCounts = new PropertyMetadataCollection<RelationsCountMetadataArgs>();
// -------------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------------
constructor() {
}
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
@ -69,69 +59,67 @@ export class MetadataArgsStorage {
mergeWithAbstract(allTableMetadatas: TargetMetadataCollection<TableMetadataArgs>,
tableMetadata: TableMetadataArgs) {
const compositeIndexMetadatas = this.compositeIndexMetadatas.filterByClass(tableMetadata.target);
const columnMetadatas = this.columnMetadatas.filterByClass(tableMetadata.target);
const relationMetadatas = this.relationMetadatas.filterByClass(tableMetadata.target);
const joinColumnMetadatas = this.joinColumnMetadatas.filterByClass(tableMetadata.target);
const joinTableMetadatas = this.joinTableMetadatas.filterByClass(tableMetadata.target);
const indexMetadatas = this.indexMetadatas.filterByClass(tableMetadata.target);
const entityListenerMetadatas = this.entityListenerMetadatas.filterByClass(tableMetadata.target);
const relationCountMetadatas = this.relationCountMetadatas.filterByClass(tableMetadata.target);
const indices = this.indices.filterByClass(tableMetadata.target);
const columns = this.columns.filterByClass(tableMetadata.target);
const relations = this.relations.filterByClass(tableMetadata.target);
const joinColumns = this.joinColumns.filterByClass(tableMetadata.target);
const joinTables = this.joinTables.filterByClass(tableMetadata.target);
const entityListeners = this.entityListeners.filterByClass(tableMetadata.target);
const relationCounts = this.relationCounts.filterByClass(tableMetadata.target);
allTableMetadatas
.filter(metadata => this.isInherited(tableMetadata, metadata))
.forEach(parentMetadata => {
const metadatasFromAbstract = this.mergeWithAbstract(allTableMetadatas, parentMetadata);
metadatasFromAbstract.columnMetadatas
.filterRepeatedMetadatas(columnMetadatas)
.forEach(metadata => columnMetadatas.push(metadata));
metadatasFromAbstract.columns
.filterRepeatedMetadatas(columns)
.forEach(metadata => columns.push(metadata));
metadatasFromAbstract.relationMetadatas
.filterRepeatedMetadatas(relationMetadatas)
.forEach(metadata => relationMetadatas.push(metadata));
metadatasFromAbstract.relations
.filterRepeatedMetadatas(relations)
.forEach(metadata => relations.push(metadata));
metadatasFromAbstract.joinColumnMetadatas
.filterRepeatedMetadatas(joinColumnMetadatas)
.forEach(metadata => joinColumnMetadatas.push(metadata));
metadatasFromAbstract.joinColumns
.filterRepeatedMetadatas(joinColumns)
.forEach(metadata => joinColumns.push(metadata));
metadatasFromAbstract.joinTableMetadatas
.filterRepeatedMetadatas(joinTableMetadatas)
.forEach(metadata => joinTableMetadatas.push(metadata));
metadatasFromAbstract.joinTables
.filterRepeatedMetadatas(joinTables)
.forEach(metadata => joinTables.push(metadata));
metadatasFromAbstract.indexMetadatas
.filterRepeatedMetadatas(indexMetadatas)
.forEach(metadata => indexMetadatas.push(metadata));
metadatasFromAbstract.entityListeners
.filterRepeatedMetadatas(entityListeners)
.forEach(metadata => entityListeners.push(metadata));
metadatasFromAbstract.entityListenerMetadatas
.filterRepeatedMetadatas(entityListenerMetadatas)
.forEach(metadata => entityListenerMetadatas.push(metadata));
metadatasFromAbstract.relationCountMetadatas
.filterRepeatedMetadatas(relationCountMetadatas)
.forEach(metadata => relationCountMetadatas.push(metadata));
metadatasFromAbstract.relationCounts
.filterRepeatedMetadatas(relationCounts)
.forEach(metadata => relationCounts.push(metadata));
});
return {
compositeIndexMetadatas: compositeIndexMetadatas,
columnMetadatas: columnMetadatas,
relationMetadatas: relationMetadatas,
joinColumnMetadatas: joinColumnMetadatas,
joinTableMetadatas: joinTableMetadatas,
indexMetadatas: indexMetadatas,
entityListenerMetadatas: entityListenerMetadatas,
relationCountMetadatas: relationCountMetadatas
indices: indices,
columns: columns,
relations: relations,
joinColumns: joinColumns,
joinTables: joinTables,
entityListeners: entityListeners,
relationCounts: relationCounts
};
}
// -------------------------------------------------------------------------
// Private Methods
// -------------------------------------------------------------------------
/**
* Checks if this table is inherited from another table.
*/
private isInherited(firstTargetMetadata: TargetMetadataArgs, secondTargetMetadata: TargetMetadataArgs) {
return Object.getPrototypeOf(firstTargetMetadata.target.prototype).constructor === secondTargetMetadata.target;
// we cannot use instanceOf in this method, because we need order of inherited tables, to ensure that
// properties get inherited in a right order. To achieve it we can only check a first parent of the class
// return this.target.prototype instanceof anotherTable.target;
return Object.getPrototypeOf(firstTargetMetadata.target.prototype).constructor === secondTargetMetadata.target;
}

View File

@ -3,7 +3,11 @@ import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterfac
import {ColumnMetadataArgs} from "./args/ColumnMetadataArgs";
import {ColumnType} from "./types/ColumnTypes";
export type ColumnMode = "regular"|"createDate"|"updateDate"|"version"|"treeChildrenCount"|"treeLevel";
/**
* 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.
*/
export type ColumnMode = "regular"|"virtual"|"primary"|"createDate"|"updateDate"|"version"|"treeChildrenCount"|"treeLevel";
/**
* This metadata contains all information about class's column.
@ -43,11 +47,6 @@ export class ColumnMetadata extends PropertyMetadata {
*/
readonly length = "";
/**
* Indicates if this column is primary key.
*/
readonly isPrimary = false;
/**
* Indicates if this column is auto increment.
*/
@ -63,11 +62,6 @@ export class ColumnMetadata extends PropertyMetadata {
*/
readonly isNullable = false;
/**
* Indicates if column is virtual. Virtual columns are not mapped to the entity.
*/
readonly isVirtual = false;
/**
* Extra sql definition for the given column.
*/
@ -116,12 +110,8 @@ export class ColumnMetadata extends PropertyMetadata {
constructor(args: ColumnMetadataArgs) {
super(args.target, args.propertyName);
if (args.isPrimaryKey)
this.isPrimary = args.isPrimaryKey;
if (args.mode)
this.mode = args.mode;
if (args.isVirtual)
this.isVirtual = args.isVirtual;
if (args.propertyType)
this.propertyType = args.propertyType.toLowerCase();
if (args.options.name)
@ -164,17 +154,40 @@ export class ColumnMetadata extends PropertyMetadata {
return this.namingStrategy ? this.namingStrategy.columnName(this.propertyName) : this.propertyName;
}
/**
* Indicates if this column contains an entity update date.
*/
get isUpdateDate() {
return this.mode === "updateDate";
}
/**
* Indicates if this column contains an entity creation date.
*/
get isCreateDate() {
return this.mode === "createDate";
}
/**
* Indicates if this column contains an entity version.
*/
get isVersion() {
return this.mode === "version";
}
/**
* Indicates if this column is primary key.
*/
get isPrimary() {
return this.mode === "primary";
}
/**
* Indicates if column is virtual. Virtual columns are not mapped to the entity.
*/
get isVirtual() {
return this.mode === "virtual";
}
}

View File

@ -1,80 +0,0 @@
import {TargetMetadata} from "./TargetMetadata";
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
import {EntityMetadata} from "./EntityMetadata";
import {CompositeIndexMetadataArgs} from "./args/CompositeIndexMetadataArgs";
/**
* This metadata interface contains all information about table's composite index.
*/
export class CompositeIndexMetadata extends TargetMetadata {
// ---------------------------------------------------------------------
// Public Properties
// ---------------------------------------------------------------------
/**
* Naming strategy used to generate and normalize index name.
*/
namingStrategy: NamingStrategyInterface;
/**
* Entity metadata of the class to which this index is applied.
*/
entityMetadata: EntityMetadata;
// ---------------------------------------------------------------------
// Readonly Properties
// ---------------------------------------------------------------------
/**
* Indicates if this index must be unique.
*/
readonly isUnique: boolean;
// ---------------------------------------------------------------------
// Private Properties
// ---------------------------------------------------------------------
/**
* Composite index name.
*/
private readonly _name: string;
/**
* Columns combination to be used as index.
*/
private readonly _columns: ((object: any) => any[])|string[];
// ---------------------------------------------------------------------
// Constructor
// ---------------------------------------------------------------------
constructor(args: CompositeIndexMetadataArgs) {
super(args.target);
this._columns = args.columns;
if (args.name)
this._name = args.name;
if (args.options && args.options.unique)
this.isUnique = args.options.unique;
}
// ---------------------------------------------------------------------
// Accessors
// ---------------------------------------------------------------------
get name() { // throw exception if naming strategy is not set
return this.namingStrategy.indexName(this.target, this._name, this.columns);
}
get columns() {
// if columns already an array of string then simply return it
if (this._columns instanceof Array)
return this._columns;
// if columns is a function that returns array of field names then execute it and get columns names from it
const propertiesMap = this.entityMetadata.createPropertiesMap();
return this._columns(propertiesMap).map((i: any) => String(i));
}
}

View File

@ -1,11 +1,10 @@
import {TableMetadata} from "./TableMetadata";
import {ColumnMetadata} from "./ColumnMetadata";
import {RelationMetadata} from "./RelationMetadata";
import {CompositeIndexMetadata} from "./CompositeIndexMetadata";
import {IndexMetadata} from "./IndexMetadata";
import {RelationTypes} from "./types/RelationTypes";
import {ForeignKeyMetadata} from "./ForeignKeyMetadata";
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
import {PropertyMetadata} from "./PropertyMetadata";
/**
* Contains all entity metadata.
@ -30,7 +29,7 @@ export class EntityMetadata {
readonly table: TableMetadata;
readonly columns: ColumnMetadata[];
readonly relations: RelationMetadata[];
readonly compositeIndices: CompositeIndexMetadata[];
readonly compositeIndices: IndexMetadata[];
readonly foreignKeys: ForeignKeyMetadata[] = [];
// -------------------------------------------------------------------------
@ -41,7 +40,7 @@ export class EntityMetadata {
tableMetadata: TableMetadata,
columnMetadatas: ColumnMetadata[],
relationMetadatas: RelationMetadata[],
compositeIndexMetadatas: CompositeIndexMetadata[]) {
compositeIndexMetadatas: IndexMetadata[]) {
this.namingStrategy = namingStrategy;
this.table = tableMetadata;
this.columns = columnMetadatas;

View File

@ -1,12 +1,12 @@
import {PropertyMetadata} from "./PropertyMetadata";
import {TargetMetadata} from "./TargetMetadata";
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
import {EntityMetadata} from "./EntityMetadata";
import {IndexMetadataArgs} from "./args/IndexMetadataArgs";
/**
* This metadata interface contains all information about some index on a field.
* @deprecated
* Index metadata contains all information about table's index.
*/
export class IndexMetadata extends PropertyMetadata {
export class IndexMetadata extends TargetMetadata {
// ---------------------------------------------------------------------
// Public Properties
@ -17,24 +17,62 @@ export class IndexMetadata extends PropertyMetadata {
*/
namingStrategy: NamingStrategyInterface;
/**
* Entity metadata of the class to which this index is applied.
*/
entityMetadata: EntityMetadata;
// ---------------------------------------------------------------------
// Readonly Properties
// ---------------------------------------------------------------------
/**
* The name of the index.
* Indicates if this index must be unique.
*/
readonly name: string;
readonly isUnique: boolean;
// ---------------------------------------------------------------------
// Private Properties
// ---------------------------------------------------------------------
/**
* Composite index name.
*/
private readonly _name: string|undefined;
/**
* Columns combination to be used as index.
*/
private readonly _columns: ((object: any) => any[])|string[];
// ---------------------------------------------------------------------
// Constructor
// ---------------------------------------------------------------------
constructor(args: IndexMetadataArgs) {
super(args.target, args.propertyName);
if (args.name)
this.name = name; // todo: if there is no name, then generate it (using naming strategy?)
super(args.target);
this._columns = args.columns;
this._name = args.name;
this.isUnique = args.unique;
}
// ---------------------------------------------------------------------
// Accessors
// ---------------------------------------------------------------------
get name() { // throw exception if naming strategy is not set
return this.namingStrategy.indexName(this.target, this._name, this.columns);
}
get columns() {
// if columns already an array of string then simply return it
if (this._columns instanceof Array)
return this._columns;
// if columns is a function that returns array of field names then execute it and get columns names from it
const propertiesMap = this.entityMetadata.createPropertiesMap();
return this._columns(propertiesMap).map((i: any) => String(i));
}
}

View File

@ -1,6 +1,4 @@
import {PropertyMetadata} from "./PropertyMetadata";
import {JoinColumnOptions} from "./options/JoinColumnOptions";
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
import {RelationMetadata} from "./RelationMetadata";
import {ColumnMetadata} from "./ColumnMetadata";
import {JoinColumnMetadataArgs} from "./args/JoinColumnMetadataArgs";

View File

@ -2,47 +2,33 @@ import {ColumnOptions} from "../options/ColumnOptions";
import {ColumnMode} from "../ColumnMetadata";
/**
* Constructor arguments for ColumnMetadata class.
* Arguments for ColumnMetadata class.
*/
export interface ColumnMetadataArgs {
/**
* Class to which this column is applied.
* Class to which column is applied.
*/
target: Function;
readonly target: Function;
/**
* Class's property name to which this column is applied.
* Class's property name to which column is applied.
*/
propertyName: string;
readonly propertyName: string;
/**
* Class's property type (reflected) to which this column is applied.
* Class's property type (reflected) to which column is applied.
*/
propertyType: string;
readonly propertyType: string;
/**
* Indicates if this column is primary key or not.
* Column mode in which column will work.
*/
isPrimaryKey?: boolean;
/**
* Indicates if this column is virtual or not.
*/
isVirtual?: boolean;
/**
* Column mode.
*/
mode?: ColumnMode;
/**
* Indicates if this column is order id column.
*/
isOrderId?: boolean;
readonly mode: ColumnMode;
/**
* Extra column options.
*/
options: ColumnOptions;
readonly options: ColumnOptions;
}

View File

@ -1,19 +0,0 @@
import {CompositeIndexOptions} from "../options/CompositeIndexOptions";
import {TargetMetadataArgs} from "./TargetMetadataArgs";
/**
*/
export interface CompositeIndexMetadataArgs extends TargetMetadataArgs {
/**
* Class to which this column is applied.
*/
target: Function;
name?: string;
columns: ((object: any) => any[])|string[];
options?: CompositeIndexOptions;
}

View File

@ -1,22 +1,23 @@
import {EventListenerType} from "../types/EventListenerTypes";
/**
* Arguments for EntityListenerMetadata class.
*/
export interface EntityListenerMetadataArgs {
/**
* Class to which this column is applied.
* Class to which listener is applied.
*/
target: Function;
readonly target: Function;
/**
* Class's property name to which this column is applied.
* Class's property name to which listener is applied.
*/
propertyName: string;
readonly propertyName: string;
/**
* The type of the listener.
*/
type: EventListenerType;
readonly type: EventListenerType;
}

View File

@ -1,12 +1,12 @@
import {TargetMetadataArgs} from "./TargetMetadataArgs";
/**
* Arguments for EventSubscriberMetadata class.
*/
export interface EventSubscriberMetadataArgs extends TargetMetadataArgs {
export interface EventSubscriberMetadataArgs {
/**
* Class to which this subscriber is applied.
* Class to which subscriber is applied.
*/
target: Function;
readonly target: Function;
}

View File

@ -1,14 +1,27 @@
/**
* Arguments for IndexMetadata class.
*/
export interface IndexMetadataArgs {
/**
* Class to which this column is applied.
* Class to which index is applied.
*/
target: Function;
propertyName: string;
name?: string;
readonly target: Function;
/**
* Index name.
*/
readonly name?: string;
/**
* Columns combination to be used as index.
*/
readonly columns: ((object: any) => any[])|string[];
/**
* Indicates if index must be unique or not.
*/
readonly unique: boolean;
}

View File

@ -1,23 +1,23 @@
import {JoinColumnOptions} from "../options/JoinColumnOptions";
/**
* Constructor arguments for ColumnMetadata class.
* Arguments for JoinColumnMetadata class.
*/
export interface JoinColumnMetadataArgs {
/**
* Class to which this column is applied.
*/
target: Function;
readonly target: Function;
/**
* Class's property name to which this column is applied.
*/
propertyName: string;
readonly propertyName: string;
/**
* Class's property type (reflected) to which this column is applied.
* Class's property type (reflected) to which join column is applied.
*/
options: JoinColumnOptions;
readonly options: JoinColumnOptions;
}

View File

@ -1,23 +1,23 @@
import {JoinTableOptions} from "../options/JoinTableOptions";
/**
* Constructor arguments for ColumnMetadata class.
* Arguments for JoinTableMetadata class.
*/
export interface JoinTableMetadataArgs {
/**
* Class to which this column is applied.
*/
target: Function;
readonly target: Function;
/**
* Class's property name to which this column is applied.
*/
propertyName: string;
readonly propertyName: string;
/**
* Class's property type (reflected) to which this column is applied.
*/
options: JoinTableOptions;
readonly options: JoinTableOptions;
}

View File

@ -1,11 +1,18 @@
import {TargetMetadataArgs} from "./TargetMetadataArgs";
/**
* Arguments for NamingStrategyMetadata class.
*/
export interface NamingStrategyMetadataArgs extends TargetMetadataArgs {
export interface NamingStrategyMetadataArgs {
/**
* Class to which this column is applied.
*/
name: string;
readonly target: Function;
/**
* Strategy name.
*/
readonly name: string;
}

View File

@ -3,54 +3,54 @@ import {RelationOptions} from "../options/RelationOptions";
import {PropertyTypeInFunction, RelationTypeInFunction} from "../RelationMetadata";
/**
* Relation metadata constructor arguments.
* Arguments for RelationMetadata class.
*/
export interface RelationMetadataArgs {
/**
* Class to which this relation is applied.
*/
target: Function;
readonly target: Function;
/**
* Class's property name to which this relation is applied.
*/
propertyName: string;
readonly propertyName: string;
/**
* Original (reflected) class's property type.
*/
propertyType: any;
readonly propertyType: any;
/**
* Type of relation. Can be one of the value of the RelationTypes class.
*/
relationType: RelationType;
readonly relationType: RelationType;
/**
* Type of the relation. This type is in function because of language specifics and problems with recursive
* referenced classes.
*/
type: RelationTypeInFunction;
readonly type: RelationTypeInFunction;
/**
* Inverse side of the relation.
*/
inverseSideProperty?: PropertyTypeInFunction<any>;
readonly inverseSideProperty?: PropertyTypeInFunction<any>;
/**
* Additional relation options.
*/
options: RelationOptions;
readonly options: RelationOptions;
/**
* Indicates if this is a parent (can be only many-to-one relation) relation in the tree tables.
*/
isTreeParent?: boolean;
readonly isTreeParent?: boolean;
/**
* Indicates if this is a children (can be only one-to-many relation) relation in the tree tables.
*/
isTreeChildren?: boolean;
readonly isTreeChildren?: boolean;
}

View File

@ -1,20 +1,21 @@
import {ColumnOptions} from "../options/ColumnOptions";
import {ColumnMode} from "../ColumnMetadata";
/**
* Constructor arguments for ColumnMetadata class.
* Arguments for RelationsCountMetadata class.
*/
export interface RelationsCountMetadataArgs {
/**
* Class to which this column is applied.
*/
target: Function;
readonly target: Function;
/**
* Class's property name to which this column is applied.
*/
propertyName: string;
readonly propertyName: string;
/**
* Target's relation which it should count.
*/
readonly relation: string|((object: any) => any);
relation: string|((object: any) => any);
}

View File

@ -1,18 +1,23 @@
import {TableType} from "../TableMetadata";
/**
* Arguments for TableMetadata class.
*/
export interface TableMetadataArgs {
/**
* Class to which table is applied.
*/
target: Function;
readonly target: Function;
/**
* Table name.
*/
name?: string;
readonly name?: string;
/**
* Table type.
*/
type: TableType;
readonly type: TableType;
}

View File

@ -4,8 +4,8 @@
export interface TargetMetadataArgs {
/**
* Class to which this column is applied.
* Class to which this arguments is applied.
*/
target: Function;
readonly target: Function;
}

View File

@ -8,65 +8,71 @@ export interface ColumnOptions {
/**
* Column name.
*/
name?: string;
readonly name?: string;
/**
* Column type. Must be one of the value from the ColumnTypes class.
*/
type?: ColumnType;
readonly type?: ColumnType;
/**
* Column type's length. For example type = "string" and length = 100 means that ORM will create a column with
* type varchar(100).
*/
length?: string;
readonly length?: string;
/**
* Specifies if this column will use AUTO_INCREMENT or not (e.g. generated number).
*/
generated?: boolean;
readonly generated?: boolean;
/**
* Specifies if column's value must be unique or not.
*/
unique?: boolean;
readonly unique?: boolean;
/**
* Indicates if column's value can be set to NULL.
*/
nullable?: boolean;
readonly nullable?: boolean;
/**
* Extra column definition. Should be used only in emergency situations. Note that if you'll use this property
* auto schema generation will not work properly anymore.
*/
columnDefinition?: string;
readonly columnDefinition?: string;
/**
* Column comment.
*/
comment?: string;
readonly comment?: string;
/**
* Column name used previously for this column. Used to make safe schema updates. Experimental and most probably
* will be removed in the future. Avoid using it.
*/
oldColumnName?: string;
readonly oldColumnName?: string;
/**
* The precision for a decimal (exact numeric) column (applies only for decimal column), which is the maximum
* number of digits that are stored for the values.
*/
precision?: number;
readonly precision?: number;
/**
* The scale for a decimal (exact numeric) column (applies only for decimal column), which represents the number
* of digits to the right of the decimal point and must not be greater than precision.
*/
scale?: number;
readonly scale?: number;
/**
* Column collation. Note that not all databases support it.
*/
collation?: string;
readonly collation?: string; // todo: looks like this is not used
/**
* Indicates if this column is order id column.
*/
readonly isOrderId?: boolean; // todo: looks like this is not implemented yet
}

View File

@ -18,7 +18,7 @@ export class DefaultNamingStrategy implements NamingStrategyInterface {
return propertyName;
}
indexName(target: Function, name: string, columns: string[]): string {
indexName(target: Function, name: string|undefined, columns: string[]): string {
if (name)
return name;

View File

@ -22,7 +22,7 @@ export interface NamingStrategyInterface {
/**
* Gets the name of the index - simple and compose index.
*/
indexName(target: Function, name: string, columns: string[]): string;
indexName(target: Function, name: string|undefined, columns: string[]): string;
/**
* Gets the name of the join column used in the one-to-one and many-to-one relations.

View File

@ -3,7 +3,7 @@ import {MysqlDriver} from "../driver/MysqlDriver";
import {ColumnMetadata} from "../metadata/ColumnMetadata";
import {ForeignKeyMetadata} from "../metadata/ForeignKeyMetadata";
import {TableMetadata} from "../metadata/TableMetadata";
import {CompositeIndexMetadata} from "../metadata/CompositeIndexMetadata";
import {IndexMetadata} from "../metadata/IndexMetadata";
/**
* @internal
@ -118,7 +118,7 @@ export class MysqlSchemaBuilder extends SchemaBuilder {
return this.query(sql).then(() => {});
}
createIndex(tableName: string, index: CompositeIndexMetadata): Promise<void> {
createIndex(tableName: string, index: IndexMetadata): Promise<void> {
const sql = `CREATE ${index.isUnique ? "UNIQUE" : ""} INDEX \`${index.name}\` ON ${tableName}(${index.columns.join(", ")})`;
return this.query(sql).then(() => {});
}

View File

@ -1,7 +1,7 @@
import {ColumnMetadata} from "../metadata/ColumnMetadata";
import {ForeignKeyMetadata} from "../metadata/ForeignKeyMetadata";
import {TableMetadata} from "../metadata/TableMetadata";
import {CompositeIndexMetadata} from "../metadata/CompositeIndexMetadata";
import {IndexMetadata} from "../metadata/IndexMetadata";
/**
* todo: make internal too (need to refactor driver).
@ -20,7 +20,7 @@ export abstract class SchemaBuilder {
abstract getTableIndicesQuery(tableName: string): Promise<{ key: string, sequence: number, column: string }[]>;
abstract getPrimaryConstraintName(tableName: string): Promise<string>;
abstract dropIndex(tableName: string, indexName: string): Promise<void>;
abstract createIndex(tableName: string, index: CompositeIndexMetadata): Promise<void>;
abstract createIndex(tableName: string, index: IndexMetadata): Promise<void>;
abstract addUniqueKey(tableName: string, columnName: string, keyName: string): Promise<void>;
abstract getTableColumns(tableName: string): Promise<string[]>;
abstract changeColumnQuery(tableName: string, columnName: string, newColumn: ColumnMetadata, skipPrimary?: boolean): Promise<void>;

View File

@ -5,7 +5,6 @@ import {EntityMetadata} from "../metadata/EntityMetadata";
import {SchemaBuilder} from "../schema-builder/SchemaBuilder";
import {EntityMetadataCollection} from "../metadata/collection/EntityMetadataCollection";
import {IndexMetadata} from "../metadata/IndexMetadata";
import {CompositeIndexMetadata} from "../metadata/CompositeIndexMetadata";
/**
* Creates indexes based on the given metadata.
@ -214,7 +213,7 @@ export class SchemaCreator {
* Creates indices which are missing in db yet, and drops indices which exist in the db,
* but does not exist in the metadata anymore.
*/
private createIndices(table: TableMetadata, compositeIndices: CompositeIndexMetadata[]) {
private createIndices(table: TableMetadata, compositeIndices: IndexMetadata[]) {
return this.schemaBuilder.getTableIndicesQuery(table.name).then(tableIndices => {
// drop all indices that exist in the table, but does not exist in the given composite indices