refactored relation decorators

This commit is contained in:
Umed Khudoiberdiev 2016-03-19 11:55:37 +05:00
parent b32d8c49c4
commit 6aaf1f515c
14 changed files with 277 additions and 303 deletions

View File

@ -1,20 +1,21 @@
import "reflect-metadata";
import {ColumnOptions, ColumnTypeString, ColumnTypes} from "../../metadata-builder/options/ColumnOptions";
import {ColumnOptions} from "../../metadata-builder/options/ColumnOptions";
import {ColumnTypeUndefinedError} from "../error/ColumnTypeUndefinedError";
import {AutoIncrementOnlyForPrimaryError} from "../error/AutoIncrementOnlyForPrimaryError";
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
import {ColumnMetadata} from "../../metadata-builder/metadata/ColumnMetadata";
import {ColumnType, ColumnTypes} from "../../metadata-builder/types/ColumnTypes";
/**
* Column decorator is used to mark a specific class property as a table column. Only properties decorated with this
* decorator will be persisted to the database when entity be saved.
*/
export function Column(options?: ColumnOptions): Function;
export function Column(type?: ColumnTypeString, options?: ColumnOptions): Function;
export function Column(typeOrOptions?: ColumnTypeString|ColumnOptions, options?: ColumnOptions): Function {
let type: ColumnTypeString;
export function Column(type?: ColumnType, options?: ColumnOptions): Function;
export function Column(typeOrOptions?: ColumnType|ColumnOptions, options?: ColumnOptions): Function {
let type: ColumnType;
if (typeof typeOrOptions === "string") {
type = <ColumnTypeString> typeOrOptions;
type = <ColumnType> typeOrOptions;
} else {
options = <ColumnOptions> typeOrOptions;
}

View File

@ -1,4 +1,5 @@
import {ColumnOptions, ColumnTypeString, ColumnTypes} from "../../metadata-builder/options/ColumnOptions";
import {ColumnOptions} from "../../metadata-builder/options/ColumnOptions";
import {ColumnType, ColumnTypes} from "../../metadata-builder/types/ColumnTypes";
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
import {ColumnMetadata} from "../../metadata-builder/metadata/ColumnMetadata";
import "reflect-metadata";
@ -15,7 +16,7 @@ export function CreateDateColumn(options?: ColumnOptions): Function {
options = {};
// implicitly set a type, because this column's type cannot be anything else except date
options.type = <ColumnTypeString> ColumnTypes.DATETIME;
options.type = <ColumnType> ColumnTypes.DATETIME;
// create and register a new column metadata
defaultMetadataStorage.addColumnMetadata(new ColumnMetadata({

View File

@ -1,5 +1,6 @@
import "reflect-metadata";
import {ColumnOptions, ColumnTypeString, ColumnTypes} from "../../metadata-builder/options/ColumnOptions";
import {ColumnOptions} from "../../metadata-builder/options/ColumnOptions";
import {ColumnType, ColumnTypes} from "../../metadata-builder/types/ColumnTypes";
import {ColumnTypeUndefinedError} from "../error/ColumnTypeUndefinedError";
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
import {ColumnMetadata} from "../../metadata-builder/metadata/ColumnMetadata";
@ -11,11 +12,11 @@ import {PrimaryColumnCannotBeNullableError} from "../error/PrimaryColumnCannotBe
* this column in a db.
*/
export function PrimaryColumn(options?: ColumnOptions): Function;
export function PrimaryColumn(type?: ColumnTypeString, options?: ColumnOptions): Function;
export function PrimaryColumn(typeOrOptions?: ColumnTypeString|ColumnOptions, options?: ColumnOptions): Function {
let type: ColumnTypeString;
export function PrimaryColumn(type?: ColumnType, options?: ColumnOptions): Function;
export function PrimaryColumn(typeOrOptions?: ColumnType|ColumnOptions, options?: ColumnOptions): Function {
let type: ColumnType;
if (typeof typeOrOptions === "string") {
type = <ColumnTypeString> typeOrOptions;
type = <ColumnType> typeOrOptions;
} else {
options = <ColumnOptions> typeOrOptions;
}

View File

@ -1,4 +1,5 @@
import {ColumnOptions, ColumnTypeString, ColumnTypes} from "../../metadata-builder/options/ColumnOptions";
import {ColumnOptions} from "../../metadata-builder/options/ColumnOptions";
import {ColumnType, ColumnTypes} from "../../metadata-builder/types/ColumnTypes";
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
import {ColumnMetadata} from "../../metadata-builder/metadata/ColumnMetadata";
import "reflect-metadata";
@ -15,7 +16,7 @@ export function UpdateDateColumn(options?: ColumnOptions): Function {
options = {};
// implicitly set a type, because this column's type cannot be anything else except date
options.type = <ColumnTypeString> ColumnTypes.DATETIME;
options.type = <ColumnType> ColumnTypes.DATETIME;
// create and register a new column metadata
defaultMetadataStorage.addColumnMetadata(new ColumnMetadata({

View File

@ -1,34 +1,38 @@
import {RelationMetadata} from "../../metadata-builder/metadata/RelationMetadata";
import {RelationOptions} from "../../metadata-builder/options/RelationOptions";
import {
RelationTypeInFunction, PropertyTypeInFunction,
RelationMetadata
} from "../../metadata-builder/metadata/RelationMetadata";
import {RelationOptions} from "../../metadata-builder/options/RelationOptions";
import {RelationTypes} from "../../metadata-builder/types/RelationTypes";
RelationTypes
} from "../../metadata-builder/types/RelationTypes";
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
export function ManyToMany<T>(isOwning: boolean, typeFunction: RelationTypeInFunction, options?: RelationOptions): Function;
export function ManyToMany<T>(isOwning: boolean, typeFunction: RelationTypeInFunction, inverseSide?: PropertyTypeInFunction<T>, options?: RelationOptions): Function;
export function ManyToMany<T>(isOwning: boolean,
export function ManyToMany<T>(isOwner: boolean, typeFunction: RelationTypeInFunction, options?: RelationOptions): Function;
export function ManyToMany<T>(isOwner: boolean, typeFunction: RelationTypeInFunction, inverseSide?: PropertyTypeInFunction<T>, options?: RelationOptions): Function;
export function ManyToMany<T>(isOwner: boolean,
typeFunction: RelationTypeInFunction,
inverseSideOrOptions: PropertyTypeInFunction<T>|RelationOptions,
options?: RelationOptions): Function {
let inverseSide: PropertyTypeInFunction<T>;
let inverseSideProperty: PropertyTypeInFunction<T>;
if (typeof inverseSideOrOptions === "object") {
options = <RelationOptions> inverseSideOrOptions;
} else {
inverseSide = <PropertyTypeInFunction<T>> inverseSideOrOptions;
inverseSideProperty = <PropertyTypeInFunction<T>> inverseSideOrOptions;
}
return function (object: Object, propertyName: string) {
// todo: type in function validation, inverse side function validation
if (!options)
options = {};
const metadata = new RelationMetadata(
object.constructor, propertyName, RelationTypes.MANY_TO_MANY, typeFunction, inverseSide, isOwning, options
);
defaultMetadataStorage.addRelationMetadata(metadata);
defaultMetadataStorage.addRelationMetadata(new RelationMetadata({
target: object.constructor,
propertyName: propertyName,
relationType: RelationTypes.MANY_TO_MANY,
type: typeFunction,
inverseSideProperty: inverseSideProperty,
isOwning: isOwner,
options: options
}));
};
}

View File

@ -1,9 +1,9 @@
import {
RelationTypeInFunction, PropertyTypeInFunction,
RelationMetadata
} from "../../metadata-builder/metadata/RelationMetadata";
import {RelationMetadata} from "../../metadata-builder/metadata/RelationMetadata";
import {RelationOptions} from "../../metadata-builder/options/RelationOptions";
import {RelationTypes} from "../../metadata-builder/types/RelationTypes";
import {
PropertyTypeInFunction, RelationTypeInFunction,
RelationTypes
} from "../../metadata-builder/types/RelationTypes";
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
export function ManyToOne<T>(typeFunction: RelationTypeInFunction, options?: RelationOptions): Function;
@ -11,22 +11,26 @@ export function ManyToOne<T>(typeFunction: RelationTypeInFunction, inverseSide?:
export function ManyToOne<T>(typeFunction: RelationTypeInFunction,
inverseSideOrOptions: PropertyTypeInFunction<T>|RelationOptions,
options?: RelationOptions): Function {
let inverseSide: PropertyTypeInFunction<T>;
let inverseSideProperty: PropertyTypeInFunction<T>;
if (typeof inverseSideOrOptions === "object") {
options = <RelationOptions> inverseSideOrOptions;
} else {
inverseSide = <PropertyTypeInFunction<T>> inverseSideOrOptions;
inverseSideProperty = <PropertyTypeInFunction<T>> inverseSideOrOptions;
}
return function (object: Object, propertyName: string) {
// todo: type in function validation, inverse side function validation
if (!options)
options = {};
const metadata = new RelationMetadata(
object.constructor, propertyName, RelationTypes.MANY_TO_ONE, typeFunction, inverseSide, true, options
);
defaultMetadataStorage.addRelationMetadata(metadata);
defaultMetadataStorage.addRelationMetadata(new RelationMetadata({
target: object.constructor,
propertyName: propertyName,
relationType: RelationTypes.MANY_TO_ONE,
type: typeFunction,
inverseSideProperty: inverseSideProperty,
isOwning: true,
options: options
}));
};
}

View File

@ -1,9 +1,9 @@
import {
RelationTypeInFunction, PropertyTypeInFunction,
RelationMetadata
} from "../../metadata-builder/metadata/RelationMetadata";
import {RelationMetadata} from "../../metadata-builder/metadata/RelationMetadata";
import {RelationOptions} from "../../metadata-builder/options/RelationOptions";
import {RelationTypes} from "../../metadata-builder/types/RelationTypes";
import {
PropertyTypeInFunction, RelationTypeInFunction,
RelationTypes
} from "../../metadata-builder/types/RelationTypes";
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
export function OneToMany<T>(typeFunction: RelationTypeInFunction, options?: RelationOptions): Function;
@ -11,23 +11,27 @@ export function OneToMany<T>(typeFunction: RelationTypeInFunction, inverseSide?:
export function OneToMany<T>(typeFunction: RelationTypeInFunction,
inverseSideOrOptions: PropertyTypeInFunction<T>|RelationOptions,
options?: RelationOptions): Function {
let inverseSide: PropertyTypeInFunction<T>;
let inverseSideProperty: PropertyTypeInFunction<T>;
if (typeof inverseSideOrOptions === "object") {
options = <RelationOptions> inverseSideOrOptions;
} else {
inverseSide = <PropertyTypeInFunction<T>> inverseSideOrOptions;
inverseSideProperty = <PropertyTypeInFunction<T>> inverseSideOrOptions;
}
return function (object: Object, propertyName: string) {
// todo: type in function validation, inverse side function validation
if (!options)
options = {};
const metadata = new RelationMetadata(
object.constructor, propertyName, RelationTypes.ONE_TO_MANY, typeFunction, inverseSide, false, options
);
defaultMetadataStorage.addRelationMetadata(metadata);
defaultMetadataStorage.addRelationMetadata(new RelationMetadata({
target: object.constructor,
propertyName: propertyName,
relationType: RelationTypes.ONE_TO_MANY,
type: typeFunction,
inverseSideProperty: inverseSideProperty,
isOwning: false,
options: options
}));
};
}

View File

@ -1,9 +1,9 @@
import {
RelationTypeInFunction, PropertyTypeInFunction,
RelationMetadata
} from "../../metadata-builder/metadata/RelationMetadata";
import {RelationMetadata} from "../../metadata-builder/metadata/RelationMetadata";
import {RelationOptions} from "../../metadata-builder/options/RelationOptions";
import {RelationTypes} from "../../metadata-builder/types/RelationTypes";
import {
PropertyTypeInFunction, RelationTypeInFunction,
RelationTypes
} from "../../metadata-builder/types/RelationTypes";
import {defaultMetadataStorage} from "../../metadata-builder/MetadataStorage";
export function OneToOne<T>(isOwning: boolean, typeFunction: RelationTypeInFunction, options?: RelationOptions): Function;
@ -21,13 +21,17 @@ export function OneToOne<T>(isOwning: boolean,
return function (object: Object, propertyName: string) {
// todo: type in function validation, inverse side function validation
if (!options)
options = {};
const metadata = new RelationMetadata(
object.constructor, propertyName, RelationTypes.ONE_TO_ONE, typeFunction, inverseSideProperty, isOwning, options
);
defaultMetadataStorage.addRelationMetadata(metadata);
defaultMetadataStorage.addRelationMetadata(new RelationMetadata({
target: object.constructor,
propertyName: propertyName,
relationType: RelationTypes.ONE_TO_ONE,
type: typeFunction,
inverseSideProperty: inverseSideProperty,
isOwning: isOwning,
options: options
}));
};
}

View File

@ -13,6 +13,8 @@ import {ForeignKeyMetadata} from "./metadata/ForeignKeyMetadata";
*/
export class EntityMetadataBuilder {
// todo: type in function validation, inverse side function validation
// -------------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------------

View File

@ -1,6 +1,7 @@
import {PropertyMetadata} from "./PropertyMetadata";
import {ColumnOptions, ColumnTypeString} from "../options/ColumnOptions";
import {ColumnOptions} from "../options/ColumnOptions";
import {NamingStrategy} from "../../naming-strategy/NamingStrategy";
import {ColumnType} from "../types/ColumnTypes";
/**
* Constructor arguments for ColumnMetadata class.
@ -41,7 +42,7 @@ export class ColumnMetadata extends PropertyMetadata {
/**
* The type of the column.
*/
private _type: ColumnTypeString;
private _type: ColumnType;
/**
* Maximum length in the database.
@ -174,7 +175,7 @@ export class ColumnMetadata extends PropertyMetadata {
/**
* Type of the column.
*/
get type(): ColumnTypeString {
get type(): ColumnType {
return this._type;
}

View File

@ -1,19 +1,19 @@
import {PropertyMetadata} from "./PropertyMetadata";
import {RelationTypes} from "../types/RelationTypes";
import {RelationTypes, RelationType, RelationTypeInFunction, PropertyTypeInFunction} from "../types/RelationTypes";
import {RelationOptions} from "../options/RelationOptions";
import {NamingStrategy} from "../../naming-strategy/NamingStrategy";
import {TableMetadata} from "./TableMetadata";
import {EntityMetadata} from "./EntityMetadata";
/**
* Function that returns a type of the field. Returned value should be some class within which this relation is being created.
*/
export type RelationTypeInFunction = ((type?: any) => Function);
/**
* 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);
export interface RelationMetadataArgs {
target: Function;
propertyName: string;
relationType: RelationType;
type: RelationTypeInFunction;
inverseSideProperty: PropertyTypeInFunction<any>;
isOwning: boolean;
options: RelationOptions;
}
/**
* This metadata interface contains all information about some document's relation.
@ -39,7 +39,7 @@ export class RelationMetadata extends PropertyMetadata {
/**
* Relation type.
*/
private _relationType: RelationTypes;
private _relationType: RelationType;
/**
* The type of the field.
@ -95,34 +95,28 @@ export class RelationMetadata extends PropertyMetadata {
// Constructor
// ---------------------------------------------------------------------
constructor(target: Function,
propertyName: string,
relationType: RelationTypes,
type: RelationTypeInFunction,
inverseSideProperty: PropertyTypeInFunction<any>,
isOwning: boolean,
options: RelationOptions) {
super(target, propertyName);
this._relationType = relationType;
this._type = type;
this._isOwning = isOwning;
this._inverseSideProperty = inverseSideProperty;
constructor(args: RelationMetadataArgs) {
super(args.target, args.propertyName);
this._relationType = args.relationType;
this._type = args.type;
this._isOwning = args.isOwning;
this._inverseSideProperty = args.inverseSideProperty;
if (options.name)
this._name = options.name;
if (options.cascadeInsert)
this._isCascadeInsert = options.cascadeInsert;
if (options.cascadeUpdate)
this._isCascadeUpdate = options.cascadeUpdate;
if (options.cascadeRemove)
this._isCascadeRemove = options.cascadeRemove;
if (options.oldColumnName)
this._oldColumnName = options.oldColumnName;
if (options.nullable)
this._isNullable = options.nullable;
if (args.options.name)
this._name = args.options.name;
if (args.options.cascadeInsert)
this._isCascadeInsert = args.options.cascadeInsert;
if (args.options.cascadeUpdate)
this._isCascadeUpdate = args.options.cascadeUpdate;
if (args.options.cascadeRemove)
this._isCascadeRemove = args.options.cascadeRemove;
if (args.options.oldColumnName)
this._oldColumnName = args.options.oldColumnName;
if (args.options.nullable)
this._isNullable = args.options.nullable;
if (!this._name)
this._name = propertyName;
this._name = args.propertyName;
}
// ---------------------------------------------------------------------
@ -149,7 +143,7 @@ export class RelationMetadata extends PropertyMetadata {
this._junctionEntityMetadata = metadata;
}
get relationType(): RelationTypes {
get relationType(): RelationType {
return this._relationType;
}

View File

@ -1,3 +1,5 @@
import {ColumnType} from "../types/ColumnTypes";
/**
* Describes all column's options.
*/
@ -11,7 +13,7 @@ export interface ColumnOptions {
/**
* Column type. Must be one of the value from the ColumnTypes class.
*/
type?: ColumnTypeString;
type?: ColumnType;
/**
* Column type's length. For example type = "string" and length = 100 means that ORM will create a column with
@ -68,153 +70,3 @@ export interface ColumnOptions {
*/
collation?: string;
}
/**
* All types that column can be.
*/
export type ColumnTypeString = "string"|"text"|"number"|"integer"|"int"|"smallint"|"bigint"|"float"|"double"|
"decimal"|"date"|"time"|"datetime"|"boolean"|"json"|"simple_array";
/**
* All types that column can be.
*/
export class ColumnTypes {
/**
* SQL VARCHAR type. Your class's property type should be a "string".
*/
static STRING = "string";
/**
* SQL CLOB type. Your class's property type should be a "string".
*/
static TEXT = "text";
/**
* SQL FLOAT type. Your class's property type should be a "number".
*/
static NUMBER = "number";
/**
* SQL INT type. Your class's property type should be a "number".
*/
static INTEGER = "integer";
/**
* SQL INT type. Your class's property type should be a "number".
*/
static INT = "int";
/**
* SQL SMALLINT type. Your class's property type should be a "number".
*/
static SMALLINT = "smallint";
/**
* SQL BIGINT type. Your class's property type should be a "number".
*/
static BIGINT = "bigint";
/**
* SQL FLOAT type. Your class's property type should be a "number".
*/
static FLOAT = "float";
/**
* SQL FLOAT type. Your class's property type should be a "number".
*/
static DOUBLE = "double";
/**
* SQL DECIMAL type. Your class's property type should be a "string".
*/
static DECIMAL = "decimal";
/**
* SQL DATETIME type. Your class's property type should be a "Date" object.
*/
static DATE = "date";
/**
* SQL TIME type. Your class's property type should be a "Date" object.
*/
static TIME = "time";
/**
* SQL DATETIME/TIMESTAMP type. Your class's property type should be a "Date" object.
*/
static DATETIME = "datetime";
/**
* SQL BOOLEAN type. Your class's property type should be a "boolean".
*/
static BOOLEAN = "boolean";
/**
* SQL CLOB type. Your class's property type should be any Object.
*/
static JSON = "json";
/**
* SQL CLOB type. Your class's property type should be array of string. Note: value in this column should not contain
* a comma (",") since this symbol is used to create a string from the array, using .join(",") operator.
*/
static SIMPLE_ARRAY = "simple_array";
/**
* Checks if given type in a string format is supported by ORM.
*/
static isTypeSupported(type: string) {
return this.supportedTypes.indexOf(type) !== -1;
}
/**
* Returns list of all supported types by the ORM.
*/
static get supportedTypes() {
return [
this.STRING,
this.TEXT,
this.NUMBER,
this.INTEGER,
this.INT,
this.SMALLINT,
this.BIGINT,
this.FLOAT,
this.DOUBLE,
this.DECIMAL,
this.DATE,
this.TIME,
this.DATETIME,
this.BOOLEAN,
this.JSON,
this.SIMPLE_ARRAY
];
}
/**
* Tries to guess a column type from the given function.
*/
static determineTypeFromFunction(type: Function): ColumnTypeString {
if (type instanceof Date) {
return "datetime";
} else if (type instanceof Function) {
const typeName = (<any>type).name.toLowerCase();
switch (typeName) {
case "number":
return "number";
case "boolean":
return "boolean";
case "string":
return "string";
}
} else if (type instanceof Object) {
return "json";
}
return undefined;
}
}

View File

@ -1,58 +1,149 @@
/**
* Lists all types that can be a table column.
* All types that column can be.
*/
export type ColumnType = "string"|"text"|"number"|"integer"|"int"|"smallint"|"bigint"|"float"|"double"|
"decimal"|"date"|"time"|"datetime"|"boolean"|"json"|"simple_array";
/**
* All types that column can be.
*/
export class ColumnTypes {
static SMALLINT = "smallint";
static INTEGER = "integer";
static BIGINT = "bigint";
static DECIMAL = "decimal";
static FLOAT = "float";
static STRING = "string";
static TEXT = "text";
static BINARY = "binary";
static BLOB = "blob";
static BOOLEAN = "boolean";
static DATE = "date";
static DATETIME = "datetime";
static TIME = "time";
static ARRAY = "array";
static JSON = "json";
/**
* SQL VARCHAR type. Your class's property type should be a "string".
*/
static STRING: ColumnType = "string";
static isTypeSupported(type: string): boolean {
switch (type) {
case this.SMALLINT:
case this.INTEGER:
case this.BIGINT:
case this.DECIMAL:
case this.FLOAT:
case this.STRING:
case this.TEXT:
case this.BINARY:
case this.BLOB:
case this.BOOLEAN:
case this.DATE:
case this.DATETIME:
case this.TIME:
case this.ARRAY:
case this.JSON:
return true;
}
return false;
/**
* SQL CLOB type. Your class's property type should be a "string".
*/
static TEXT: ColumnType = "text";
/**
* SQL FLOAT type. Your class's property type should be a "number".
*/
static NUMBER: ColumnType = "number";
/**
* SQL INT type. Your class's property type should be a "number".
*/
static INTEGER: ColumnType = "integer";
/**
* SQL INT type. Your class's property type should be a "number".
*/
static INT: ColumnType = "int";
/**
* SQL SMALLINT type. Your class's property type should be a "number".
*/
static SMALLINT: ColumnType = "smallint";
/**
* SQL BIGINT type. Your class's property type should be a "number".
*/
static BIGINT: ColumnType = "bigint";
/**
* SQL FLOAT type. Your class's property type should be a "number".
*/
static FLOAT: ColumnType = "float";
/**
* SQL FLOAT type. Your class's property type should be a "number".
*/
static DOUBLE: ColumnType = "double";
/**
* SQL DECIMAL type. Your class's property type should be a "string".
*/
static DECIMAL: ColumnType = "decimal";
/**
* SQL DATETIME type. Your class's property type should be a "Date" object.
*/
static DATE: ColumnType = "date";
/**
* SQL TIME type. Your class's property type should be a "Date" object.
*/
static TIME: ColumnType = "time";
/**
* SQL DATETIME/TIMESTAMP type. Your class's property type should be a "Date" object.
*/
static DATETIME: ColumnType = "datetime";
/**
* SQL BOOLEAN type. Your class's property type should be a "boolean".
*/
static BOOLEAN: ColumnType = "boolean";
/**
* SQL CLOB type. Your class's property type should be any Object.
*/
static JSON: ColumnType = "json";
/**
* SQL CLOB type. Your class's property type should be array of string. Note: value in this column should not contain
* a comma (",") since this symbol is used to create a string from the array, using .join(",") operator.
*/
static SIMPLE_ARRAY: ColumnType = "simple_array";
/**
* Checks if given type in a string format is supported by ORM.
*/
static isTypeSupported(type: string) {
return this.supportedTypes.indexOf(<ColumnType> type) !== -1;
}
static validateTypeInFunction(typeFunction: () => Function): boolean {
if (!typeFunction || typeof typeFunction !== "function")
return false;
/**
* Returns list of all supported types by the ORM.
*/
static get supportedTypes() {
return [
this.STRING,
this.TEXT,
this.NUMBER,
this.INTEGER,
this.INT,
this.SMALLINT,
this.BIGINT,
this.FLOAT,
this.DOUBLE,
this.DECIMAL,
this.DATE,
this.TIME,
this.DATETIME,
this.BOOLEAN,
this.JSON,
this.SIMPLE_ARRAY
];
}
let type = typeFunction();
if (!type)
return false;
/**
* Tries to guess a column type from the given function.
*/
static determineTypeFromFunction(type: Function): ColumnType {
if (type instanceof Date) {
return ColumnTypes.DATETIME;
if (typeof type === "string" && !ColumnTypes.isTypeSupported(String(type)))
return false;
} else if (type instanceof Function) {
const typeName = (<any>type).name.toLowerCase();
switch (typeName) {
case "number":
return ColumnTypes.NUMBER;
case "boolean":
return ColumnTypes.BOOLEAN;
case "string":
return ColumnTypes.STRING;
}
return true;
} else if (type instanceof Object) {
return ColumnTypes.JSON;
}
return undefined;
}
}

View File

@ -1,7 +1,21 @@
/**
* All types that relation can be.
*/
export type RelationType = "one-to-one"|"one-to-many"|"many-to-one"|"many-to-many";
export enum RelationTypes {
ONE_TO_ONE = 1,
ONE_TO_MANY = 2,
MANY_TO_ONE = 3,
MANY_TO_MANY = 4
/**
* Function that returns a type of the field. Returned value should be some class within which this relation is being created.
*/
export type RelationTypeInFunction = ((type?: any) => Function);
/**
* 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);
export class RelationTypes {
static ONE_TO_ONE: RelationType = "one-to-one";
static ONE_TO_MANY: RelationType = "one-to-many";
static MANY_TO_ONE: RelationType = "many-to-one";
static MANY_TO_MANY: RelationType = "many-to-many";
}