Skip to content

Commit

Permalink
refactored column types - now databases support their own column type…
Browse files Browse the repository at this point in the history
…s individually
  • Loading branch information
Umed Khudoiberdiev committed Jun 15, 2017
1 parent 87c94ee commit f1c566f
Show file tree
Hide file tree
Showing 149 changed files with 2,319 additions and 1,022 deletions.
18 changes: 15 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,18 @@ Now naming strategy should be registered by passing naming strategy instance dir
More env variable names you can find in `ConnectionOptionsEnvReader` class.
* some api changes in `ConnectionManager` and `createConnection` / `createConnections` methods of typeorm main entrypoint
* `usePool` option has been removed from connection options. Now connections are working only with connection pooling
* `simple_array` column type now is called `simple-array`
* some column types were removed. Now orm uses directly column types of underlying database
* now `number` type in column definitions (like `@Column() likes: number`) maps to `integer` instead of `double` as before.
This is more programmatic design. If you need to store float-pointing values there define a type explicitly
* `fixedLength` in column options has been removed. Now actual column types can be used, e.g. `@Column("char")` or `@Column("varchar")`
* `timezone` option has been removed from column options. Now corresponding database types can be used instead
* `localTimezone` has been removed from the column options
* `skipSchemaSync` in entity options has been renamed to `skipSync`

### OTHER API CHANGES
### DEPRECATIONS

* moved `query`, `transaction` and `createQueryBuilder` to the `Connection`.
`EntityManager` now simply use them from the connection.
* `Embedded` decorator is deprecated now. use `@Column(type => SomeEmbedded)` instead now

### NEW FEATURES

Expand All @@ -53,6 +60,11 @@ More env variable names you can find in `ConnectionOptionsEnvReader` class.
* now relations for multiple primary keys are generated properly
* now ormconfig is read from `.env`, `.js`, `.json`, `.yml`, `.xml` formats

### OTHER API CHANGES

* moved `query`, `transaction` and `createQueryBuilder` to the `Connection`.
`EntityManager` now simply use them from the connection.

### BUG FIXES

* fixes [#285](https://github.com/typeorm/typeorm/issues/285) - issue when cli commands rise `CannotCloseNotConnectedError`
Expand Down
2 changes: 1 addition & 1 deletion sample/sample1-simple-entity/entity/Post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {Index} from "../../../src/decorator/Index";
@Entity("sample01_post")
export class Post {

@PrimaryColumn("int", { generated: true })
@PrimaryColumn("integer", { generated: true })
id: number;

@Column()
Expand Down
2 changes: 1 addition & 1 deletion sample/sample24-schemas/schemas/category.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"generated": true
},
"description": {
"type": "string",
"type": "varchar",
"nullable": false
}
},
Expand Down
4 changes: 2 additions & 2 deletions sample/sample24-schemas/schemas/image.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
"generated": true
},
"name": {
"type": "string",
"type": "varchar",
"nullable": false
},
"url": {
"type": "string",
"type": "varchar",
"nullable": false
}
},
Expand Down
4 changes: 2 additions & 2 deletions sample/sample24-schemas/schemas/post-details.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
"generated": true
},
"comment": {
"type": "string",
"type": "varchar",
"nullable": false
},
"metadata": {
"type": "string",
"type": "varchar",
"nullable": false
}
},
Expand Down
4 changes: 2 additions & 2 deletions sample/sample24-schemas/schemas/post.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
"generated": true
},
"title": {
"type": "string",
"type": "varchar",
"nullable": false
},
"text": {
"type": "string",
"type": "varchar",
"nullable": false
}
},
Expand Down
2 changes: 1 addition & 1 deletion sample/sample26-embedded-tables/entity/Post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class Post {
@Column()
text: string;

@Embedded(type => Counters)
@Column(type => Counters)
counters: Counters;

}
2 changes: 1 addition & 1 deletion sample/sample26-embedded-tables/entity/Question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class Question {
@Column()
title: string;

@Embedded(type => Counters)
@Column(type => Counters)
counters: Counters;

}
2 changes: 1 addition & 1 deletion sample/sample28-single-table-inheritance/entity/Person.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {PrimaryColumn} from "../../../src/decorator/columns/PrimaryColumn";

@Entity("sample28_person")
@TableInheritance("single-table")
@DiscriminatorColumn({ name: "type", type: "string"})
@DiscriminatorColumn({ name: "type", type: "varchar" })
export abstract class Person {

@PrimaryColumn("int")
Expand Down
2 changes: 1 addition & 1 deletion sample/sample29-class-table-inheritance/entity/Person.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {PrimaryColumn} from "../../../src/decorator/columns/PrimaryColumn";

@Entity("sample29_person")
@TableInheritance("class-table")
@DiscriminatorColumn({ name: "type", type: "string"})
@DiscriminatorColumn({ name: "type", type: "varchar" })
export abstract class Person {

@PrimaryColumn("int"/*, { generated: true }*/)
Expand Down
2 changes: 1 addition & 1 deletion src/connection/BaseConnectionOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {DriverOptions} from "../driver/DriverOptions";
import {EntitySchema} from "../entity-schema/EntitySchema";
import {LoggerOptions} from "../logger/LoggerOptions";
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
import {DatabaseType} from "../driver/DatabaseType";
import {DatabaseType} from "../driver/types/DatabaseType";

/**
* BaseConnectionOptions is set of connection options shared by all database types.
Expand Down
2 changes: 2 additions & 0 deletions src/decorator/Embedded.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {EmbeddedMetadataArgs} from "../metadata-args/EmbeddedMetadataArgs";
* embedded will be mapped to it from the single table.
*
* Array option works only in monogodb.
*
* @deprecated use @Column(type => EmbeddedModel) instead
*/
export function Embedded<T>(typeFunction: (type?: any) => ObjectType<T>, options?: { prefix?: string|boolean, array?: boolean }) {
return function (object: Object, propertyName: string) {
Expand Down
114 changes: 78 additions & 36 deletions src/decorator/columns/Column.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import {ColumnOptions} from "../options/ColumnOptions";
import {GeneratedOnlyForPrimaryError} from "../error/GeneratedOnlyForPrimaryError";
import {getMetadataArgsStorage} from "../../index";
import {ColumnType, ColumnTypes} from "../../metadata/types/ColumnTypes";
import {
ColumnType,
SimpleColumnType,
WithLengthColumnType,
WithPrecisionColumnType
} from "../../driver/types/ColumnTypes";
import {ColumnMetadataArgs} from "../../metadata-args/ColumnMetadataArgs";
import {ColumnCommonOptions} from "../options/ColumnCommonOptions";
import {ColumnWithLengthOptions} from "../options/ColumnWithLengthOptions";
import {ColumnNumericOptions} from "../options/ColumnNumericOptions";
import {ColumnEnumOptions} from "../options/ColumnEnumOptions";
import {ColumnEmbeddedOptions} from "../options/ColumnEmbeddedOptions";
import {EmbeddedMetadataArgs} from "../../metadata-args/EmbeddedMetadataArgs";

/**
* Column decorator is used to mark a specific class property as a table column. Only properties decorated with this
Expand All @@ -14,27 +25,49 @@ export function Column(): Function;
* 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(type: ColumnType): Function;
export function Column(options: ColumnOptions): Function;

/**
* 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: SimpleColumnType, options?: ColumnCommonOptions): Function;

/**
* 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(type: WithLengthColumnType, options?: ColumnCommonOptions & ColumnWithLengthOptions): Function;

/**
* 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(type: WithPrecisionColumnType, options?: ColumnCommonOptions & ColumnNumericOptions): Function;

/**
* 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(type: ColumnType, options: ColumnOptions): Function;
export function Column(type: "enum", options?: ColumnCommonOptions & ColumnEnumOptions): Function;

/**
* 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.
*
* Property in entity can be marked as Embedded, and on persist all columns from the embedded are mapped to the
* single table of the entity where Embedded is used. And on hydration all columns which supposed to be in the
* embedded will be mapped to it from the single table.
*/
export function Column(typeOrOptions?: ColumnType|ColumnOptions, options?: ColumnOptions): Function {
export function Column(type: (type?: any) => Function, options?: ColumnEmbeddedOptions): Function;

/**
* 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(typeOrOptions?: ((type?: any) => Function)|ColumnType|(ColumnOptions&ColumnEmbeddedOptions), options?: (ColumnOptions&ColumnEmbeddedOptions)): Function {
let type: ColumnType|undefined;
if (typeof typeOrOptions === "string") {
if (typeof typeOrOptions === "string" || typeOrOptions instanceof Function) {
type = <ColumnType> typeOrOptions;

} else if (typeOrOptions) {
Expand All @@ -43,39 +76,48 @@ export function Column(typeOrOptions?: ColumnType|ColumnOptions, options?: Colum
}
return function (object: Object, propertyName: string) {

// todo: need to store not string type, but original type instead? (like in relation metadata)
// const reflectedType = ColumnTypes.typeToString((Reflect as any).getMetadata("design:type", object, propertyName));
if (typeOrOptions instanceof Function) {

// if type is not given implicitly then try to guess it
if (!type) {
const reflectMetadataType = Reflect && (Reflect as any).getMetadata ? (Reflect as any).getMetadata("design:type", object, propertyName) : undefined;
if (reflectMetadataType)
type = ColumnTypes.determineTypeFromFunction(reflectMetadataType);
const isArray = reflectMetadataType === Array || (options && options.array === true) ? true : false;

const args: EmbeddedMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
isArray: isArray,
prefix: options && options.prefix !== undefined ? options.prefix : undefined,
type: typeOrOptions as (type?: any) => Function
};
getMetadataArgsStorage().embeddeds.push(args);

} else {
// if type is not given implicitly then try to guess it
if (!type) {
const reflectMetadataType = Reflect && (Reflect as any).getMetadata ? (Reflect as any).getMetadata("design:type", object, propertyName) : undefined;
if (reflectMetadataType)
type = reflectMetadataType; // todo: need to determine later on driver level
}

// if column options are not given then create a new empty options
if (!options) options = {} as ColumnOptions;

// check if there is no type in column options then set type from first function argument, or guessed one
if (!options.type && type)
options = Object.assign({ type: type } as ColumnOptions, options);

// check if auto increment is not set for simple column
if (options.generated)
throw new GeneratedOnlyForPrimaryError(object, propertyName);

// create and register a new column metadata
const args: ColumnMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
mode: "regular",
options: options
};
getMetadataArgsStorage().columns.push(args);
}

// if column options are not given then create a new empty options
if (!options) options = {} as ColumnOptions;

// check if there is no type in column options then set type from first function argument, or guessed one
if (!options.type && type)
options = Object.assign({ type: type } as ColumnOptions, options);

// if we still don't have a type then we need to give error to user that type is required
// if (!options.type)
// throw new ColumnTypeUndefinedError(object, propertyName);

// check if auto increment is not set for simple column
if (options.generated)
throw new GeneratedOnlyForPrimaryError(object, propertyName);

// create and register a new column metadata
const args: ColumnMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
// propertyType: reflectedType,
mode: "regular",
options: options
};
getMetadataArgsStorage().columns.push(args);
};
}
3 changes: 1 addition & 2 deletions src/decorator/columns/CreateDateColumn.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {ColumnOptions} from "../options/ColumnOptions";
import {ColumnTypes} from "../../metadata/types/ColumnTypes";
import {getMetadataArgsStorage} from "../../index";
import {ColumnMetadataArgs} from "../../metadata-args/ColumnMetadataArgs";

Expand All @@ -17,7 +16,7 @@ export function CreateDateColumn(options?: ColumnOptions): Function {
if (!options) options = {} as ColumnOptions;

// implicitly set a type, because this column's type cannot be anything else except date
options = Object.assign({ type: ColumnTypes.DATETIME } as ColumnOptions, options);
// options = Object.assign({ type: Date } as ColumnOptions, options);

// create and register a new column metadata
const args: ColumnMetadataArgs = {
Expand Down
2 changes: 1 addition & 1 deletion src/decorator/columns/DiscriminatorColumn.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ColumnOptions} from "../options/ColumnOptions";
import {ColumnType} from "../../metadata/types/ColumnTypes";
import {ColumnType} from "../../driver/types/ColumnTypes";
import {getMetadataArgsStorage} from "../../index";
import {ColumnMetadataArgs} from "../../metadata-args/ColumnMetadataArgs";

Expand Down
4 changes: 2 additions & 2 deletions src/decorator/columns/PrimaryColumn.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ColumnOptions} from "../options/ColumnOptions";
import {ColumnType, ColumnTypes} from "../../metadata/types/ColumnTypes";
import {ColumnType} from "../../driver/types/ColumnTypes";
import {ColumnTypeUndefinedError} from "../error/ColumnTypeUndefinedError";
import {getMetadataArgsStorage} from "../../index";
import {PrimaryColumnCannotBeNullableError} from "../error/PrimaryColumnCannotBeNullableError";
Expand Down Expand Up @@ -39,7 +39,7 @@ export function PrimaryColumn(typeOrOptions?: ColumnType|ColumnOptions, options?
if (!type) {
const reflectMetadataType = Reflect && (Reflect as any).getMetadata ? (Reflect as any).getMetadata("design:type", object, propertyName) : undefined;
if (reflectMetadataType)
type = ColumnTypes.determineTypeFromFunction(reflectMetadataType);
type = reflectMetadataType;
}

// if column options are not given then create a new empty options
Expand Down
3 changes: 1 addition & 2 deletions src/decorator/columns/UpdateDateColumn.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {ColumnOptions} from "../options/ColumnOptions";
import {ColumnTypes} from "../../metadata/types/ColumnTypes";
import {getMetadataArgsStorage} from "../../index";
import {ColumnMetadataArgs} from "../../metadata-args/ColumnMetadataArgs";

Expand All @@ -16,7 +15,7 @@ export function UpdateDateColumn(options?: ColumnOptions): Function {
if (!options) options = {} as ColumnOptions;

// implicitly set a type, because this column's type cannot be anything else except date
options = Object.assign({ type: ColumnTypes.DATETIME } as ColumnOptions, options);
// options = Object.assign({ type: Date } as ColumnOptions, options);

// create and register a new column metadata
const args: ColumnMetadataArgs = {
Expand Down
9 changes: 0 additions & 9 deletions src/decorator/columns/VersionColumn.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {ColumnOptions} from "../options/ColumnOptions";
import {ColumnTypes} from "../../metadata/types/ColumnTypes";
import {getMetadataArgsStorage} from "../../index";
import {ColumnMetadataArgs} from "../../metadata-args/ColumnMetadataArgs";

Expand All @@ -11,21 +10,13 @@ import {ColumnMetadataArgs} from "../../metadata-args/ColumnMetadataArgs";
export function VersionColumn(options?: ColumnOptions): Function {
return function (object: Object, propertyName: string) {

// const reflectedType = ColumnTypes.typeToString((Reflect as any).getMetadata("design:type", object, propertyName));

// if column options are not given then create a new empty options
if (!options) options = {} as ColumnOptions;

// implicitly set a type, because this column's type cannot be anything else except date
options = Object.assign({ type: ColumnTypes.INTEGER } as ColumnOptions, options);

// todo: check if reflectedType is number too

// create and register a new column metadata
const args: ColumnMetadataArgs = {
target: object.constructor,
propertyName: propertyName,
// propertyType: reflectedType,
mode: "version",
options: options
};
Expand Down
2 changes: 1 addition & 1 deletion src/decorator/entity/ClassEntityChild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function ClassEntityChild(tableName?: string, options?: EntityOptions) {
name: tableName,
type: "class-table-child",
orderBy: options && options.orderBy ? options.orderBy : undefined,
skipSchemaSync: !!(options && options.skipSchemaSync === true)
skipSync: !!(options && options.skipSync === true)
};
getMetadataArgsStorage().tables.push(args);
};
Expand Down
Loading

0 comments on commit f1c566f

Please sign in to comment.