mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
refactored column types - now databases support their own column types individually
This commit is contained in:
parent
87c94ee833
commit
f1c566f2ef
18
CHANGELOG.md
18
CHANGELOG.md
@ -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
|
||||
|
||||
@ -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`
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
"generated": true
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
}
|
||||
},
|
||||
|
||||
@ -10,11 +10,11 @@
|
||||
"generated": true
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
}
|
||||
},
|
||||
|
||||
@ -10,11 +10,11 @@
|
||||
"generated": true
|
||||
},
|
||||
"comment": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
},
|
||||
"metadata": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
}
|
||||
},
|
||||
|
||||
@ -10,11 +10,11 @@
|
||||
"generated": true
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
},
|
||||
"text": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
}
|
||||
},
|
||||
|
||||
@ -14,7 +14,7 @@ export class Post {
|
||||
@Column()
|
||||
text: string;
|
||||
|
||||
@Embedded(type => Counters)
|
||||
@Column(type => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -11,7 +11,7 @@ export class Question {
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Embedded(type => Counters)
|
||||
@Column(type => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -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")
|
||||
|
||||
@ -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 }*/)
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
@ -10,12 +21,6 @@ import {ColumnMetadataArgs} from "../../metadata-args/ColumnMetadataArgs";
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -26,15 +31,43 @@ 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(type: ColumnType, 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(typeOrOptions?: ColumnType|ColumnOptions, options?: ColumnOptions): Function {
|
||||
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: "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(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) {
|
||||
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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 = {
|
||||
|
||||
@ -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";
|
||||
|
||||
|
||||
@ -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";
|
||||
@ -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
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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 = {
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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
|
||||
};
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
@ -12,7 +12,7 @@ export function ClosureEntity(name?: string, options?: EntityOptions) {
|
||||
name: name,
|
||||
type: "closure",
|
||||
orderBy: options && options.orderBy ? options.orderBy : undefined,
|
||||
skipSchemaSync: !!(options && options.skipSchemaSync === true)
|
||||
skipSync: !!(options && options.skipSync === true)
|
||||
};
|
||||
getMetadataArgsStorage().tables.push(args);
|
||||
};
|
||||
|
||||
@ -14,7 +14,7 @@ export function Entity(name?: string, options?: EntityOptions) {
|
||||
type: "regular",
|
||||
orderBy: options && options.orderBy ? options.orderBy : undefined,
|
||||
engine: options && options.engine ? options.engine : undefined,
|
||||
skipSchemaSync: !!(options && options.skipSchemaSync === true)
|
||||
skipSync: !!(options && options.skipSync === true)
|
||||
};
|
||||
getMetadataArgsStorage().tables.push(args);
|
||||
};
|
||||
|
||||
37
src/decorator/options/ColumnCommonOptions.ts
Normal file
37
src/decorator/options/ColumnCommonOptions.ts
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Column options specific to all column types.
|
||||
*/
|
||||
export interface ColumnCommonOptions {
|
||||
|
||||
/**
|
||||
* Column name in the database.
|
||||
*/
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* Indicates if this column is a primary key.
|
||||
* Same can be achieved when @PrimaryColumn decorator is used.
|
||||
*/
|
||||
primary?: boolean;
|
||||
|
||||
/**
|
||||
* Specifies if column's value must be unique or not.
|
||||
*/
|
||||
unique?: boolean;
|
||||
|
||||
/**
|
||||
* Indicates if column's value can be set to NULL.
|
||||
*/
|
||||
nullable?: boolean;
|
||||
|
||||
/**
|
||||
* Default database value.
|
||||
*/
|
||||
default?: any;
|
||||
|
||||
/**
|
||||
* Column comment. Not supported by all database types.
|
||||
*/
|
||||
comment?: string;
|
||||
|
||||
}
|
||||
16
src/decorator/options/ColumnEmbeddedOptions.ts
Normal file
16
src/decorator/options/ColumnEmbeddedOptions.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Column options specific to all column types.
|
||||
*/
|
||||
export interface ColumnEmbeddedOptions {
|
||||
|
||||
/**
|
||||
* Embedded column prefix.
|
||||
*/
|
||||
prefix?: string;
|
||||
|
||||
/**
|
||||
* Indicates if this embedded column is an array.
|
||||
*/
|
||||
array?: boolean;
|
||||
|
||||
}
|
||||
11
src/decorator/options/ColumnEnumOptions.ts
Normal file
11
src/decorator/options/ColumnEnumOptions.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Column options for enum-typed columns.
|
||||
*/
|
||||
export interface ColumnEnumOptions {
|
||||
|
||||
/**
|
||||
* Array of possible enumerated values.
|
||||
*/
|
||||
enum?: any[];
|
||||
|
||||
}
|
||||
18
src/decorator/options/ColumnNumericOptions.ts
Normal file
18
src/decorator/options/ColumnNumericOptions.ts
Normal file
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Options for numeric column types where user can specify scale and precision.
|
||||
*/
|
||||
export interface ColumnNumericOptions {
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import {ColumnType} from "../../metadata/types/ColumnTypes";
|
||||
import {ColumnType} from "../../driver/types/ColumnTypes";
|
||||
|
||||
/**
|
||||
* Describes all column's options.
|
||||
@ -22,8 +22,8 @@ export interface ColumnOptions {
|
||||
length?: string|number;
|
||||
|
||||
/**
|
||||
* Indicates if this column is PRIMARY.
|
||||
* Same can be achieved if @PrimaryColumn decorator will be used.
|
||||
* Indicates if this column is a primary key.
|
||||
* Same can be achieved when @PrimaryColumn decorator is used.
|
||||
*/
|
||||
primary?: boolean;
|
||||
|
||||
@ -45,7 +45,7 @@ export interface ColumnOptions {
|
||||
nullable?: boolean;
|
||||
|
||||
/**
|
||||
* Column comment.
|
||||
* Column comment. Not supported by all database types.
|
||||
*/
|
||||
comment?: string;
|
||||
|
||||
@ -67,23 +67,8 @@ export interface ColumnOptions {
|
||||
scale?: number;
|
||||
|
||||
/**
|
||||
* Indicates if this date column will contain a timezone.
|
||||
* Used only for date-typed column types.
|
||||
* Note that timezone option is not supported by all databases (only postgres for now).
|
||||
* Array of possible enumerated values.
|
||||
*/
|
||||
timezone?: boolean;
|
||||
|
||||
/**
|
||||
* Indicates if date object must be stored in given date's timezone.
|
||||
* By default date is saved in UTC timezone.
|
||||
* Works only with "datetime" columns.
|
||||
*/
|
||||
localTimezone?: boolean;
|
||||
|
||||
/**
|
||||
* Indicates if column's type will be set as a fixed-length data type.
|
||||
* Works only with "string" columns.
|
||||
*/
|
||||
fixedLength?: boolean;
|
||||
enum?: any[];
|
||||
|
||||
}
|
||||
|
||||
12
src/decorator/options/ColumnWithLengthOptions.ts
Normal file
12
src/decorator/options/ColumnWithLengthOptions.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Options for columns that can define a length of the column type.
|
||||
*/
|
||||
export interface ColumnWithLengthOptions {
|
||||
|
||||
/**
|
||||
* Column type's length.
|
||||
* For example type = "varchar" and length = "100" means ORM will create a column with type varchar(100).
|
||||
*/
|
||||
length?: string|number;
|
||||
|
||||
}
|
||||
@ -21,6 +21,6 @@ export interface EntityOptions {
|
||||
/**
|
||||
* Specifies if this table will be skipped during schema synchronization.
|
||||
*/
|
||||
skipSchemaSync?: boolean;
|
||||
skipSync?: boolean;
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import {getMetadataArgsStorage} from "../../index";
|
||||
import {ColumnTypes} from "../../metadata/types/ColumnTypes";
|
||||
import {ColumnOptions} from "../options/ColumnOptions";
|
||||
import {ColumnMetadataArgs} from "../../metadata-args/ColumnMetadataArgs";
|
||||
|
||||
@ -9,18 +8,12 @@ import {ColumnMetadataArgs} from "../../metadata-args/ColumnMetadataArgs";
|
||||
export function TreeLevelColumn(): Function {
|
||||
return function (object: Object, propertyName: string) {
|
||||
|
||||
// const reflectedType = ColumnTypes.typeToString((Reflect as any).getMetadata("design:type", object, propertyName));
|
||||
|
||||
// implicitly set a type, because this column's type cannot be anything else except number
|
||||
const options: ColumnOptions = { type: ColumnTypes.INTEGER };
|
||||
|
||||
// create and register a new column metadata
|
||||
const args: ColumnMetadataArgs = {
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
// propertyType: reflectedType,
|
||||
mode: "treeLevel",
|
||||
options: options
|
||||
options: {}
|
||||
};
|
||||
getMetadataArgsStorage().columns.push(args);
|
||||
};
|
||||
|
||||
@ -1,12 +1,25 @@
|
||||
import {QueryRunner} from "../query-runner/QueryRunner";
|
||||
import {ColumnMetadata} from "../metadata/ColumnMetadata";
|
||||
import {ObjectLiteral} from "../common/ObjectLiteral";
|
||||
import {ColumnType} from "./types/ColumnTypes";
|
||||
import {MappedColumnTypes} from "./types/MappedColumnTypes";
|
||||
|
||||
/**
|
||||
* Driver organizes TypeORM communication with specific database management system.
|
||||
*/
|
||||
export interface Driver {
|
||||
|
||||
/**
|
||||
* Gets list of supported column data types by a driver.
|
||||
*/
|
||||
supportedDataTypes: ColumnType[];
|
||||
|
||||
/**
|
||||
* Orm has special columns and we need to know what database column types should be for those types.
|
||||
* Column types are driver dependant.
|
||||
*/
|
||||
mappedDataTypes: MappedColumnTypes;
|
||||
|
||||
/**
|
||||
* Performs connection to the database.
|
||||
* Depend on driver type it may create a connection pool.
|
||||
@ -59,15 +72,9 @@ export interface Driver {
|
||||
*/
|
||||
preparePersistentValue(value: any, column: ColumnMetadata): any;
|
||||
|
||||
/**
|
||||
* Prepares given value to a value to be persisted, based on its column metadata.
|
||||
*/
|
||||
prepareHydratedValue(value: any, type: ColumnMetadata): any;
|
||||
|
||||
/**
|
||||
* Prepares given value to a value to be persisted, based on its column type.
|
||||
*/
|
||||
prepareHydratedValue(value: any, column: ColumnMetadata): any;
|
||||
|
||||
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import {DatabaseType} from "./DatabaseType";
|
||||
import {DatabaseType} from "./types/DatabaseType";
|
||||
|
||||
/**
|
||||
* Connectivity options used to connect to the database, and other database-driver-specific options.
|
||||
|
||||
@ -11,6 +11,8 @@ import {DriverOptionNotSetError} from "../error/DriverOptionNotSetError";
|
||||
import {PlatformTools} from "../../platform/PlatformTools";
|
||||
import {Connection} from "../../connection/Connection";
|
||||
import {MongoConnectionOptions} from "./MongoConnectionOptions";
|
||||
import {MappedColumnTypes} from "../types/MappedColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
|
||||
/**
|
||||
* Organizes communication with MongoDB.
|
||||
@ -27,6 +29,27 @@ export class MongoDriver implements Driver {
|
||||
*/
|
||||
queryRunner: MongoQueryRunner;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Implemented Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Mongodb does not need to have column types because they are not used in schema sync.
|
||||
*/
|
||||
supportedDataTypes: ColumnType[] = [];
|
||||
|
||||
/**
|
||||
* Mongodb does not need to have a strong defined mapped column types because they are not used in schema sync.
|
||||
*/
|
||||
mappedDataTypes: MappedColumnTypes = {
|
||||
createDate: "int",
|
||||
updateDate: "int",
|
||||
version: "int",
|
||||
treeLevel: "int",
|
||||
migrationName: "int",
|
||||
migrationTimestamp: "int",
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -6,7 +6,7 @@ import {ColumnMetadata} from "../../metadata/ColumnMetadata";
|
||||
import {TableSchema} from "../../schema-builder/schema/TableSchema";
|
||||
import {ForeignKeySchema} from "../../schema-builder/schema/ForeignKeySchema";
|
||||
import {IndexSchema} from "../../schema-builder/schema/IndexSchema";
|
||||
import {ColumnType} from "../../metadata/types/ColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
import {
|
||||
AggregationCursor,
|
||||
BulkWriteOpResultObject,
|
||||
@ -648,7 +648,7 @@ export class MongoQueryRunner implements QueryRunner {
|
||||
/**
|
||||
* Creates a database type from a given column metadata.
|
||||
*/
|
||||
normalizeType(typeOptions: { type: ColumnType, length?: string|number, precision?: number, scale?: number, timezone?: boolean, fixedLength?: boolean }): string {
|
||||
normalizeType(column: ColumnMetadata): string {
|
||||
throw new Error(`Schema update queries are not supported by MongoDB driver.`);
|
||||
}
|
||||
|
||||
|
||||
214
src/driver/mysql/MysqlColumnTypes.ts
Normal file
214
src/driver/mysql/MysqlColumnTypes.ts
Normal file
@ -0,0 +1,214 @@
|
||||
// -------------------------------------------------------------------------
|
||||
// Numeric Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A very small integer that can be signed or unsigned.
|
||||
* If signed, the allowable range is from -128 to 127.
|
||||
* If unsigned, the allowable range is from 0 to 255.
|
||||
* You can specify a width of up to 4 digits.
|
||||
*/
|
||||
export type TinyintColumnType = "tinyint";
|
||||
|
||||
/**
|
||||
* A small integer that can be signed or unsigned.
|
||||
* If signed, the allowable range is from -32768 to 32767.
|
||||
* If unsigned, the allowable range is from 0 to 65535.
|
||||
* You can specify a width of up to 5 digits.
|
||||
*/
|
||||
export type SmallintColumnType = "smallint";
|
||||
|
||||
/**
|
||||
* A medium-sized integer that can be signed or unsigned.
|
||||
* If signed, the allowable range is from -8388608 to 8388607.
|
||||
* If unsigned, the allowable range is from 0 to 16777215.
|
||||
* You can specify a width of up to 9 digits.
|
||||
*/
|
||||
export type MediumintColumnType = "mediumint";
|
||||
|
||||
/**
|
||||
* A normal-sized integer that can be signed or unsigned.
|
||||
* If signed, the allowable range is from -2147483648 to 2147483647.
|
||||
* If unsigned, the allowable range is from 0 to 4294967295.
|
||||
* You can specify a width of up to 11 digits.
|
||||
*/
|
||||
export type IntegerColumnType = "int";
|
||||
|
||||
/**
|
||||
* A large integer that can be signed or unsigned.
|
||||
* If signed, the allowable range is from -9223372036854775808 to 9223372036854775807.
|
||||
* If unsigned, the allowable range is from 0 to 18446744073709551615.
|
||||
* You can specify a width of up to 20 digits.
|
||||
*/
|
||||
export type BigintColumnType = "bigint";
|
||||
|
||||
/**
|
||||
* A floating-point number that cannot be unsigned.
|
||||
* You can define the display length (M) and the number of decimals (D).
|
||||
* This is not required and will default to 10,2,
|
||||
* where 2 is the number of decimals and 10 is the total number of digits (including decimals).
|
||||
* Decimal precision can go to 24 places for a FLOAT.
|
||||
*/
|
||||
export type FloatColumnType = "float";
|
||||
|
||||
/**
|
||||
* A double precision floating-point number that cannot be unsigned.
|
||||
* You can define the display length (M) and the number of decimals (D).
|
||||
* This is not required and will default to 16,4, where 4 is the number of decimals.
|
||||
* Decimal precision can go to 53 places for a DOUBLE. REAL is a synonym for DOUBLE.
|
||||
*/
|
||||
export type DoubleColumnType = "real"|"double";
|
||||
|
||||
/**
|
||||
* An unpacked floating-point number that cannot be unsigned.
|
||||
* In unpacked decimals, each decimal corresponds to one byte.
|
||||
* Defining the display length (M) and the number of decimals (D) is required.
|
||||
* NUMERIC is a synonym for DECIMAL.
|
||||
*/
|
||||
export type DecimalColumnType = "numeric"|"decimal";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Character Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A variable-length string between 1 and 255 characters in length; for example VARCHAR(25).
|
||||
* You must define a length when creating a VARCHAR field.
|
||||
*/
|
||||
export type VarcharColumnType = "varchar";
|
||||
|
||||
/**
|
||||
* A fixed-length string between 1 and 255 characters in length (for example CHAR(5)),
|
||||
* right-padded with spaces to the specified length when stored.
|
||||
* Defining a length is not required, but the default is 1.
|
||||
*/
|
||||
export type CharColumnType = "char";
|
||||
|
||||
/**
|
||||
* A BLOB or TEXT column with a maximum length of 255 characters.
|
||||
* You do not specify a length with TINYBLOB or TINYTEXT.
|
||||
*/
|
||||
export type TinyTextColumnType = "tinyblob"|"tinytext";
|
||||
|
||||
/**
|
||||
* A BLOB or TEXT column with a maximum length of 16777215 characters.
|
||||
* You do not specify a length with MEDIUMBLOB or MEDIUMTEXT.
|
||||
*/
|
||||
export type MediumTextColumnType = "mediumblob"|"mediumtext";
|
||||
|
||||
/**
|
||||
* A field with a maximum length of 65535 characters.
|
||||
* BLOBs are "Binary Large Objects" and are used to store large amounts of binary data, such as images or other types of files.
|
||||
* Fields defined as TEXT also hold large amounts of data;
|
||||
* the difference between the two is that sorts and comparisons on stored data are case sensitive on BLOBs and are not case sensitive in TEXT fields.
|
||||
* You do not specify a length with BLOB or TEXT.
|
||||
*/
|
||||
export type TextColumnType = "blob"|"text";
|
||||
|
||||
/**
|
||||
* A BLOB or TEXT column with a maximum length of 4294967295 characters.
|
||||
* You do not specify a length with LONGBLOB or LONGTEXT.
|
||||
*/
|
||||
export type LongTextColumnType = "longblob"|"longtext";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Date/Time Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A date in YYYY-MM-DD format, between 1000-01-01 and 9999-12-31.
|
||||
* For example, December 30th, 1973 would be stored as 1973-12-30.
|
||||
*/
|
||||
export type DateColumnType = "date";
|
||||
|
||||
/**
|
||||
* A date and time combination in YYYY-MM-DD HH:MM:SS format,
|
||||
* between 1000-01-01 00:00:00 and 9999-12-31 23:59:59.
|
||||
* For example, 3:30 in the afternoon on December 30th, 1973 would be stored as 1973-12-30 15:30:00.
|
||||
*/
|
||||
export type DatetimeColumnType = "datetime";
|
||||
|
||||
/**
|
||||
* A timestamp between midnight, January 1, 1970 and sometime in 2037.
|
||||
* This looks like the previous DATETIME format, only without the hyphens between numbers;
|
||||
* 3:30 in the afternoon on December 30th, 1973 would be stored as 19731230153000 ( YYYYMMDDHHMMSS ).
|
||||
*/
|
||||
export type TimestampColumnType = "timestamp";
|
||||
|
||||
/**
|
||||
* Stores the time in HH:MM:SS format.
|
||||
*/
|
||||
export type TimeColumnType = "time";
|
||||
|
||||
/**
|
||||
* Stores a year in 2-digit or 4-digit format.
|
||||
* If the length is specified as 2 (for example YEAR(2)), YEAR can be 1970 to 2069 (70 to 69).
|
||||
* If the length is specified as 4, YEAR can be 1901 to 2155.
|
||||
* The default length is 4.
|
||||
*/
|
||||
export type YearColumnType = "year";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Enumerated Type
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* An enumeration, which is a fancy term for list.
|
||||
* When defining an ENUM, you are creating a list of items from which the value must be selected (or it can be NULL).
|
||||
* For example, if you wanted your field to contain "A" or "B" or "C",
|
||||
* you would define your ENUM as ENUM ('A', 'B', 'C') and only those values (or NULL) could ever populate that field.
|
||||
*/
|
||||
export type EnumColumnType = "enum";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Merged Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Column types where column length is used.
|
||||
*/
|
||||
export type WithLengthColumnType =
|
||||
VarcharColumnType|
|
||||
CharColumnType|
|
||||
YearColumnType;
|
||||
|
||||
/**
|
||||
* Column types where precision is used.
|
||||
*/
|
||||
export type NumericColumnType =
|
||||
FloatColumnType|
|
||||
DoubleColumnType|
|
||||
DecimalColumnType;
|
||||
|
||||
/**
|
||||
* Column types where time options are used.
|
||||
*/
|
||||
export type WithTimeColumnType =
|
||||
DatetimeColumnType|
|
||||
TimestampColumnType;
|
||||
|
||||
/**
|
||||
* All other column types without extra options used.
|
||||
*/
|
||||
export type SimpleColumnType =
|
||||
TinyintColumnType|
|
||||
SmallintColumnType|
|
||||
MediumintColumnType|
|
||||
IntegerColumnType|
|
||||
BigintColumnType|
|
||||
TinyTextColumnType|
|
||||
MediumTextColumnType|
|
||||
TextColumnType|
|
||||
LongTextColumnType|
|
||||
DateColumnType|
|
||||
TimeColumnType;
|
||||
|
||||
/**
|
||||
* All column types supported by a database.
|
||||
*/
|
||||
export type AllColumnType =
|
||||
SimpleColumnType|
|
||||
WithLengthColumnType|
|
||||
NumericColumnType|
|
||||
WithTimeColumnType|
|
||||
EnumColumnType;
|
||||
@ -5,7 +5,6 @@ import {DriverPackageNotInstalledError} from "../error/DriverPackageNotInstalled
|
||||
import {DriverUtils} from "../DriverUtils";
|
||||
import {QueryRunner} from "../../query-runner/QueryRunner";
|
||||
import {MysqlQueryRunner} from "./MysqlQueryRunner";
|
||||
import {ColumnTypes} from "../../metadata/types/ColumnTypes";
|
||||
import {ObjectLiteral} from "../../common/ObjectLiteral";
|
||||
import {ColumnMetadata} from "../../metadata/ColumnMetadata";
|
||||
import {DriverOptionNotSetError} from "../error/DriverOptionNotSetError";
|
||||
@ -14,12 +13,64 @@ import {PlatformTools} from "../../platform/PlatformTools";
|
||||
import {Connection} from "../../connection/Connection";
|
||||
import {SchemaBuilder} from "../../schema-builder/SchemaBuilder";
|
||||
import {MysqlConnectionOptions} from "./MysqlConnectionOptions";
|
||||
import {MappedColumnTypes} from "../types/MappedColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
|
||||
/**
|
||||
* Organizes communication with MySQL DBMS.
|
||||
*/
|
||||
export class MysqlDriver implements Driver {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Implemented Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets list of supported column data types by a driver.
|
||||
*
|
||||
* @see https://www.tutorialspoint.com/mysql/mysql-data-types.htm
|
||||
* @see https://dev.mysql.com/doc/refman/5.7/en/data-types.html
|
||||
*/
|
||||
supportedDataTypes: ColumnType[] = [
|
||||
"int",
|
||||
"tinyint",
|
||||
"smallint",
|
||||
"mediumint",
|
||||
"bigint",
|
||||
"float",
|
||||
"double",
|
||||
"decimal",
|
||||
"date",
|
||||
"datetime",
|
||||
"timestamp",
|
||||
"time",
|
||||
"year",
|
||||
"char",
|
||||
"varchar",
|
||||
"blob",
|
||||
"text",
|
||||
"tinyblob",
|
||||
"tinytext",
|
||||
"mediumblob",
|
||||
"mediumtext",
|
||||
"longblob",
|
||||
"longtext",
|
||||
"enum"
|
||||
];
|
||||
|
||||
/**
|
||||
* Orm has special columns and we need to know what database column types should be for those types.
|
||||
* Column types are driver dependant.
|
||||
*/
|
||||
mappedDataTypes: MappedColumnTypes = {
|
||||
createDate: "datetime",
|
||||
updateDate: "datetime",
|
||||
version: "int",
|
||||
treeLevel: "int",
|
||||
migrationName: "varchar",
|
||||
migrationTimestamp: "timestamp",
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Properties
|
||||
// -------------------------------------------------------------------------
|
||||
@ -176,30 +227,25 @@ export class MysqlDriver implements Driver {
|
||||
*/
|
||||
preparePersistentValue(value: any, columnMetadata: ColumnMetadata): any {
|
||||
if (value === null || value === undefined)
|
||||
return null;
|
||||
return value;
|
||||
|
||||
switch (columnMetadata.type) {
|
||||
case ColumnTypes.BOOLEAN:
|
||||
return value === true ? 1 : 0;
|
||||
if (columnMetadata.type === Boolean) {
|
||||
return value === true ? 1 : 0;
|
||||
|
||||
case ColumnTypes.DATE:
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
} else if (columnMetadata.type === "date") {
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
|
||||
case ColumnTypes.TIME:
|
||||
return DataUtils.mixedDateToTimeString(value);
|
||||
} else if (columnMetadata.type === "time") {
|
||||
return DataUtils.mixedDateToTimeString(value);
|
||||
|
||||
case ColumnTypes.DATETIME:
|
||||
if (columnMetadata.localTimezone) {
|
||||
return DataUtils.mixedDateToDatetimeString(value);
|
||||
} else {
|
||||
return DataUtils.mixedDateToUtcDatetimeString(value);
|
||||
}
|
||||
} else if (columnMetadata.type === "datetime") {
|
||||
return DataUtils.mixedDateToUtcDatetimeString(value);
|
||||
|
||||
case ColumnTypes.JSON:
|
||||
return JSON.stringify(value);
|
||||
} else if (columnMetadata.type === "json") {
|
||||
return JSON.stringify(value);
|
||||
|
||||
case ColumnTypes.SIMPLE_ARRAY:
|
||||
return DataUtils.simpleArrayToString(value);
|
||||
} else if (columnMetadata.type === "simple-array") {
|
||||
return DataUtils.simpleArrayToString(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
@ -209,24 +255,23 @@ export class MysqlDriver implements Driver {
|
||||
* Prepares given value to a value to be persisted, based on its column type or metadata.
|
||||
*/
|
||||
prepareHydratedValue(value: any, columnMetadata: ColumnMetadata): any {
|
||||
switch (columnMetadata.type) {
|
||||
case ColumnTypes.BOOLEAN:
|
||||
return value ? true : false;
|
||||
if (columnMetadata.type === Boolean) {
|
||||
return value ? true : false;
|
||||
|
||||
case ColumnTypes.DATETIME:
|
||||
return DataUtils.normalizeHydratedDate(value, columnMetadata.localTimezone === true);
|
||||
} else if (columnMetadata.type === "datetime") {
|
||||
return DataUtils.normalizeHydratedDate(value);
|
||||
|
||||
case ColumnTypes.DATE:
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
} else if (columnMetadata.type === "date") {
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
|
||||
case ColumnTypes.TIME:
|
||||
return DataUtils.mixedTimeToString(value);
|
||||
} else if (columnMetadata.type === "time") {
|
||||
return DataUtils.mixedTimeToString(value);
|
||||
|
||||
case ColumnTypes.JSON:
|
||||
return JSON.parse(value);
|
||||
} else if (columnMetadata.type === "json") {
|
||||
return JSON.parse(value);
|
||||
|
||||
case ColumnTypes.SIMPLE_ARRAY:
|
||||
return DataUtils.stringToSimpleArray(value);
|
||||
} else if (columnMetadata.type === "simple-array") {
|
||||
return DataUtils.stringToSimpleArray(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
@ -11,9 +11,10 @@ import {ForeignKeySchema} from "../../schema-builder/schema/ForeignKeySchema";
|
||||
import {PrimaryKeySchema} from "../../schema-builder/schema/PrimaryKeySchema";
|
||||
import {IndexSchema} from "../../schema-builder/schema/IndexSchema";
|
||||
import {QueryRunnerAlreadyReleasedError} from "../../query-runner/error/QueryRunnerAlreadyReleasedError";
|
||||
import {ColumnType} from "../../metadata/types/ColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
import {Connection} from "../../connection/Connection";
|
||||
import {MysqlConnectionOptions} from "./MysqlConnectionOptions";
|
||||
import {ColumnOptions} from "../../decorator/options/ColumnOptions";
|
||||
|
||||
/**
|
||||
* Runs queries on a single mysql database connection.
|
||||
@ -691,58 +692,66 @@ export class MysqlQueryRunner implements QueryRunner {
|
||||
/**
|
||||
* Creates a database type from a given column metadata.
|
||||
*/
|
||||
normalizeType(typeOptions: { type: ColumnType, length?: string|number, precision?: number, scale?: number, timezone?: boolean, fixedLength?: boolean }): string {
|
||||
normalizeType(column: ColumnMetadata): string {
|
||||
let type = "";
|
||||
if (column.type === Number) {
|
||||
type += "int";
|
||||
|
||||
switch (typeOptions.type) {
|
||||
case "string":
|
||||
if (typeOptions.fixedLength) {
|
||||
return "char(" + (typeOptions.length ? typeOptions.length : 255) + ")";
|
||||
} else {
|
||||
return "varchar(" + (typeOptions.length ? typeOptions.length : 255) + ")";
|
||||
}
|
||||
case "text":
|
||||
return "text";
|
||||
case "boolean":
|
||||
return "tinyint(1)";
|
||||
case "integer":
|
||||
case "int":
|
||||
return "int(" + (typeOptions.length ? typeOptions.length : 11) + ")";
|
||||
case "smallint":
|
||||
return "smallint(" + (typeOptions.length ? typeOptions.length : 11) + ")";
|
||||
case "bigint":
|
||||
return "bigint(" + (typeOptions.length ? typeOptions.length : 11) + ")";
|
||||
case "float":
|
||||
return "float";
|
||||
case "double":
|
||||
case "number":
|
||||
return "double";
|
||||
case "decimal":
|
||||
if (typeOptions.precision && typeOptions.scale) {
|
||||
return `decimal(${typeOptions.precision},${typeOptions.scale})`;
|
||||
} else if (column.type === String) {
|
||||
type += "varchar";
|
||||
|
||||
} else if (typeOptions.scale) {
|
||||
return `decimal(${typeOptions.scale})`;
|
||||
} else if (column.type === Date) {
|
||||
type += "datetime";
|
||||
|
||||
} else if (typeOptions.precision) {
|
||||
return `decimal(${typeOptions.precision})`;
|
||||
} else if (column.type === Boolean) {
|
||||
type += "tinyint(1)";
|
||||
|
||||
} else {
|
||||
return "decimal";
|
||||
} else if (column.type === Object) {
|
||||
type += "text";
|
||||
|
||||
}
|
||||
case "date":
|
||||
return "date";
|
||||
case "time":
|
||||
return "time";
|
||||
case "datetime":
|
||||
return "datetime";
|
||||
case "json":
|
||||
return "text";
|
||||
case "simple_array":
|
||||
return typeOptions.length ? "varchar(" + typeOptions.length + ")" : "text";
|
||||
} else if (column.type === "simple-array") {
|
||||
type += "text";
|
||||
|
||||
} else {
|
||||
type += column.type;
|
||||
}
|
||||
|
||||
throw new DataTypeNotSupportedByDriverError(typeOptions.type, "MySQL/MariaDB");
|
||||
if (column.length) {
|
||||
type += "(" + column.length + ")";
|
||||
|
||||
} else if (column.precision && column.scale) {
|
||||
type += "(" + column.precision + "," + column.scale + ")";
|
||||
|
||||
} else if (column.precision) {
|
||||
type += "(" + column.precision + ")";
|
||||
|
||||
} else if (column.scale) {
|
||||
type += "(" + column.scale + ")";
|
||||
}
|
||||
|
||||
// set default required length if those were not specified
|
||||
if (type === "varchar")
|
||||
type += "(255)";
|
||||
|
||||
if (type === "int")
|
||||
type += "(11)";
|
||||
|
||||
if (type === "tinyint")
|
||||
type += "(4)";
|
||||
|
||||
if (type === "smallint")
|
||||
type += "(5)";
|
||||
|
||||
if (type === "mediumint")
|
||||
type += "(9)";
|
||||
|
||||
if (type === "bigint")
|
||||
type += "(20)";
|
||||
|
||||
if (type === "year")
|
||||
type += "(4)";
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -4,7 +4,6 @@ import {DatabaseConnection} from "../DatabaseConnection";
|
||||
import {DriverPackageNotInstalledError} from "../error/DriverPackageNotInstalledError";
|
||||
import {QueryRunner} from "../../query-runner/QueryRunner";
|
||||
import {OracleQueryRunner} from "./OracleQueryRunner";
|
||||
import {ColumnTypes} from "../../metadata/types/ColumnTypes";
|
||||
import {ObjectLiteral} from "../../common/ObjectLiteral";
|
||||
import {ColumnMetadata} from "../../metadata/ColumnMetadata";
|
||||
import {DriverOptionNotSetError} from "../error/DriverOptionNotSetError";
|
||||
@ -13,6 +12,8 @@ import {PlatformTools} from "../../platform/PlatformTools";
|
||||
import {Connection} from "../../connection/Connection";
|
||||
import {SchemaBuilder} from "../../schema-builder/SchemaBuilder";
|
||||
import {OracleConnectionOptions} from "./OracleConnectionOptions";
|
||||
import {MappedColumnTypes} from "../types/MappedColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
|
||||
/**
|
||||
* Organizes communication with Oracle RDBMS.
|
||||
@ -21,6 +22,60 @@ import {OracleConnectionOptions} from "./OracleConnectionOptions";
|
||||
*/
|
||||
export class OracleDriver implements Driver {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Implemented Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets list of supported column data types by a driver.
|
||||
*
|
||||
* @see https://www.techonthenet.com/oracle/datatypes.php
|
||||
* @see https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT012
|
||||
*/
|
||||
supportedDataTypes: ColumnType[] = [
|
||||
"char",
|
||||
"nchar",
|
||||
"nvarchar2",
|
||||
"varchar2",
|
||||
"long",
|
||||
"raw",
|
||||
"long raw",
|
||||
"number",
|
||||
"numeric",
|
||||
"dec",
|
||||
"decimal",
|
||||
"integer",
|
||||
"int",
|
||||
"smallint",
|
||||
"real",
|
||||
"double precision",
|
||||
"date",
|
||||
"timestamp",
|
||||
"timestamp with time zone",
|
||||
"timestamp with local time zone",
|
||||
"interval year",
|
||||
"interval day",
|
||||
"bfile",
|
||||
"blob",
|
||||
"clob",
|
||||
"nclob",
|
||||
"rowid",
|
||||
"urowid"
|
||||
];
|
||||
|
||||
/**
|
||||
* Orm has special columns and we need to know what database column types should be for those types.
|
||||
* Column types are driver dependant.
|
||||
*/
|
||||
mappedDataTypes: MappedColumnTypes = {
|
||||
createDate: "datetime",
|
||||
updateDate: "datetime",
|
||||
version: "number",
|
||||
treeLevel: "number",
|
||||
migrationName: "varchar",
|
||||
migrationTimestamp: "timestamp",
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Properties
|
||||
// -------------------------------------------------------------------------
|
||||
@ -189,30 +244,25 @@ export class OracleDriver implements Driver {
|
||||
*/
|
||||
preparePersistentValue(value: any, columnMetadata: ColumnMetadata): any {
|
||||
if (value === null || value === undefined)
|
||||
return null;
|
||||
return value;
|
||||
|
||||
switch (columnMetadata.type) {
|
||||
case ColumnTypes.BOOLEAN:
|
||||
return value === true ? 1 : 0;
|
||||
if (columnMetadata.type === Boolean) {
|
||||
return value === true ? 1 : 0;
|
||||
|
||||
case ColumnTypes.DATE:
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
} else if (columnMetadata.type === "date") {
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
|
||||
case ColumnTypes.TIME:
|
||||
return DataUtils.mixedDateToTimeString(value);
|
||||
} else if (columnMetadata.type === "time") {
|
||||
return DataUtils.mixedDateToTimeString(value);
|
||||
|
||||
case ColumnTypes.DATETIME:
|
||||
if (columnMetadata.localTimezone) {
|
||||
return DataUtils.mixedDateToDatetimeString(value);
|
||||
} else {
|
||||
return DataUtils.mixedDateToUtcDatetimeString(value);
|
||||
}
|
||||
} else if (columnMetadata.type === "datetime") {
|
||||
return DataUtils.mixedDateToUtcDatetimeString(value);
|
||||
|
||||
case ColumnTypes.JSON:
|
||||
return JSON.stringify(value);
|
||||
} else if (columnMetadata.type === "json") {
|
||||
return JSON.stringify(value);
|
||||
|
||||
case ColumnTypes.SIMPLE_ARRAY:
|
||||
return DataUtils.simpleArrayToString(value);
|
||||
} else if (columnMetadata.type === "simple-array") {
|
||||
return DataUtils.simpleArrayToString(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
@ -222,24 +272,23 @@ export class OracleDriver implements Driver {
|
||||
* Prepares given value to a value to be persisted, based on its column type or metadata.
|
||||
*/
|
||||
prepareHydratedValue(value: any, columnMetadata: ColumnMetadata): any {
|
||||
switch (columnMetadata.type) {
|
||||
case ColumnTypes.BOOLEAN:
|
||||
return value ? true : false;
|
||||
if (columnMetadata.type === Boolean) {
|
||||
return value ? true : false;
|
||||
|
||||
case ColumnTypes.DATETIME:
|
||||
return DataUtils.normalizeHydratedDate(value, columnMetadata.localTimezone === true);
|
||||
} else if (columnMetadata.type === "datetime") {
|
||||
return DataUtils.normalizeHydratedDate(value);
|
||||
|
||||
case ColumnTypes.DATE:
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
} else if (columnMetadata.type === "date") {
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
|
||||
case ColumnTypes.TIME:
|
||||
return DataUtils.mixedTimeToString(value);
|
||||
} else if (columnMetadata.type === "time") {
|
||||
return DataUtils.mixedTimeToString(value);
|
||||
|
||||
case ColumnTypes.JSON:
|
||||
return JSON.parse(value);
|
||||
} else if (columnMetadata.type === "json") {
|
||||
return JSON.parse(value);
|
||||
|
||||
case ColumnTypes.SIMPLE_ARRAY:
|
||||
return DataUtils.stringToSimpleArray(value);
|
||||
} else if (columnMetadata.type === "simple-array") {
|
||||
return DataUtils.stringToSimpleArray(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
@ -11,9 +11,10 @@ import {ForeignKeySchema} from "../../schema-builder/schema/ForeignKeySchema";
|
||||
import {PrimaryKeySchema} from "../../schema-builder/schema/PrimaryKeySchema";
|
||||
import {IndexSchema} from "../../schema-builder/schema/IndexSchema";
|
||||
import {QueryRunnerAlreadyReleasedError} from "../../query-runner/error/QueryRunnerAlreadyReleasedError";
|
||||
import {ColumnType} from "../../metadata/types/ColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
import {Connection} from "../../connection/Connection";
|
||||
import {OracleConnectionOptions} from "./OracleConnectionOptions";
|
||||
import {ColumnOptions} from "../../decorator/options/ColumnOptions";
|
||||
|
||||
/**
|
||||
* Runs queries on a single mysql database connection.
|
||||
@ -749,72 +750,42 @@ AND cons.constraint_name = cols.constraint_name AND cons.owner = cols.owner ORDE
|
||||
/**
|
||||
* Creates a database type from a given column metadata.
|
||||
*/
|
||||
normalizeType(typeOptions: { type: ColumnType, length?: string|number, precision?: number, scale?: number, timezone?: boolean, fixedLength?: boolean }): string {
|
||||
switch (typeOptions.type) {
|
||||
case "string":
|
||||
if (typeOptions.fixedLength) {
|
||||
return "char(" + (typeOptions.length ? typeOptions.length : 255) + ")";
|
||||
} else {
|
||||
return "varchar2(" + (typeOptions.length ? typeOptions.length : 255) + ")";
|
||||
}
|
||||
case "text":
|
||||
return "clob";
|
||||
case "boolean":
|
||||
return "number(1)";
|
||||
case "integer":
|
||||
case "int":
|
||||
// if (column.isGenerated)
|
||||
// return `number(22)`;
|
||||
if (typeOptions.precision && typeOptions.scale)
|
||||
return `number(${typeOptions.precision},${typeOptions.scale})`;
|
||||
if (typeOptions.precision)
|
||||
return `number(${typeOptions.precision},0)`;
|
||||
if (typeOptions.scale)
|
||||
return `number(0,${typeOptions.scale})`;
|
||||
normalizeType(column: ColumnMetadata): string {
|
||||
let type = "";
|
||||
if (column.type === Number) {
|
||||
type += "integer";
|
||||
|
||||
return "number(10,0)";
|
||||
case "smallint":
|
||||
return "number(5)";
|
||||
case "bigint":
|
||||
return "number(20)";
|
||||
case "float":
|
||||
if (typeOptions.precision && typeOptions.scale)
|
||||
return `float(${typeOptions.precision},${typeOptions.scale})`;
|
||||
if (typeOptions.precision)
|
||||
return `float(${typeOptions.precision},0)`;
|
||||
if (typeOptions.scale)
|
||||
return `float(0,${typeOptions.scale})`;
|
||||
} else if (column.type === String) {
|
||||
type += "nvarchar2";
|
||||
|
||||
return `float(126)`;
|
||||
case "double":
|
||||
case "number":
|
||||
return "float(126)";
|
||||
case "decimal":
|
||||
if (typeOptions.precision && typeOptions.scale) {
|
||||
return `decimal(${typeOptions.precision},${typeOptions.scale})`;
|
||||
} else if (column.type === Date) {
|
||||
type += "timestamp(0)";
|
||||
|
||||
} else if (typeOptions.scale) {
|
||||
return `decimal(0,${typeOptions.scale})`;
|
||||
} else if (column.type === Boolean) {
|
||||
type += "number(1)";
|
||||
|
||||
} else if (typeOptions.precision) {
|
||||
return `decimal(${typeOptions.precision})`;
|
||||
} else if (column.type === Object) {
|
||||
type += "text";
|
||||
|
||||
} else {
|
||||
return "decimal";
|
||||
}
|
||||
case "date":
|
||||
return "date";
|
||||
case "time":
|
||||
return "date";
|
||||
case "datetime":
|
||||
return "timestamp(0)";
|
||||
case "json":
|
||||
return "clob";
|
||||
case "simple_array":
|
||||
return typeOptions.length ? "varchar2(" + typeOptions.length + ")" : "text";
|
||||
} else if (column.type === "simple-array") {
|
||||
type += "text";
|
||||
|
||||
} else {
|
||||
type += column.type;
|
||||
}
|
||||
if (column.length) {
|
||||
type += "(" + column.length + ")";
|
||||
|
||||
throw new DataTypeNotSupportedByDriverError(typeOptions.type, "Oracle");
|
||||
} else if (column.precision && column.scale) {
|
||||
type += "(" + column.precision + "," + column.scale + ")";
|
||||
|
||||
} else if (column.precision) {
|
||||
type += "(" + column.precision + ")";
|
||||
|
||||
} else if (column.scale) {
|
||||
type += "(" + column.scale + ")";
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
379
src/driver/postgres/PostgresColumnTypes.ts
Normal file
379
src/driver/postgres/PostgresColumnTypes.ts
Normal file
@ -0,0 +1,379 @@
|
||||
// -------------------------------------------------------------------------
|
||||
// Numeric Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Numeric type.
|
||||
* Small-range integer type.
|
||||
* Size: 2 bytes.
|
||||
* Range: -32768 to +32767.
|
||||
*/
|
||||
export type SmallintColumnType = "smallint"|"int2";
|
||||
|
||||
/**
|
||||
* Integer type.
|
||||
* Size: 4 bytes.
|
||||
* Range: -2147483648 to +2147483647.
|
||||
*/
|
||||
export type IntegerColumnType = "integer"|"int"|"int4";
|
||||
|
||||
/**
|
||||
* Numeric type.
|
||||
* Large-range integer type.
|
||||
* Size: 8 bytes.
|
||||
* Range: -9223372036854775808 to 9223372036854775807.
|
||||
*/
|
||||
export type BigintColumnType = "bigint"|"int8";
|
||||
|
||||
/**
|
||||
* Numeric type.
|
||||
* User-specified precision, exact.
|
||||
* Size: variable.
|
||||
* Range: up to 131072 digits before the decimal point; up to 16383 digits after the decimal point.
|
||||
*/
|
||||
export type DecimalColumnType = "decimal";
|
||||
|
||||
/**
|
||||
* Numeric type.
|
||||
* User-specified precision, exact.
|
||||
* Size: variable.
|
||||
* Range: up to 131072 digits before the decimal point; up to 16383 digits after the decimal point.
|
||||
*/
|
||||
export type NumericColumnType = "numeric"|"decimal";
|
||||
|
||||
/**
|
||||
* Numeric type.
|
||||
* Variable-precision, inexact.
|
||||
* Size: 4 bytes.
|
||||
* Range: 6 decimal digits precision.
|
||||
*/
|
||||
export type RealColumnType = "real"|"float4";
|
||||
|
||||
/**
|
||||
* Numeric type.
|
||||
* Variable-precision, inexact.
|
||||
* Size: 8 bytes.
|
||||
* Range: 15 decimal digits precision.
|
||||
*/
|
||||
export type DoublePrecisionColumnType = "double precision"|"float8";
|
||||
|
||||
/**
|
||||
* Numeric type.
|
||||
* Small autoincrementing integer.
|
||||
* Size: 2 bytes.
|
||||
* Range: 1 to 32767.
|
||||
*/
|
||||
export type SmallserialColumnType = "smallserial"|"serial2";
|
||||
|
||||
/**
|
||||
* Numeric type.
|
||||
* Autoincrementing integer.
|
||||
* Size: 4 bytes.
|
||||
* Range: 1 to 2147483647.
|
||||
*/
|
||||
export type SerialColumnType = "serial"|"serial4";
|
||||
|
||||
/**
|
||||
* Numeric type.
|
||||
* Large autoincrementing integer.
|
||||
* Size: 8 bytes.
|
||||
* Range: -92233720368547758.08 to +92233720368547758.07
|
||||
*/
|
||||
export type BigserialColumnType = "bigserial"|"serial8";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Monetary Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Monetary type.
|
||||
* Currency amount.
|
||||
* Size: 8 bytes.
|
||||
* Range: 1 to 9223372036854775807.
|
||||
*/
|
||||
export type MoneyColumnType = "money";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Character Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Character type.
|
||||
* Variable-length with limit type.
|
||||
*/
|
||||
export type VarcharColumnType = "character varying"|"varchar";
|
||||
|
||||
/**
|
||||
* Character type.
|
||||
* Fixed-length, blank padded type.
|
||||
*/
|
||||
export type CharColumnType = "character"|"char";
|
||||
|
||||
/**
|
||||
* Character type.
|
||||
* Variable-length character string.
|
||||
*/
|
||||
export type TextColumnType = "text";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Binary Data Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Variable-length binary string type.
|
||||
* Size: 1 or 4 bytes plus the actual binary string.
|
||||
*/
|
||||
export type ByteaColumnType = "bytea";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Date/Time Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Both date and time type.
|
||||
* With or without timezone.
|
||||
* Size: 8 bytes.
|
||||
* Value range: from 4713 BC to 294276 AD.
|
||||
*/
|
||||
export type TimestampColumnType = "timestamp";
|
||||
|
||||
/**
|
||||
* Date (no time of day) type.
|
||||
* With or without timezone.
|
||||
* Size: 4 bytes.
|
||||
* Value range: from 4713 BC to 5874897 AD.
|
||||
*
|
||||
* This column type has additional options.
|
||||
*/
|
||||
export type DateColumnType = "date";
|
||||
|
||||
/**
|
||||
* Time of day (no date) type.
|
||||
* With or without timezone.
|
||||
* Size: 8 bytes or 12 bytes (depend on timezone).
|
||||
* Value range: from 00:00:00+1459 BC to 24:00:00-1459.
|
||||
*
|
||||
* This column type has additional options.
|
||||
*/
|
||||
export type TimeColumnType = "time";
|
||||
|
||||
/**
|
||||
* Time interval type.
|
||||
* Size: 12 bytes.
|
||||
* Value range: from -178000000 years to 178000000 years.
|
||||
*/
|
||||
export type IntervalColumnType = "interval";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Boolean Type
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Boolean type.
|
||||
* Size: 1 byte.
|
||||
*/
|
||||
export type BooleanColumnType = "boolean"|"bool";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Enumerated Type
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Enumerated type.
|
||||
* Enumerated (enum) types are data types that comprise a static, ordered set of values.
|
||||
* This column type has additional options.
|
||||
*/
|
||||
export type EnumColumnType = "enum";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Geometric Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Geometric type - point.
|
||||
* Stores values in a (x,y) format.
|
||||
* Size: 16 bytes.
|
||||
*/
|
||||
export type PointColumnType = "point";
|
||||
|
||||
/**
|
||||
* Geometric type - infinite line.
|
||||
* Stores values in a ((x1,y1),(x2,y2)) format.
|
||||
* Size: 32 bytes.
|
||||
*/
|
||||
export type LineColumnType = "line";
|
||||
|
||||
/**
|
||||
* Geometric type - finite line segment.
|
||||
* Stores values in a ((x1,y1),(x2,y2)) format.
|
||||
* Size: 32 bytes.
|
||||
*/
|
||||
export type LsegColumnType = "lseg";
|
||||
|
||||
/**
|
||||
* Geometric type - rectangular box.
|
||||
* Stores values in a ((x1,y1),(x2,y2)) format.
|
||||
* Size: 32 bytes.
|
||||
*/
|
||||
export type BoxColumnType = "box";
|
||||
|
||||
/**
|
||||
* Geometric type - circle.
|
||||
* Stores values in a <(x,y),r> format.
|
||||
* Size: 24 bytes.
|
||||
*/
|
||||
export type CircleColumnType = "circle";
|
||||
|
||||
/**
|
||||
* Geometric type - path.
|
||||
* Size: 40+16n bytes.
|
||||
*/
|
||||
export type PathColumnType = "path";
|
||||
|
||||
/**
|
||||
* Geometric type - path (similar to polygon).
|
||||
*/
|
||||
export type PolygonColumnType = "polygon";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Network Address Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* IPv4 and IPv6 networks.
|
||||
* Size: 7 or 19 bytes.
|
||||
*/
|
||||
export type CidrColumnType = "cidr";
|
||||
|
||||
/**
|
||||
* IPv4 and IPv6 hosts and networks type.
|
||||
* Size: 7 or 19 bytes.
|
||||
*/
|
||||
export type InetColumnType = "inet";
|
||||
|
||||
/**
|
||||
* MAC addresses type.
|
||||
* Size: 6 bytes.
|
||||
*/
|
||||
export type MacaddrColumnType = "macaddr";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Bit String Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Bit types are used to store bit masks with fixed length.
|
||||
*/
|
||||
export type BitColumnType = "bit";
|
||||
|
||||
/**
|
||||
* Bit type are used to store bit masks with variable length.
|
||||
*/
|
||||
export type VarbitColumnType = "bit varying"|"varbit";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Text Search Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* This is a sorted list of distinct words that have been normalized
|
||||
* to merge different variants of the same word, called as "lexemes".
|
||||
*/
|
||||
export type TsvectorColumnType = "tsvector";
|
||||
|
||||
/**
|
||||
* This stores lexemes that are to be searched for,
|
||||
* and combines them honoring the Boolean operators & (AND), | (OR), and ! (NOT).
|
||||
* Parentheses can be used to enforce grouping of the operators.
|
||||
*/
|
||||
export type TsqueryColumnType = "tsquery";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Other Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Universally Unique Identifier type.
|
||||
*/
|
||||
export type UUIDColumnType = "UUID";
|
||||
|
||||
/**
|
||||
* The xml data type can be used to store XML data.
|
||||
*/
|
||||
export type XmlColumnType = "xml";
|
||||
|
||||
/**
|
||||
* The json data type can be used to store JSON (JavaScript Object Notation) data.
|
||||
*/
|
||||
export type JsonColumnType = "json";
|
||||
|
||||
/**
|
||||
* The jsonb data type can be used to store JSON (JavaScript Object Notation) in a binary format.
|
||||
*/
|
||||
export type JsonbColumnType = "jsonb";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Merged Types
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Column types where column length is used.
|
||||
*/
|
||||
export type WithLengthColumnType =
|
||||
VarcharColumnType|
|
||||
CharColumnType|
|
||||
IntervalColumnType|
|
||||
BitColumnType|
|
||||
VarbitColumnType;
|
||||
|
||||
/**
|
||||
* Column types where time options are used.
|
||||
*/
|
||||
export type WithTimeColumnType =
|
||||
TimeColumnType|
|
||||
TimestampColumnType;
|
||||
|
||||
/**
|
||||
* All other column types without extra options used.
|
||||
*/
|
||||
export type SimpleColumnType =
|
||||
SmallintColumnType|
|
||||
IntegerColumnType|
|
||||
BigintColumnType|
|
||||
DecimalColumnType|
|
||||
RealColumnType|
|
||||
DoublePrecisionColumnType|
|
||||
SmallserialColumnType|
|
||||
SerialColumnType|
|
||||
BigserialColumnType|
|
||||
MoneyColumnType|
|
||||
TextColumnType|
|
||||
ByteaColumnType|
|
||||
DateColumnType|
|
||||
BooleanColumnType|
|
||||
PointColumnType|
|
||||
LineColumnType|
|
||||
LsegColumnType|
|
||||
BoxColumnType|
|
||||
CircleColumnType|
|
||||
PathColumnType|
|
||||
PolygonColumnType|
|
||||
CidrColumnType|
|
||||
InetColumnType|
|
||||
MacaddrColumnType|
|
||||
TsvectorColumnType|
|
||||
TsqueryColumnType|
|
||||
UUIDColumnType|
|
||||
XmlColumnType|
|
||||
JsonColumnType|
|
||||
JsonbColumnType;
|
||||
|
||||
/**
|
||||
* All column types supported by a database.
|
||||
*/
|
||||
export type AllColumnType =
|
||||
SimpleColumnType|
|
||||
WithLengthColumnType|
|
||||
WithTimeColumnType|
|
||||
NumericColumnType|
|
||||
EnumColumnType;
|
||||
@ -4,9 +4,7 @@ import {ObjectLiteral} from "../../common/ObjectLiteral";
|
||||
import {DatabaseConnection} from "../DatabaseConnection";
|
||||
import {DriverPackageNotInstalledError} from "../error/DriverPackageNotInstalledError";
|
||||
import {DriverUtils} from "../DriverUtils";
|
||||
import {ColumnTypes} from "../../metadata/types/ColumnTypes";
|
||||
import {ColumnMetadata} from "../../metadata/ColumnMetadata";
|
||||
import {Logger} from "../../logger/Logger";
|
||||
import {PostgresQueryRunner} from "./PostgresQueryRunner";
|
||||
import {QueryRunner} from "../../query-runner/QueryRunner";
|
||||
import {DriverOptionNotSetError} from "../error/DriverOptionNotSetError";
|
||||
@ -15,12 +13,83 @@ import {PlatformTools} from "../../platform/PlatformTools";
|
||||
import {Connection} from "../../connection/Connection";
|
||||
import {SchemaBuilder} from "../../schema-builder/SchemaBuilder";
|
||||
import {PostgresConnectionOptions} from "./PostgresConnectionOptions";
|
||||
import {MappedColumnTypes} from "../types/MappedColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
|
||||
/**
|
||||
* Organizes communication with PostgreSQL DBMS.
|
||||
*/
|
||||
export class PostgresDriver implements Driver {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Implemented Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets list of supported column data types by a driver.
|
||||
*
|
||||
* @see https://www.tutorialspoint.com/postgresql/postgresql_data_types.htm
|
||||
* @see https://www.postgresql.org/docs/9.2/static/datatype.html
|
||||
*/
|
||||
supportedDataTypes: ColumnType[] = [
|
||||
"smallint",
|
||||
"integer",
|
||||
"bigint",
|
||||
"decimal",
|
||||
"numeric",
|
||||
"real",
|
||||
"double precision",
|
||||
"smallserial",
|
||||
"serial",
|
||||
"bigserial",
|
||||
"money",
|
||||
"character varying",
|
||||
"varchar",
|
||||
"character",
|
||||
"char",
|
||||
"text",
|
||||
"bytea",
|
||||
"timestamp",
|
||||
"timestamp without time zone",
|
||||
"timestamp with time zone",
|
||||
"date",
|
||||
"time",
|
||||
"time without time zone",
|
||||
"time with time zone",
|
||||
"interval",
|
||||
"boolean",
|
||||
"enum",
|
||||
"point",
|
||||
"line",
|
||||
"lseg",
|
||||
"box",
|
||||
"path",
|
||||
"polygon",
|
||||
"circle",
|
||||
"cidr",
|
||||
"inet",
|
||||
"macaddr",
|
||||
"tsvector",
|
||||
"tsquery",
|
||||
"uuid",
|
||||
"xml",
|
||||
"json",
|
||||
"jsonb"
|
||||
];
|
||||
|
||||
/**
|
||||
* Orm has special columns and we need to know what database column types should be for those types.
|
||||
* Column types are driver dependant.
|
||||
*/
|
||||
mappedDataTypes: MappedColumnTypes = {
|
||||
createDate: "timestamp",
|
||||
updateDate: "timestamp",
|
||||
version: "int",
|
||||
treeLevel: "int",
|
||||
migrationName: "varchar",
|
||||
migrationTimestamp: "timestamp",
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Properties
|
||||
// -------------------------------------------------------------------------
|
||||
@ -147,33 +216,29 @@ export class PostgresDriver implements Driver {
|
||||
/**
|
||||
* Prepares given value to a value to be persisted, based on its column type and metadata.
|
||||
*/
|
||||
preparePersistentValue(value: any, column: ColumnMetadata): any {
|
||||
preparePersistentValue(value: any, columnMetadata: ColumnMetadata): any {
|
||||
if (value === null || value === undefined)
|
||||
return null;
|
||||
return value;
|
||||
|
||||
switch (column.type) {
|
||||
case ColumnTypes.BOOLEAN:
|
||||
return value === true ? 1 : 0;
|
||||
if (columnMetadata.type === Boolean) {
|
||||
return value === true ? 1 : 0;
|
||||
|
||||
case ColumnTypes.DATE:
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
} else if (columnMetadata.type === "date") {
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
|
||||
case ColumnTypes.TIME:
|
||||
return DataUtils.mixedDateToTimeString(value);
|
||||
} else if (columnMetadata.type === "time") {
|
||||
return DataUtils.mixedDateToTimeString(value);
|
||||
|
||||
case ColumnTypes.DATETIME:
|
||||
if (column.localTimezone) {
|
||||
return DataUtils.mixedDateToDatetimeString(value);
|
||||
} else {
|
||||
return DataUtils.mixedDateToUtcDatetimeString(value);
|
||||
}
|
||||
} else if (columnMetadata.type === "timestamp"
|
||||
|| columnMetadata.type === "timestamp with time zone"
|
||||
|| columnMetadata.type === "timestamp without time zone") {
|
||||
return DataUtils.mixedDateToUtcDatetimeString(value);
|
||||
|
||||
case ColumnTypes.JSON:
|
||||
case ColumnTypes.JSONB:
|
||||
return JSON.stringify(value);
|
||||
} else if (columnMetadata.type === "json" || columnMetadata.type === "jsonb") {
|
||||
return JSON.stringify(value);
|
||||
|
||||
case ColumnTypes.SIMPLE_ARRAY:
|
||||
return DataUtils.simpleArrayToString(value);
|
||||
} else if (columnMetadata.type === "simple-array") {
|
||||
return DataUtils.simpleArrayToString(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
@ -183,32 +248,26 @@ export class PostgresDriver implements Driver {
|
||||
* Prepares given value to a value to be persisted, based on its column type or metadata.
|
||||
*/
|
||||
prepareHydratedValue(value: any, columnMetadata: ColumnMetadata): any {
|
||||
switch (columnMetadata.type) {
|
||||
case ColumnTypes.BOOLEAN:
|
||||
return value ? true : false;
|
||||
if (columnMetadata.type === Boolean) {
|
||||
return value ? true : false;
|
||||
|
||||
case ColumnTypes.DATETIME:
|
||||
return DataUtils.normalizeHydratedDate(value, columnMetadata.localTimezone === true);
|
||||
} else if (columnMetadata.type === "timestamp"
|
||||
|| columnMetadata.type === "timestamp with time zone"
|
||||
|| columnMetadata.type === "timestamp without time zone") {
|
||||
return DataUtils.normalizeHydratedDate(value);
|
||||
|
||||
case ColumnTypes.DATE:
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
} else if (columnMetadata.type === "date") {
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
|
||||
case ColumnTypes.TIME:
|
||||
return DataUtils.mixedTimeToString(value);
|
||||
} else if (columnMetadata.type === "time") {
|
||||
return DataUtils.mixedTimeToString(value);
|
||||
|
||||
case ColumnTypes.JSON:
|
||||
case ColumnTypes.JSONB:
|
||||
// pg(pg-types) have done JSON.parse conversion
|
||||
// https://github.com/brianc/node-pg-types/blob/ed2d0e36e33217b34530727a98d20b325389e73a/lib/textParsers.js#L170
|
||||
return value;
|
||||
|
||||
case ColumnTypes.SIMPLE_ARRAY:
|
||||
return DataUtils.stringToSimpleArray(value);
|
||||
} else if (columnMetadata.type === "simple-array") {
|
||||
return DataUtils.stringToSimpleArray(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces parameters in the given sql with special escaping character
|
||||
* and an array of parameter names to be passed to a query.
|
||||
|
||||
@ -11,9 +11,10 @@ import {IndexSchema} from "../../schema-builder/schema/IndexSchema";
|
||||
import {ForeignKeySchema} from "../../schema-builder/schema/ForeignKeySchema";
|
||||
import {PrimaryKeySchema} from "../../schema-builder/schema/PrimaryKeySchema";
|
||||
import {QueryRunnerAlreadyReleasedError} from "../../query-runner/error/QueryRunnerAlreadyReleasedError";
|
||||
import {ColumnType} from "../../metadata/types/ColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
import {Connection} from "../../connection/Connection";
|
||||
import {PostgresConnectionOptions} from "./PostgresConnectionOptions";
|
||||
import {ColumnOptions} from "../../decorator/options/ColumnOptions";
|
||||
|
||||
/**
|
||||
* Runs queries on a single postgres database connection.
|
||||
@ -752,69 +753,42 @@ where constraint_type = 'PRIMARY KEY' AND c.table_schema = '${this.schemaName}'
|
||||
/**
|
||||
* Creates a database type from a given column metadata.
|
||||
*/
|
||||
normalizeType(typeOptions: { type: ColumnType, length?: string|number, precision?: number, scale?: number, timezone?: boolean, fixedLength?: boolean }): string {
|
||||
switch (typeOptions.type) {
|
||||
case "string":
|
||||
if (typeOptions.fixedLength) {
|
||||
return "character(" + (typeOptions.length ? typeOptions.length : 255) + ")";
|
||||
} else {
|
||||
return "character varying(" + (typeOptions.length ? typeOptions.length : 255) + ")";
|
||||
}
|
||||
case "text":
|
||||
return "text";
|
||||
case "boolean":
|
||||
return "boolean";
|
||||
case "integer":
|
||||
case "int":
|
||||
return "integer";
|
||||
case "smallint":
|
||||
return "smallint";
|
||||
case "bigint":
|
||||
return "bigint";
|
||||
case "float":
|
||||
return "real";
|
||||
case "double":
|
||||
case "number":
|
||||
return "double precision";
|
||||
case "decimal":
|
||||
if (typeOptions.precision && typeOptions.scale) {
|
||||
return `decimal(${typeOptions.precision},${typeOptions.scale})`;
|
||||
normalizeType(column: ColumnMetadata): string {
|
||||
let type = "";
|
||||
if (column.type === Number) {
|
||||
type += "integer";
|
||||
|
||||
} else if (typeOptions.scale) {
|
||||
return `decimal(${typeOptions.scale})`;
|
||||
} else if (column.type === String) {
|
||||
type += "character varying";
|
||||
|
||||
} else if (typeOptions.precision) {
|
||||
return `decimal(${typeOptions.precision})`;
|
||||
} else if (column.type === Date) {
|
||||
type += "timestamp";
|
||||
|
||||
} else {
|
||||
return "decimal";
|
||||
} else if (column.type === Boolean) {
|
||||
type += "boolean";
|
||||
|
||||
}
|
||||
case "date":
|
||||
return "date";
|
||||
case "time":
|
||||
if (typeOptions.timezone) {
|
||||
return "time with time zone";
|
||||
} else {
|
||||
return "time without time zone";
|
||||
}
|
||||
case "datetime":
|
||||
if (typeOptions.timezone) {
|
||||
return "timestamp with time zone";
|
||||
} else {
|
||||
return "timestamp without time zone";
|
||||
}
|
||||
case "json":
|
||||
return "json";
|
||||
case "jsonb":
|
||||
return "jsonb";
|
||||
case "simple_array":
|
||||
return typeOptions.length ? "character varying(" + typeOptions.length + ")" : "text";
|
||||
case "uuid":
|
||||
return "uuid";
|
||||
} else if (column.type === Object) {
|
||||
type += "text";
|
||||
|
||||
} else if (column.type === "simple-array") {
|
||||
type += "text";
|
||||
|
||||
} else {
|
||||
type += column.type;
|
||||
}
|
||||
if (column.length) {
|
||||
type += "(" + column.length + ")";
|
||||
|
||||
throw new DataTypeNotSupportedByDriverError(typeOptions.type, "Postgres");
|
||||
} else if (column.precision && column.scale) {
|
||||
type += "(" + column.precision + "," + column.scale + ")";
|
||||
|
||||
} else if (column.precision) {
|
||||
type += "(" + column.precision + ")";
|
||||
|
||||
} else if (column.scale) {
|
||||
type += "(" + column.scale + ")";
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -3,7 +3,6 @@ import {ConnectionIsNotSetError} from "../error/ConnectionIsNotSetError";
|
||||
import {ObjectLiteral} from "../../common/ObjectLiteral";
|
||||
import {DatabaseConnection} from "../DatabaseConnection";
|
||||
import {DriverPackageNotInstalledError} from "../error/DriverPackageNotInstalledError";
|
||||
import {ColumnTypes} from "../../metadata/types/ColumnTypes";
|
||||
import {ColumnMetadata} from "../../metadata/ColumnMetadata";
|
||||
import {SqliteQueryRunner} from "./SqliteQueryRunner";
|
||||
import {QueryRunner} from "../../query-runner/QueryRunner";
|
||||
@ -13,12 +12,69 @@ import {PlatformTools} from "../../platform/PlatformTools";
|
||||
import {Connection} from "../../connection/Connection";
|
||||
import {SchemaBuilder} from "../../schema-builder/SchemaBuilder";
|
||||
import {SqliteConnectionOptions} from "./SqliteConnectionOptions";
|
||||
import {MappedColumnTypes} from "../types/MappedColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
|
||||
/**
|
||||
* Organizes communication with sqlite DBMS.
|
||||
*/
|
||||
export class SqliteDriver implements Driver {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Implemented Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets list of supported column data types by a driver.
|
||||
*
|
||||
* @see https://www.tutorialspoint.com/sqlite/sqlite_data_types.htm
|
||||
* @see https://sqlite.org/datatype3.html
|
||||
*/
|
||||
supportedDataTypes: ColumnType[] = [
|
||||
"int",
|
||||
"integer",
|
||||
"tinyint",
|
||||
"smallint",
|
||||
"mediumint",
|
||||
"bigint",
|
||||
"int2",
|
||||
"int8",
|
||||
"integer",
|
||||
"character",
|
||||
"varchar",
|
||||
"varying character",
|
||||
"nchar",
|
||||
"native character",
|
||||
"nvarchar",
|
||||
"text",
|
||||
"clob",
|
||||
"text",
|
||||
"blob",
|
||||
"real",
|
||||
"double",
|
||||
"double precision",
|
||||
"float",
|
||||
"real",
|
||||
"numeric",
|
||||
"decimal",
|
||||
"boolean",
|
||||
"date",
|
||||
"datetime",
|
||||
];
|
||||
|
||||
/**
|
||||
* Orm has special columns and we need to know what database column types should be for those types.
|
||||
* Column types are driver dependant.
|
||||
*/
|
||||
mappedDataTypes: MappedColumnTypes = {
|
||||
createDate: "datetime",
|
||||
updateDate: "datetime",
|
||||
version: "integer",
|
||||
treeLevel: "integer",
|
||||
migrationName: "varchar",
|
||||
migrationTimestamp: "timestamp",
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Properties
|
||||
// -------------------------------------------------------------------------
|
||||
@ -129,30 +185,25 @@ export class SqliteDriver implements Driver {
|
||||
*/
|
||||
preparePersistentValue(value: any, columnMetadata: ColumnMetadata): any {
|
||||
if (value === null || value === undefined)
|
||||
return null;
|
||||
return value;
|
||||
|
||||
switch (columnMetadata.type) {
|
||||
case ColumnTypes.BOOLEAN:
|
||||
return value === true ? 1 : 0;
|
||||
if (columnMetadata.type === Boolean) {
|
||||
return value === true ? 1 : 0;
|
||||
|
||||
case ColumnTypes.DATE:
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
} else if (columnMetadata.type === "date") {
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
|
||||
case ColumnTypes.TIME:
|
||||
return DataUtils.mixedDateToTimeString(value);
|
||||
} else if (columnMetadata.type === "time") {
|
||||
return DataUtils.mixedDateToTimeString(value);
|
||||
|
||||
case ColumnTypes.DATETIME:
|
||||
if (columnMetadata.localTimezone) {
|
||||
return DataUtils.mixedDateToDatetimeString(value);
|
||||
} else {
|
||||
return DataUtils.mixedDateToUtcDatetimeString(value);
|
||||
}
|
||||
} else if (columnMetadata.type === "datetime") {
|
||||
return DataUtils.mixedDateToUtcDatetimeString(value);
|
||||
|
||||
case ColumnTypes.JSON:
|
||||
return JSON.stringify(value);
|
||||
} else if (columnMetadata.type === "json") {
|
||||
return JSON.stringify(value);
|
||||
|
||||
case ColumnTypes.SIMPLE_ARRAY:
|
||||
return DataUtils.simpleArrayToString(value);
|
||||
} else if (columnMetadata.type === "simple-array") {
|
||||
return DataUtils.simpleArrayToString(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
@ -162,24 +213,23 @@ export class SqliteDriver implements Driver {
|
||||
* Prepares given value to a value to be persisted, based on its column type or metadata.
|
||||
*/
|
||||
prepareHydratedValue(value: any, columnMetadata: ColumnMetadata): any {
|
||||
switch (columnMetadata.type) {
|
||||
case ColumnTypes.BOOLEAN:
|
||||
return value ? true : false;
|
||||
if (columnMetadata.type === Boolean) {
|
||||
return value ? true : false;
|
||||
|
||||
case ColumnTypes.DATETIME:
|
||||
return DataUtils.normalizeHydratedDate(value, columnMetadata.localTimezone === true);
|
||||
} else if (columnMetadata.type === "datetime") {
|
||||
return DataUtils.normalizeHydratedDate(value);
|
||||
|
||||
case ColumnTypes.DATE:
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
} else if (columnMetadata.type === "date") {
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
|
||||
case ColumnTypes.TIME:
|
||||
return DataUtils.mixedTimeToString(value);
|
||||
} else if (columnMetadata.type === "time") {
|
||||
return DataUtils.mixedTimeToString(value);
|
||||
|
||||
case ColumnTypes.JSON:
|
||||
return JSON.parse(value);
|
||||
} else if (columnMetadata.type === "json") {
|
||||
return JSON.parse(value);
|
||||
|
||||
case ColumnTypes.SIMPLE_ARRAY:
|
||||
return DataUtils.stringToSimpleArray(value);
|
||||
} else if (columnMetadata.type === "simple-array") {
|
||||
return DataUtils.stringToSimpleArray(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
@ -11,9 +11,10 @@ import {IndexSchema} from "../../schema-builder/schema/IndexSchema";
|
||||
import {ForeignKeySchema} from "../../schema-builder/schema/ForeignKeySchema";
|
||||
import {PrimaryKeySchema} from "../../schema-builder/schema/PrimaryKeySchema";
|
||||
import {QueryRunnerAlreadyReleasedError} from "../../query-runner/error/QueryRunnerAlreadyReleasedError";
|
||||
import {ColumnType} from "../../metadata/types/ColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
import {RandomGenerator} from "../../util/RandomGenerator";
|
||||
import {Connection} from "../../connection/Connection";
|
||||
import {ColumnOptions} from "../../decorator/options/ColumnOptions";
|
||||
|
||||
/**
|
||||
* Runs queries on a single sqlite database connection.
|
||||
@ -737,61 +738,50 @@ export class SqliteQueryRunner implements QueryRunner {
|
||||
/**
|
||||
* Creates a database type from a given column metadata.
|
||||
*/
|
||||
normalizeType(typeOptions: { type: ColumnType, length?: string|number, precision?: number, scale?: number, timezone?: boolean, fixedLength?: boolean }): string {
|
||||
switch (typeOptions.type) {
|
||||
case "string":
|
||||
return "character varying(" + (typeOptions.length ? typeOptions.length : 255) + ")";
|
||||
case "text":
|
||||
return "text";
|
||||
case "boolean":
|
||||
return "boolean";
|
||||
case "integer":
|
||||
case "int":
|
||||
return "integer";
|
||||
case "smallint":
|
||||
return "smallint";
|
||||
case "bigint":
|
||||
return "bigint";
|
||||
case "float":
|
||||
return "real";
|
||||
case "double":
|
||||
case "number":
|
||||
return "double precision";
|
||||
case "decimal":
|
||||
if (typeOptions.precision && typeOptions.scale) {
|
||||
return `decimal(${typeOptions.precision},${typeOptions.scale})`;
|
||||
normalizeType(column: ColumnMetadata): string {
|
||||
let type = "";
|
||||
if (column.type === Number || column.type === "int") {
|
||||
type += "integer";
|
||||
|
||||
} else if (typeOptions.scale) {
|
||||
return `decimal(${typeOptions.scale})`;
|
||||
} else if (column.type === String) {
|
||||
type += "varchar";
|
||||
|
||||
} else if (typeOptions.precision) {
|
||||
return `decimal(${typeOptions.precision})`;
|
||||
} else if (column.type === Date) {
|
||||
type += "datetime";
|
||||
|
||||
} else {
|
||||
return "decimal";
|
||||
} else if (column.type === Boolean) {
|
||||
type += "boolean";
|
||||
|
||||
}
|
||||
case "date":
|
||||
return "date";
|
||||
case "time":
|
||||
if (typeOptions.timezone) {
|
||||
return "time with time zone";
|
||||
} else {
|
||||
return "time without time zone";
|
||||
}
|
||||
case "datetime":
|
||||
if (typeOptions.timezone) {
|
||||
return "timestamp with time zone";
|
||||
} else {
|
||||
return "timestamp without time zone";
|
||||
}
|
||||
case "json":
|
||||
return "json";
|
||||
case "simple_array":
|
||||
return typeOptions.length ? "character varying(" + typeOptions.length + ")" : "text";
|
||||
} else if (column.type === Object) {
|
||||
type += "text";
|
||||
|
||||
} else if (column.type === "simple-array") {
|
||||
type += "text";
|
||||
|
||||
} else {
|
||||
type += column.type;
|
||||
}
|
||||
if (column.length) {
|
||||
type += "(" + column.length + ")";
|
||||
|
||||
} else if (column.precision && column.scale) {
|
||||
type += "(" + column.precision + "," + column.scale + ")";
|
||||
|
||||
} else if (column.precision) {
|
||||
type += "(" + column.precision + ")";
|
||||
|
||||
} else if (column.scale) {
|
||||
type += "(" + column.scale + ")";
|
||||
}
|
||||
|
||||
throw new DataTypeNotSupportedByDriverError(typeOptions.type, "SQLite");
|
||||
// set default required length if those were not specified
|
||||
if (type === "varchar")
|
||||
type += "(255)";
|
||||
|
||||
if (type === "int")
|
||||
type += "(11)";
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -843,6 +833,7 @@ export class SqliteQueryRunner implements QueryRunner {
|
||||
c += " UNIQUE";
|
||||
if (column.isGenerated === true) // don't use skipPrimary here since updates can update already exist primary without auto inc.
|
||||
c += " PRIMARY KEY AUTOINCREMENT";
|
||||
|
||||
if (column.default !== undefined && column.default !== null) { // todo: same code in all drivers. make it DRY
|
||||
if (typeof column.default === "number") {
|
||||
c += " DEFAULT " + column.default + "";
|
||||
|
||||
@ -5,7 +5,6 @@ import {DriverPackageNotInstalledError} from "../error/DriverPackageNotInstalled
|
||||
import {DriverUtils} from "../DriverUtils";
|
||||
import {QueryRunner} from "../../query-runner/QueryRunner";
|
||||
import {SqlServerQueryRunner} from "./SqlServerQueryRunner";
|
||||
import {ColumnTypes} from "../../metadata/types/ColumnTypes";
|
||||
import {ObjectLiteral} from "../../common/ObjectLiteral";
|
||||
import {ColumnMetadata} from "../../metadata/ColumnMetadata";
|
||||
import {DriverOptionNotSetError} from "../error/DriverOptionNotSetError";
|
||||
@ -14,12 +13,72 @@ import {PlatformTools} from "../../platform/PlatformTools";
|
||||
import {Connection} from "../../connection/Connection";
|
||||
import {SchemaBuilder} from "../../schema-builder/SchemaBuilder";
|
||||
import {SqlServerConnectionOptions} from "./SqlServerConnectionOptions";
|
||||
import {MappedColumnTypes} from "../types/MappedColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
|
||||
/**
|
||||
* Organizes communication with SQL Server DBMS.
|
||||
*/
|
||||
export class SqlServerDriver implements Driver {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Implemented Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets list of supported column data types by a driver.
|
||||
*
|
||||
* @see https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-types-transact-sql
|
||||
*/
|
||||
supportedDataTypes: ColumnType[] = [
|
||||
"bigint",
|
||||
"bit",
|
||||
"decimal",
|
||||
"int",
|
||||
"money",
|
||||
"numeric",
|
||||
"smallint",
|
||||
"smallmoney",
|
||||
"tinyint",
|
||||
"float",
|
||||
"real",
|
||||
"date",
|
||||
"datetime2",
|
||||
"datetime",
|
||||
"datetimeoffset",
|
||||
"smalldatetime",
|
||||
"time",
|
||||
"char",
|
||||
"text",
|
||||
"varchar",
|
||||
"nchar",
|
||||
"ntext",
|
||||
"nvarchar",
|
||||
"binary",
|
||||
"image",
|
||||
"varbinary",
|
||||
"cursor",
|
||||
"hierarchyid",
|
||||
"sql_variant",
|
||||
"table",
|
||||
"timestamp",
|
||||
"uniqueidentifier",
|
||||
"xml"
|
||||
];
|
||||
|
||||
/**
|
||||
* Orm has special columns and we need to know what database column types should be for those types.
|
||||
* Column types are driver dependant.
|
||||
*/
|
||||
mappedDataTypes: MappedColumnTypes = {
|
||||
createDate: "datetime",
|
||||
updateDate: "datetime",
|
||||
version: "int",
|
||||
treeLevel: "int",
|
||||
migrationName: "varchar",
|
||||
migrationTimestamp: "timestamp",
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Properties
|
||||
// -------------------------------------------------------------------------
|
||||
@ -190,30 +249,25 @@ export class SqlServerDriver implements Driver {
|
||||
*/
|
||||
preparePersistentValue(value: any, columnMetadata: ColumnMetadata): any {
|
||||
if (value === null || value === undefined)
|
||||
return null;
|
||||
return value;
|
||||
|
||||
switch (columnMetadata.type) {
|
||||
case ColumnTypes.BOOLEAN:
|
||||
return value === true ? 1 : 0;
|
||||
if (columnMetadata.type === Boolean) {
|
||||
return value === true ? 1 : 0;
|
||||
|
||||
case ColumnTypes.DATE:
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
} else if (columnMetadata.type === "date") {
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
|
||||
case ColumnTypes.TIME:
|
||||
return DataUtils.mixedDateToTimeString(value);
|
||||
} else if (columnMetadata.type === "time") {
|
||||
return DataUtils.mixedDateToTimeString(value);
|
||||
|
||||
case ColumnTypes.DATETIME:
|
||||
if (columnMetadata.localTimezone) {
|
||||
return DataUtils.mixedDateToDatetimeString(value);
|
||||
} else {
|
||||
return DataUtils.mixedDateToUtcDatetimeString(value);
|
||||
}
|
||||
} else if (columnMetadata.type === "datetime") {
|
||||
return DataUtils.mixedDateToUtcDatetimeString(value);
|
||||
|
||||
case ColumnTypes.JSON:
|
||||
return JSON.stringify(value);
|
||||
} else if (columnMetadata.type === "json") {
|
||||
return JSON.stringify(value);
|
||||
|
||||
case ColumnTypes.SIMPLE_ARRAY:
|
||||
return DataUtils.simpleArrayToString(value);
|
||||
} else if (columnMetadata.type === "simple-array") {
|
||||
return DataUtils.simpleArrayToString(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
@ -223,29 +277,27 @@ export class SqlServerDriver implements Driver {
|
||||
* Prepares given value to a value to be persisted, based on its column type or metadata.
|
||||
*/
|
||||
prepareHydratedValue(value: any, columnMetadata: ColumnMetadata): any {
|
||||
switch (columnMetadata.type) {
|
||||
case ColumnTypes.BOOLEAN:
|
||||
return value ? true : false;
|
||||
if (columnMetadata.type === Boolean) {
|
||||
return value ? true : false;
|
||||
|
||||
case ColumnTypes.DATETIME:
|
||||
return DataUtils.normalizeHydratedDate(value, columnMetadata.localTimezone === true);
|
||||
} else if (columnMetadata.type === "datetime") {
|
||||
return DataUtils.normalizeHydratedDate(value);
|
||||
|
||||
case ColumnTypes.DATE:
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
} else if (columnMetadata.type === "date") {
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
|
||||
case ColumnTypes.TIME:
|
||||
return DataUtils.mixedTimeToString(value);
|
||||
} else if (columnMetadata.type === "time") {
|
||||
return DataUtils.mixedTimeToString(value);
|
||||
|
||||
case ColumnTypes.JSON:
|
||||
return JSON.parse(value);
|
||||
} else if (columnMetadata.type === "json") {
|
||||
return JSON.parse(value);
|
||||
|
||||
case ColumnTypes.SIMPLE_ARRAY:
|
||||
return DataUtils.stringToSimpleArray(value);
|
||||
} else if (columnMetadata.type === "simple-array") {
|
||||
return DataUtils.stringToSimpleArray(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -11,9 +11,10 @@ import {ForeignKeySchema} from "../../schema-builder/schema/ForeignKeySchema";
|
||||
import {PrimaryKeySchema} from "../../schema-builder/schema/PrimaryKeySchema";
|
||||
import {IndexSchema} from "../../schema-builder/schema/IndexSchema";
|
||||
import {QueryRunnerAlreadyReleasedError} from "../../query-runner/error/QueryRunnerAlreadyReleasedError";
|
||||
import {ColumnType} from "../../metadata/types/ColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
import {Connection} from "../../connection/Connection";
|
||||
import {SqlServerConnectionOptions} from "./SqlServerConnectionOptions";
|
||||
import {ColumnOptions} from "../../decorator/options/ColumnOptions";
|
||||
|
||||
/**
|
||||
* Runs queries on a single mysql database connection.
|
||||
@ -798,56 +799,42 @@ WHERE columnUsages.TABLE_CATALOG = '${this.dbName}' AND tableConstraints.TABLE_C
|
||||
/**
|
||||
* Creates a database type from a given column metadata.
|
||||
*/
|
||||
normalizeType(typeOptions: { type: ColumnType, length?: string|number, precision?: number, scale?: number, timezone?: boolean, fixedLength?: boolean }): string {
|
||||
switch (typeOptions.type) {
|
||||
case "string":
|
||||
if (typeOptions.fixedLength) {
|
||||
return "nchar(" + (typeOptions.length ? typeOptions.length : 255) + ")";
|
||||
} else {
|
||||
return "nvarchar(" + (typeOptions.length ? typeOptions.length : 255) + ")";
|
||||
}
|
||||
case "text":
|
||||
return "ntext";
|
||||
case "boolean":
|
||||
return "bit";
|
||||
case "integer":
|
||||
case "int":
|
||||
return "int";
|
||||
case "smallint":
|
||||
return "smallint";
|
||||
case "bigint":
|
||||
return "bigint";
|
||||
case "float":
|
||||
return "float";
|
||||
case "double":
|
||||
case "number":
|
||||
return "real";
|
||||
case "decimal":
|
||||
// if (column.precision && column.scale) {
|
||||
// return `decimal(${column.precision},${column.scale})`;
|
||||
//
|
||||
// } else if (column.scale) {
|
||||
// return `decimal(${column.scale})`;
|
||||
//
|
||||
// } else if (column.precision) {
|
||||
// return `decimal(${column.precision})`;
|
||||
//
|
||||
// } else {
|
||||
return "decimal";
|
||||
// }
|
||||
case "date":
|
||||
return "date";
|
||||
case "time":
|
||||
return "time";
|
||||
case "datetime":
|
||||
return "datetime";
|
||||
case "json":
|
||||
return "text";
|
||||
case "simple_array":
|
||||
return typeOptions.length ? "nvarchar(" + typeOptions.length + ")" : "text";
|
||||
}
|
||||
normalizeType(column: ColumnMetadata): string {
|
||||
let type = "";
|
||||
if (column.type === Number) {
|
||||
type += "int";
|
||||
|
||||
throw new DataTypeNotSupportedByDriverError(typeOptions.type, "SQLServer");
|
||||
} else if (column.type === String) {
|
||||
type += "nvarchar";
|
||||
|
||||
} else if (column.type === Date) {
|
||||
type += "datetime";
|
||||
|
||||
} else if (column.type === Boolean) {
|
||||
type += "bit";
|
||||
|
||||
} else if (column.type === Object) {
|
||||
type += "ntext";
|
||||
|
||||
} else if (column.type === "simple-array") {
|
||||
type += "ntext";
|
||||
|
||||
} else {
|
||||
type += column.type;
|
||||
}
|
||||
if (column.length) {
|
||||
type += "(" + column.length + ")";
|
||||
|
||||
} else if (column.precision && column.scale) {
|
||||
type += "(" + column.precision + "," + column.scale + ")";
|
||||
|
||||
} else if (column.precision) {
|
||||
type += "(" + column.precision + ")";
|
||||
|
||||
} else if (column.scale) {
|
||||
type += "(" + column.scale + ")";
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
417
src/driver/types/ColumnTypes.ts
Normal file
417
src/driver/types/ColumnTypes.ts
Normal file
@ -0,0 +1,417 @@
|
||||
|
||||
/**
|
||||
* Column types where precision and scale properties are used.
|
||||
*/
|
||||
export type WithPrecisionColumnType = "float" // mysql, mssql, oracle, sqlite
|
||||
|"double" // mysql, sqlite
|
||||
|"dec" // oracle
|
||||
|"decimal" // mysql, postgres, mssql, sqlite
|
||||
|"numeric" // postgres, mssql, sqlite
|
||||
|"real" // mysql, postgres, mssql, oracle, sqlite
|
||||
|"double precision" // postgres, oracle, sqlite
|
||||
|"number"; // oracle
|
||||
|
||||
/**
|
||||
* Column types where column length is used.
|
||||
*/
|
||||
export type WithLengthColumnType = "int" // mysql, postgres, mssql, oracle, sqlite
|
||||
|"tinyint" // mysql, mssql, sqlite
|
||||
|"smallint" // mysql, postgres, mssql, oracle, sqlite
|
||||
|"mediumint" // mysql, sqlite
|
||||
|"bigint" // mysql, postgres, mssql, sqlite
|
||||
|"character varying" // postgres
|
||||
|"varying character" // sqlite
|
||||
|"nvarchar" // mssql
|
||||
|"character" // mysql, postgres, sqlite
|
||||
|"native character" // sqlite
|
||||
|"varchar" // mysql, postgres, mssql, sqlite
|
||||
|"char" // mysql, postgres, mssql, oracle
|
||||
|"nchar" // mssql, oracle, sqlite
|
||||
|"varchar2" // oracle
|
||||
|"nvarchar2" // oracle, sqlite
|
||||
|"year"; // mysql
|
||||
|
||||
/**
|
||||
* All other regular column types.
|
||||
*/
|
||||
export type SimpleColumnType =
|
||||
|
||||
"simple-array" // typeorm-specific, automatically mapped to string
|
||||
// |"string" // typeorm-specific, automatically mapped to varchar depend on platform
|
||||
|
||||
// numeric types
|
||||
|"bit" // mssql
|
||||
|"int2" // postgres, sqlite
|
||||
|"integer" // postgres, oracle, sqlite
|
||||
|"int4" // postgres
|
||||
|"int8" // postgres, sqlite
|
||||
|"float4" // postgres
|
||||
|"float8" // postgres
|
||||
|"smallserial" // postgres
|
||||
|"serial2" // postgres
|
||||
|"serial" // postgres
|
||||
|"serial4" // postgres
|
||||
|"bigserial" // postgres
|
||||
|"serial8" // postgres
|
||||
|"smallmoney" // mssql
|
||||
|"money" // postgres, mssql
|
||||
|
||||
// boolean types
|
||||
|"boolean" // postgres, sqlite
|
||||
|"bool" // postgres
|
||||
|
||||
// text/binary types
|
||||
|"tinyblob" // mysql
|
||||
|"tinytext" // mysql
|
||||
|"mediumblob" // mysql
|
||||
|"mediumtext" // mysql
|
||||
|"blob" // mysql, oracle, sqlite
|
||||
|"text" // mysql, postgres, mssql, sqlite
|
||||
|"ntext" // mssql
|
||||
|"longblob" // mysql
|
||||
|"longtext" // mysql
|
||||
|"bytea" // postgres
|
||||
|"long" // oracle
|
||||
|"raw" // oracle
|
||||
|"long raw" // oracle
|
||||
|"bfile" // oracle
|
||||
|"clob" // oracle, sqlite
|
||||
|"nclob" // oracle
|
||||
|"binary" // mssql
|
||||
|"varbinary" // mssql
|
||||
|"image" // mssql
|
||||
|
||||
// date types
|
||||
|"timestamp" // mysql, postgres, mssql, oracle
|
||||
|"timestamp without time zone" // postgres
|
||||
|"timestamp with time zone" // postgres, oracle
|
||||
|"timestamp with local time zone" // oracle
|
||||
|"datetime" // mssql, mysql, sqlite
|
||||
|"datetime2" // mssql
|
||||
|"datetimeoffset" // mssql
|
||||
|"smalldatetime" // mssql
|
||||
|"date" // mysql, postgres, mssql, oracle, sqlite
|
||||
|"time" // mysql, postgres, mssql
|
||||
|"time with time zone" // postgres
|
||||
|"time without time zone" // postgres
|
||||
|"interval year" // oracle
|
||||
|"interval day" // oracle
|
||||
|"interval" // postgres
|
||||
|
||||
// geometric types
|
||||
|"point" // postgres
|
||||
|"line" // postgres
|
||||
|"lseg" // postgres
|
||||
|"box" // postgres
|
||||
|"circle" // postgres
|
||||
|"path" // postgres
|
||||
|"polygon" // postgres
|
||||
|
||||
// other types
|
||||
|"enum" // mysql, postgres
|
||||
|"cidr" // postgres
|
||||
|"inet" // postgres
|
||||
|"macaddr"// postgres
|
||||
|"bit" // postgres
|
||||
|"bit varying" // postgres
|
||||
|"varbit"// postgres
|
||||
|"tsvector" // postgres
|
||||
|"tsquery" // postgres
|
||||
|"uuid" // postgres
|
||||
|"xml" // mssql, postgres
|
||||
|"json" // postgres
|
||||
|"jsonb" // postgres
|
||||
|"varbinary" // mssql
|
||||
|"cursor" // mssql
|
||||
|"hierarchyid" // mssql
|
||||
|"sql_variant" // mssql
|
||||
|"table" // mssql
|
||||
|"rowid" // oracle
|
||||
|"urowid" // oracle
|
||||
|"uniqueidentifier"; // mssql
|
||||
|
||||
/**
|
||||
* Any column type column can be.
|
||||
*/
|
||||
export type ColumnType = WithPrecisionColumnType
|
||||
|WithLengthColumnType
|
||||
|SimpleColumnType
|
||||
|BooleanConstructor
|
||||
|DateConstructor
|
||||
|NumberConstructor
|
||||
|StringConstructor
|
||||
|ObjectConstructor;
|
||||
|
||||
// "string"|"text"|"number"|"integer"|"int"|"smallint"|"bigint"|"float"|"double"|
|
||||
// "decimal"|"date"|"time"|"datetime"|"boolean"|"json"|"jsonb"|"simple_array"|"uuid";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Merged Types
|
||||
// -------------------------------------------------------------------------
|
||||
/*
|
||||
/!**
|
||||
* Column types where column length is used.
|
||||
*!/
|
||||
export type WithLengthColumnType =
|
||||
VarcharColumnType|
|
||||
CharColumnType|
|
||||
IntervalColumnType|
|
||||
BitColumnType|
|
||||
VarbitColumnType;
|
||||
|
||||
/!**
|
||||
* Column types where time options are used.
|
||||
*!/
|
||||
export type WithTimeColumnType =
|
||||
TimeColumnType|
|
||||
TimestampColumnType;
|
||||
|
||||
/!**
|
||||
* All other column types without extra options used.
|
||||
*!/
|
||||
export type SimpleColumnType =
|
||||
SmallintColumnType|
|
||||
IntegerColumnType|
|
||||
BigintColumnType|
|
||||
DecimalColumnType|
|
||||
RealColumnType|
|
||||
DoublePrecisionColumnType|
|
||||
SmallserialColumnType|
|
||||
SerialColumnType|
|
||||
BigserialColumnType|
|
||||
MoneyColumnType|
|
||||
TextColumnType|
|
||||
ByteaColumnType|
|
||||
DateColumnType|
|
||||
BooleanColumnType|
|
||||
PointColumnType|
|
||||
LineColumnType|
|
||||
LsegColumnType|
|
||||
BoxColumnType|
|
||||
CircleColumnType|
|
||||
PathColumnType|
|
||||
PolygonColumnType|
|
||||
CidrColumnType|
|
||||
InetColumnType|
|
||||
MacaddrColumnType|
|
||||
TsvectorColumnType|
|
||||
TsqueryColumnType|
|
||||
UUIDColumnType|
|
||||
XmlColumnType|
|
||||
JsonColumnType|
|
||||
JsonbColumnType;
|
||||
|
||||
/!**
|
||||
* All column types supported by a database.
|
||||
*!/
|
||||
export type AllColumnType =
|
||||
SimpleColumnType|
|
||||
WithLengthColumnType|
|
||||
WithTimeColumnType|
|
||||
NumericColumnType|
|
||||
EnumColumnType;
|
||||
|
||||
|
||||
/!**
|
||||
* All data types that column can be.
|
||||
*!/
|
||||
export type ColumnType =
|
||||
"tinyint"|
|
||||
"smallint"|
|
||||
"int2"|
|
||||
"mediumint"|
|
||||
"integer"|
|
||||
"int"|
|
||||
"int4"|
|
||||
"bigint"|
|
||||
"int8"|
|
||||
"decimal"|
|
||||
"numeric"|
|
||||
"real"|
|
||||
"float4"|
|
||||
"float"|
|
||||
"double"|
|
||||
"double precision"|
|
||||
"numeric"|
|
||||
"decimal"|
|
||||
"string"|"text"|"number"|"integer"|"int"|"smallint"|"bigint"|"float"|"double"|
|
||||
"decimal"|"date"|"time"|"datetime"|"boolean"|"json"|"jsonb"|"simple_array"|"uuid";*/
|
||||
/*
|
||||
|
||||
/!**
|
||||
* All data types that column can be.
|
||||
*!/
|
||||
export class ColumnTypes {
|
||||
|
||||
/!**
|
||||
* SQL VARCHAR type. Your class's property type should be a "string".
|
||||
*!/
|
||||
static STRING: ColumnType = "string";
|
||||
|
||||
/!**
|
||||
* 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";
|
||||
|
||||
/!**
|
||||
* Postgres jsonb type. Your class's property type should be any Object.
|
||||
*!/
|
||||
static JSONB: ColumnType = "jsonb";
|
||||
|
||||
/!**
|
||||
* 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";
|
||||
|
||||
/!**
|
||||
* UUID type. Serialized to a string in typescript or javascript
|
||||
*!/
|
||||
static UUID: ColumnType = "uuid";
|
||||
|
||||
/!**
|
||||
* Checks if given type in a string format is supported by ORM.
|
||||
*!/
|
||||
static isTypeSupported(type: string) {
|
||||
return this.supportedTypes.indexOf(<ColumnType> 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.JSONB,
|
||||
this.SIMPLE_ARRAY,
|
||||
this.UUID
|
||||
];
|
||||
}
|
||||
|
||||
/!**
|
||||
* Tries to guess a column type from the given function.
|
||||
*!/
|
||||
static determineTypeFromFunction(type: Function): ColumnType|undefined {
|
||||
if (type instanceof Date) {
|
||||
return ColumnTypes.DATETIME;
|
||||
|
||||
} 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;
|
||||
case "date":
|
||||
return ColumnTypes.DATETIME;
|
||||
case "object":
|
||||
return ColumnTypes.JSON;
|
||||
}
|
||||
|
||||
} else if (type instanceof Object) {
|
||||
return ColumnTypes.JSON;
|
||||
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
static typeToString(type: Function): string {
|
||||
return (type as any).name.toLowerCase();
|
||||
}
|
||||
|
||||
/!**
|
||||
* Checks if column type is numeric.
|
||||
*!/
|
||||
static isNumeric(type: ColumnType) {
|
||||
return type === ColumnTypes.NUMBER ||
|
||||
type === ColumnTypes.INT ||
|
||||
type === ColumnTypes.INTEGER ||
|
||||
type === ColumnTypes.BIGINT ||
|
||||
type === ColumnTypes.SMALLINT ||
|
||||
type === ColumnTypes.DOUBLE ||
|
||||
type === ColumnTypes.FLOAT;
|
||||
}
|
||||
|
||||
}*/
|
||||
39
src/driver/types/MappedColumnTypes.ts
Normal file
39
src/driver/types/MappedColumnTypes.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import {ColumnType} from "./ColumnTypes";
|
||||
|
||||
/**
|
||||
* Orm has special columns and we need to know what database column types should be for those types.
|
||||
* Column types are driver dependant.
|
||||
*/
|
||||
export interface MappedColumnTypes {
|
||||
|
||||
/**
|
||||
* Column type for the create date column.
|
||||
*/
|
||||
createDate: ColumnType;
|
||||
|
||||
/**
|
||||
* Column type for the update date column.
|
||||
*/
|
||||
updateDate: ColumnType;
|
||||
|
||||
/**
|
||||
* Column type for the version column.
|
||||
*/
|
||||
version: ColumnType;
|
||||
|
||||
/**
|
||||
* Column type for the tree level column.
|
||||
*/
|
||||
treeLevel: ColumnType;
|
||||
|
||||
/**
|
||||
* Column type of timestamp column used for migrations table.
|
||||
*/
|
||||
migrationTimestamp: ColumnType;
|
||||
|
||||
/**
|
||||
* Column type for migration name column used for migrations table.
|
||||
*/
|
||||
migrationName: ColumnType;
|
||||
|
||||
}
|
||||
@ -3,7 +3,6 @@ import {ConnectionIsNotSetError} from "../error/ConnectionIsNotSetError";
|
||||
import {DatabaseConnection} from "../DatabaseConnection";
|
||||
import {DriverUtils} from "../DriverUtils";
|
||||
import {QueryRunner} from "../../query-runner/QueryRunner";
|
||||
import {ColumnTypes} from "../../metadata/types/ColumnTypes";
|
||||
import {ObjectLiteral} from "../../common/ObjectLiteral";
|
||||
import {ColumnMetadata} from "../../metadata/ColumnMetadata";
|
||||
import {DriverOptionNotSetError} from "../error/DriverOptionNotSetError";
|
||||
@ -12,6 +11,8 @@ import {WebsqlQueryRunner} from "./WebsqlQueryRunner";
|
||||
import {Connection} from "../../connection/Connection";
|
||||
import {SchemaBuilder} from "../../schema-builder/SchemaBuilder";
|
||||
import {WebSqlConnectionOptions} from "./WebSqlConnectionOptions";
|
||||
import {MappedColumnTypes} from "../types/MappedColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
|
||||
/**
|
||||
* Declare a global function that is only available in browsers that support WebSQL.
|
||||
@ -23,6 +24,61 @@ declare function openDatabase(...params: any[]): any;
|
||||
*/
|
||||
export class WebsqlDriver implements Driver {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Implemented Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets list of supported column data types by a driver.
|
||||
*
|
||||
* @see https://www.tutorialspoint.com/sqlite/sqlite_data_types.htm
|
||||
* @see https://sqlite.org/datatype3.html
|
||||
*/
|
||||
supportedDataTypes: ColumnType[] = [
|
||||
"int",
|
||||
"integer",
|
||||
"tinyint",
|
||||
"smallint",
|
||||
"mediumint",
|
||||
"bigint",
|
||||
"int2",
|
||||
"int8",
|
||||
"integer",
|
||||
"character",
|
||||
"varchar",
|
||||
"varying character",
|
||||
"nchar",
|
||||
"native character",
|
||||
"nvarchar",
|
||||
"text",
|
||||
"clob",
|
||||
"text",
|
||||
"blob",
|
||||
"real",
|
||||
"double",
|
||||
"double precision",
|
||||
"float",
|
||||
"real",
|
||||
"numeric",
|
||||
"decimal",
|
||||
"boolean",
|
||||
"date",
|
||||
"datetime",
|
||||
];
|
||||
|
||||
/**
|
||||
* Orm has special columns and we need to know what database column types should be for those types.
|
||||
* Column types are driver dependant.
|
||||
*/
|
||||
mappedDataTypes: MappedColumnTypes = {
|
||||
createDate: "datetime",
|
||||
updateDate: "datetime",
|
||||
version: "number",
|
||||
treeLevel: "number",
|
||||
migrationName: "varchar",
|
||||
migrationTimestamp: "timestamp",
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Properties
|
||||
// -------------------------------------------------------------------------
|
||||
@ -172,30 +228,25 @@ export class WebsqlDriver implements Driver {
|
||||
*/
|
||||
preparePersistentValue(value: any, columnMetadata: ColumnMetadata): any {
|
||||
if (value === null || value === undefined)
|
||||
return null;
|
||||
return value;
|
||||
|
||||
switch (columnMetadata.type) {
|
||||
case ColumnTypes.BOOLEAN:
|
||||
return value === true ? 1 : 0;
|
||||
if (columnMetadata.type === Boolean) {
|
||||
return value === true ? 1 : 0;
|
||||
|
||||
case ColumnTypes.DATE:
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
} else if (columnMetadata.type === "date") {
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
|
||||
case ColumnTypes.TIME:
|
||||
return DataUtils.mixedDateToTimeString(value);
|
||||
} else if (columnMetadata.type === "time") {
|
||||
return DataUtils.mixedDateToTimeString(value);
|
||||
|
||||
case ColumnTypes.DATETIME:
|
||||
if (columnMetadata.localTimezone) {
|
||||
return DataUtils.mixedDateToDatetimeString(value);
|
||||
} else {
|
||||
return DataUtils.mixedDateToUtcDatetimeString(value);
|
||||
}
|
||||
} else if (columnMetadata.type === "datetime") {
|
||||
return DataUtils.mixedDateToUtcDatetimeString(value);
|
||||
|
||||
case ColumnTypes.JSON:
|
||||
return JSON.stringify(value);
|
||||
} else if (columnMetadata.type === "json") {
|
||||
return JSON.stringify(value);
|
||||
|
||||
case ColumnTypes.SIMPLE_ARRAY:
|
||||
return DataUtils.simpleArrayToString(value);
|
||||
} else if (columnMetadata.type === "simple-array") {
|
||||
return DataUtils.simpleArrayToString(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
@ -205,29 +256,27 @@ export class WebsqlDriver implements Driver {
|
||||
* Prepares given value to a value to be persisted, based on its column type or metadata.
|
||||
*/
|
||||
prepareHydratedValue(value: any, columnMetadata: ColumnMetadata): any {
|
||||
switch (columnMetadata.type) {
|
||||
case ColumnTypes.BOOLEAN:
|
||||
return value ? true : false;
|
||||
if (columnMetadata.type === Boolean) {
|
||||
return value ? true : false;
|
||||
|
||||
case ColumnTypes.DATETIME:
|
||||
return DataUtils.normalizeHydratedDate(value, columnMetadata.localTimezone === true);
|
||||
} else if (columnMetadata.type === "datetime") {
|
||||
return DataUtils.normalizeHydratedDate(value);
|
||||
|
||||
case ColumnTypes.DATE:
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
} else if (columnMetadata.type === "date") {
|
||||
return DataUtils.mixedDateToDateString(value);
|
||||
|
||||
case ColumnTypes.TIME:
|
||||
return DataUtils.mixedTimeToString(value);
|
||||
} else if (columnMetadata.type === "time") {
|
||||
return DataUtils.mixedTimeToString(value);
|
||||
|
||||
case ColumnTypes.JSON:
|
||||
return JSON.parse(value);
|
||||
} else if (columnMetadata.type === "json") {
|
||||
return JSON.parse(value);
|
||||
|
||||
case ColumnTypes.SIMPLE_ARRAY:
|
||||
return DataUtils.stringToSimpleArray(value);
|
||||
} else if (columnMetadata.type === "simple-array") {
|
||||
return DataUtils.stringToSimpleArray(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -10,8 +10,9 @@ import {TableSchema} from "../../schema-builder/schema/TableSchema";
|
||||
import {ForeignKeySchema} from "../../schema-builder/schema/ForeignKeySchema";
|
||||
import {IndexSchema} from "../../schema-builder/schema/IndexSchema";
|
||||
import {QueryRunnerAlreadyReleasedError} from "../../query-runner/error/QueryRunnerAlreadyReleasedError";
|
||||
import {ColumnType} from "../../metadata/types/ColumnTypes";
|
||||
import {ColumnType} from "../types/ColumnTypes";
|
||||
import {Connection} from "../../connection/Connection";
|
||||
import {ColumnOptions} from "../../decorator/options/ColumnOptions";
|
||||
|
||||
/**
|
||||
* Runs queries on a single websql database connection.
|
||||
@ -740,64 +741,46 @@ export class WebsqlQueryRunner implements QueryRunner {
|
||||
await this.query(sql);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a database type from a given column metadata.
|
||||
*/
|
||||
normalizeType(typeOptions: { type: ColumnType, length?: string|number, precision?: number, scale?: number, timezone?: boolean, fixedLength?: boolean }): string {
|
||||
switch (typeOptions.type) {
|
||||
case "string":
|
||||
return "character varying(" + (typeOptions.length ? typeOptions.length : 255) + ")";
|
||||
case "text":
|
||||
return "text";
|
||||
case "boolean":
|
||||
return "boolean";
|
||||
case "integer":
|
||||
case "int":
|
||||
return "integer";
|
||||
case "smallint":
|
||||
return "smallint";
|
||||
case "bigint":
|
||||
return "bigint";
|
||||
case "float":
|
||||
return "real";
|
||||
case "double":
|
||||
case "number":
|
||||
return "double precision";
|
||||
case "decimal":
|
||||
if (typeOptions.precision && typeOptions.scale) {
|
||||
return `decimal(${typeOptions.precision},${typeOptions.scale})`;
|
||||
normalizeType(column: ColumnMetadata): string {
|
||||
let type = "";
|
||||
if (column.type === Number) {
|
||||
type += "integer";
|
||||
|
||||
} else if (typeOptions.scale) {
|
||||
return `decimal(${typeOptions.scale})`;
|
||||
} else if (column.type === String) {
|
||||
type += "varchar";
|
||||
|
||||
} else if (typeOptions.precision) {
|
||||
return `decimal(${typeOptions.precision})`;
|
||||
} else if (column.type === Date) {
|
||||
type += "datetime";
|
||||
|
||||
} else {
|
||||
return "decimal";
|
||||
} else if (column.type === Boolean) {
|
||||
type += "boolean";
|
||||
|
||||
}
|
||||
case "date":
|
||||
return "date";
|
||||
case "time":
|
||||
if (typeOptions.timezone) {
|
||||
return "time with time zone";
|
||||
} else {
|
||||
return "time without time zone";
|
||||
}
|
||||
case "datetime":
|
||||
if (typeOptions.timezone) {
|
||||
return "timestamp with time zone";
|
||||
} else {
|
||||
return "timestamp without time zone";
|
||||
}
|
||||
case "json":
|
||||
return "json";
|
||||
case "simple_array":
|
||||
return typeOptions.length ? "character varying(" + typeOptions.length + ")" : "text";
|
||||
} else if (column.type === Object) {
|
||||
type += "text";
|
||||
|
||||
} else if (column.type === "simple-array") {
|
||||
type += "text";
|
||||
|
||||
} else {
|
||||
type += column.type;
|
||||
}
|
||||
if (column.length) {
|
||||
type += "(" + column.length + ")";
|
||||
|
||||
throw new DataTypeNotSupportedByDriverError(typeOptions.type, "WebSQL");
|
||||
} else if (column.precision && column.scale) {
|
||||
type += "(" + column.precision + "," + column.scale + ")";
|
||||
|
||||
} else if (column.precision) {
|
||||
type += "(" + column.precision + ")";
|
||||
|
||||
} else if (column.scale) {
|
||||
type += "(" + column.scale + ")";
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {TableType} from "../metadata/types/TableTypes";
|
||||
import {OrderByCondition} from "../find-options/OrderByCondition";
|
||||
import {JoinColumnOptions} from "../decorator/options/JoinColumnOptions";
|
||||
import {ColumnType} from "../metadata/types/ColumnTypes";
|
||||
import {ColumnType} from "../driver/types/ColumnTypes";
|
||||
import {RelationType} from "../metadata/types/RelationTypes";
|
||||
import {JoinTableMultipleColumnsOptions} from "../decorator/options/JoinTableMuplipleColumnsOptions";
|
||||
import {OnDeleteType} from "../metadata/types/OnDeleteType";
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
import {ColumnMetadata} from "../metadata/ColumnMetadata";
|
||||
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
|
||||
import {RelationMetadata} from "../metadata/RelationMetadata";
|
||||
import {IndexMetadata} from "../metadata/IndexMetadata";
|
||||
import {ForeignKeyMetadata} from "../metadata/ForeignKeyMetadata";
|
||||
import {EmbeddedMetadata} from "../metadata/EmbeddedMetadata";
|
||||
import {RelationIdMetadata} from "../metadata/RelationIdMetadata";
|
||||
import {RelationCountMetadata} from "../metadata/RelationCountMetadata";
|
||||
import {OrderByCondition} from "../find-options/OrderByCondition";
|
||||
import {TableType} from "../metadata/types/TableTypes";
|
||||
|
||||
/**
|
||||
* Arguments for EntityMetadata class.
|
||||
*/
|
||||
export interface EntityMetadataArgs {
|
||||
|
||||
readonly junction: boolean;
|
||||
readonly target: Function|string;
|
||||
readonly tablesPrefix?: string;
|
||||
readonly tableName?: string;
|
||||
readonly tableType: TableType;
|
||||
readonly inheritanceType?: "single-table"|"class-table";
|
||||
readonly discriminatorValue?: string;
|
||||
readonly namingStrategy: NamingStrategyInterface;
|
||||
readonly columnMetadatas?: ColumnMetadata[];
|
||||
readonly relationMetadatas?: RelationMetadata[];
|
||||
readonly relationIdMetadatas?: RelationIdMetadata[];
|
||||
readonly relationCountMetadatas?: RelationCountMetadata[];
|
||||
readonly indexMetadatas?: IndexMetadata[];
|
||||
readonly foreignKeyMetadatas?: ForeignKeyMetadata[];
|
||||
readonly embeddedMetadatas?: EmbeddedMetadata[];
|
||||
readonly engine?: string;
|
||||
readonly skipSchemaSync?: boolean;
|
||||
readonly orderBy?: OrderByCondition|((object: any) => OrderByCondition|any);
|
||||
|
||||
}
|
||||
@ -36,6 +36,6 @@ export interface TableMetadataArgs {
|
||||
/**
|
||||
* Whether table must be synced during schema build or not
|
||||
*/
|
||||
skipSchemaSync?: boolean;
|
||||
skipSync?: boolean;
|
||||
|
||||
}
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
import {EntityMetadata} from "../metadata/EntityMetadata";
|
||||
import {ColumnMetadata} from "../metadata/ColumnMetadata";
|
||||
import {ForeignKeyMetadata} from "../metadata/ForeignKeyMetadata";
|
||||
import {ColumnTypes} from "../metadata/types/ColumnTypes";
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {LazyRelationsWrapper} from "../lazy-loading/LazyRelationsWrapper";
|
||||
|
||||
/**
|
||||
* Creates EntityMetadata for junction tables of the closure entities.
|
||||
@ -41,6 +39,7 @@ export class ClosureJunctionEntityMetadataBuilder {
|
||||
// create ancestor and descendant columns for new closure junction table
|
||||
parentClosureEntityMetadata.primaryColumns.forEach(primaryColumn => {
|
||||
entityMetadata.ownColumns.push(new ColumnMetadata({
|
||||
connection: this.connection,
|
||||
entityMetadata: entityMetadata,
|
||||
args: {
|
||||
target: "",
|
||||
@ -53,6 +52,7 @@ export class ClosureJunctionEntityMetadataBuilder {
|
||||
}
|
||||
}));
|
||||
entityMetadata.ownColumns.push(new ColumnMetadata({
|
||||
connection: this.connection,
|
||||
entityMetadata: entityMetadata,
|
||||
args: {
|
||||
target: "",
|
||||
@ -69,13 +69,14 @@ export class ClosureJunctionEntityMetadataBuilder {
|
||||
// if tree level column was defined by a closure entity then add it to the junction columns as well
|
||||
if (parentClosureEntityMetadata.treeLevelColumn) {
|
||||
entityMetadata.ownColumns.push(new ColumnMetadata({
|
||||
connection: this.connection,
|
||||
entityMetadata: entityMetadata,
|
||||
args: {
|
||||
target: "",
|
||||
mode: "virtual",
|
||||
propertyName: "level",
|
||||
options: {
|
||||
type: ColumnTypes.INTEGER,
|
||||
type: this.connection.driver.mappedDataTypes.treeLevel,
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
@ -170,6 +170,7 @@ export class EntityMetadataBuilder {
|
||||
const parentRelationColumns = parentPrimaryColumns.map(parentPrimaryColumn => {
|
||||
const columnName = this.connection.namingStrategy.classTableInheritanceParentColumnName(metadata.parentEntityMetadata.tableName, parentPrimaryColumn.propertyPath);
|
||||
const column = new ColumnMetadata({
|
||||
connection: this.connection,
|
||||
entityMetadata: metadata,
|
||||
referencedColumn: parentPrimaryColumn,
|
||||
args: {
|
||||
@ -265,7 +266,7 @@ export class EntityMetadataBuilder {
|
||||
|
||||
entityMetadata.embeddeds = this.createEmbeddedsRecursively(entityMetadata, this.metadataArgsStorage.filterEmbeddeds(inheritanceTree));
|
||||
entityMetadata.ownColumns = this.metadataArgsStorage.filterColumns(inheritanceTree).map(args => {
|
||||
const column = new ColumnMetadata({ entityMetadata, args });
|
||||
const column = new ColumnMetadata({ connection: this.connection, entityMetadata, args });
|
||||
// console.log(column.propertyName);
|
||||
// if single table inheritance used, we need to mark all inherit table columns as nullable
|
||||
if (singleTableChildrenTargets && singleTableChildrenTargets.indexOf(args.target) !== -1)
|
||||
@ -299,7 +300,7 @@ export class EntityMetadataBuilder {
|
||||
return embeddedArgs.map(embeddedArgs => {
|
||||
const embeddedMetadata = new EmbeddedMetadata({ entityMetadata: entityMetadata, args: embeddedArgs });
|
||||
embeddedMetadata.columns = this.metadataArgsStorage.filterColumns(embeddedMetadata.type).map(args => {
|
||||
return new ColumnMetadata({ entityMetadata, embeddedMetadata, args});
|
||||
return new ColumnMetadata({ connection: this.connection, entityMetadata, embeddedMetadata, args});
|
||||
});
|
||||
embeddedMetadata.relations = this.metadataArgsStorage.filterRelations(embeddedMetadata.type).map(args => {
|
||||
return new RelationMetadata({ entityMetadata, embeddedMetadata, args });
|
||||
|
||||
@ -56,6 +56,7 @@ export class JunctionEntityMetadataBuilder {
|
||||
const columnName = joinColumn && joinColumn.name ? joinColumn.name : this.connection.namingStrategy.joinTableColumnName(relation.entityMetadata.tableNameWithoutPrefix, referencedColumn.propertyName, referencedColumn.databaseName);
|
||||
|
||||
return new ColumnMetadata({
|
||||
connection: this.connection,
|
||||
entityMetadata: entityMetadata,
|
||||
referencedColumn: referencedColumn,
|
||||
args: {
|
||||
@ -82,6 +83,7 @@ export class JunctionEntityMetadataBuilder {
|
||||
const columnName = joinColumn && joinColumn.name ? joinColumn.name : this.connection.namingStrategy.joinTableColumnName(relation.inverseEntityMetadata.tableNameWithoutPrefix, inverseReferencedColumn.propertyName, inverseReferencedColumn.databaseName);
|
||||
|
||||
return new ColumnMetadata({
|
||||
connection: this.connection,
|
||||
entityMetadata: entityMetadata,
|
||||
referencedColumn: inverseReferencedColumn,
|
||||
args: {
|
||||
|
||||
@ -107,6 +107,7 @@ export class RelationJoinColumnBuilder {
|
||||
let relationalColumn = relation.entityMetadata.ownColumns.find(column => column.databaseName === joinColumnName);
|
||||
if (!relationalColumn) {
|
||||
relationalColumn = new ColumnMetadata({
|
||||
connection: this.connection,
|
||||
entityMetadata: relation.entityMetadata,
|
||||
args: {
|
||||
target: "",
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import {ColumnType} from "./types/ColumnTypes";
|
||||
import {ColumnType} from "../driver/types/ColumnTypes";
|
||||
import {EntityMetadata} from "./EntityMetadata";
|
||||
import {EmbeddedMetadata} from "./EmbeddedMetadata";
|
||||
import {RelationMetadata} from "./RelationMetadata";
|
||||
import {ObjectLiteral} from "../common/ObjectLiteral";
|
||||
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
|
||||
import {ColumnMetadataArgs} from "../metadata-args/ColumnMetadataArgs";
|
||||
import {Connection} from "../connection/Connection";
|
||||
|
||||
/**
|
||||
* This metadata contains all information about entity's column.
|
||||
@ -93,24 +94,9 @@ export class ColumnMetadata {
|
||||
scale?: number;
|
||||
|
||||
/**
|
||||
* Indicates if date column will contain a timezone.
|
||||
* Used only for date-typed column types.
|
||||
* Note that timezone option is not supported by all databases (only postgres for now).
|
||||
* Array of possible enumerated values.
|
||||
*/
|
||||
timezone: boolean = false;
|
||||
|
||||
/**
|
||||
* Indicates if date object must be stored in given date's timezone.
|
||||
* By default date is saved in UTC timezone.
|
||||
* Works only with "datetime" columns.
|
||||
*/
|
||||
localTimezone: boolean = false;
|
||||
|
||||
/**
|
||||
* Indicates if column's type will be set as a fixed-length data type.
|
||||
* Works only with "string" columns.
|
||||
*/
|
||||
fixedLength: boolean = false;
|
||||
enum?: any[];
|
||||
|
||||
/**
|
||||
* Gets full path to this column property (including column property name).
|
||||
@ -186,6 +172,7 @@ export class ColumnMetadata {
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
constructor(options: {
|
||||
connection: Connection,
|
||||
entityMetadata: EntityMetadata,
|
||||
embeddedMetadata?: EmbeddedMetadata,
|
||||
referencedColumn?: ColumnMetadata,
|
||||
@ -208,6 +195,8 @@ export class ColumnMetadata {
|
||||
this.isGenerated = options.args.options.generated;
|
||||
if (options.args.options.unique)
|
||||
this.isUnique = options.args.options.unique;
|
||||
if (options.args.options.default === null) // to make sure default: null is the same as nullable: true
|
||||
this.isNullable = true;
|
||||
if (options.args.options.nullable)
|
||||
this.isNullable = options.args.options.nullable;
|
||||
if (options.args.options.comment)
|
||||
@ -218,12 +207,8 @@ export class ColumnMetadata {
|
||||
this.scale = options.args.options.scale;
|
||||
if (options.args.options.precision)
|
||||
this.precision = options.args.options.precision;
|
||||
if (options.args.options.timezone)
|
||||
this.timezone = options.args.options.timezone;
|
||||
if (options.args.options.localTimezone)
|
||||
this.localTimezone = options.args.options.localTimezone;
|
||||
if (options.args.options.fixedLength)
|
||||
this.fixedLength = options.args.options.fixedLength;
|
||||
if (options.args.options.enum)
|
||||
this.enum = options.args.options.enum;
|
||||
if (options.args.mode) {
|
||||
this.isVirtual = options.args.mode === "virtual";
|
||||
this.isParentId = options.args.mode === "parentId";
|
||||
@ -234,6 +219,14 @@ export class ColumnMetadata {
|
||||
this.isVersion = options.args.mode === "version";
|
||||
this.isObjectId = options.args.mode === "objectId";
|
||||
}
|
||||
if (this.isTreeLevel)
|
||||
this.type = options.connection.driver.mappedDataTypes.treeLevel;
|
||||
if (this.isCreateDate)
|
||||
this.type = options.connection.driver.mappedDataTypes.createDate;
|
||||
if (this.isUpdateDate)
|
||||
this.type = options.connection.driver.mappedDataTypes.updateDate;
|
||||
if (this.isVersion)
|
||||
this.type = options.connection.driver.mappedDataTypes.version;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
@ -118,7 +118,7 @@ export class EntityMetadata {
|
||||
/**
|
||||
* Indicates if schema sync is skipped for this entity.
|
||||
*/
|
||||
skipSchemaSync: boolean;
|
||||
skipSync: boolean;
|
||||
|
||||
/**
|
||||
* Table's database engine type (like "InnoDB", "MyISAM", etc).
|
||||
@ -362,7 +362,7 @@ export class EntityMetadata {
|
||||
this.tableType = options.args.type;
|
||||
this.engine = options.args.engine;
|
||||
this.givenTableName = options.args.name;
|
||||
this.skipSchemaSync = options.args.skipSchemaSync || false;
|
||||
this.skipSync = options.args.skipSync || false;
|
||||
this.targetName = options.args.target instanceof Function ? (options.args.target as any).name : options.args.target;
|
||||
this.tableNameWithoutPrefix = this.tableType === "closure-junction" ? namingStrategy.closureJunctionTableName(this.givenTableName!) : namingStrategy.tableName(this.targetName, this.givenTableName);
|
||||
this.tableName = tablesPrefix ? namingStrategy.prefixTableName(tablesPrefix, this.tableNameWithoutPrefix) : this.tableNameWithoutPrefix;
|
||||
|
||||
@ -1,183 +0,0 @@
|
||||
/**
|
||||
* All data types that column can be.
|
||||
*/
|
||||
export type ColumnType = "string"|"text"|"number"|"integer"|"int"|"smallint"|"bigint"|"float"|"double"|
|
||||
"decimal"|"date"|"time"|"datetime"|"boolean"|"json"|"jsonb"|"simple_array"|"uuid";
|
||||
|
||||
/**
|
||||
* All data types that column can be.
|
||||
*/
|
||||
export class ColumnTypes {
|
||||
|
||||
/**
|
||||
* SQL VARCHAR type. Your class's property type should be a "string".
|
||||
*/
|
||||
static STRING: ColumnType = "string";
|
||||
|
||||
/**
|
||||
* 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";
|
||||
|
||||
/**
|
||||
* Postgres jsonb type. Your class's property type should be any Object.
|
||||
*/
|
||||
static JSONB: ColumnType = "jsonb";
|
||||
|
||||
/**
|
||||
* 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";
|
||||
|
||||
/**
|
||||
* UUID type. Serialized to a string in typescript or javascript
|
||||
*/
|
||||
static UUID: ColumnType = "uuid";
|
||||
|
||||
/**
|
||||
* Checks if given type in a string format is supported by ORM.
|
||||
*/
|
||||
static isTypeSupported(type: string) {
|
||||
return this.supportedTypes.indexOf(<ColumnType> 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.JSONB,
|
||||
this.SIMPLE_ARRAY,
|
||||
this.UUID
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to guess a column type from the given function.
|
||||
*/
|
||||
static determineTypeFromFunction(type: Function): ColumnType|undefined {
|
||||
if (type instanceof Date) {
|
||||
return ColumnTypes.DATETIME;
|
||||
|
||||
} 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;
|
||||
case "date":
|
||||
return ColumnTypes.DATETIME;
|
||||
case "object":
|
||||
return ColumnTypes.JSON;
|
||||
}
|
||||
|
||||
} else if (type instanceof Object) {
|
||||
return ColumnTypes.JSON;
|
||||
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
static typeToString(type: Function): string {
|
||||
return (type as any).name.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if column type is numeric.
|
||||
*/
|
||||
static isNumeric(type: ColumnType) {
|
||||
return type === ColumnTypes.NUMBER ||
|
||||
type === ColumnTypes.INT ||
|
||||
type === ColumnTypes.INTEGER ||
|
||||
type === ColumnTypes.BIGINT ||
|
||||
type === ColumnTypes.SMALLINT ||
|
||||
type === ColumnTypes.DOUBLE ||
|
||||
type === ColumnTypes.FLOAT;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +1,5 @@
|
||||
import {TableSchema} from "../schema-builder/schema/TableSchema";
|
||||
import {ColumnSchema} from "../schema-builder/schema/ColumnSchema";
|
||||
import {ColumnTypes} from "../metadata/types/ColumnTypes";
|
||||
import {QueryBuilder} from "../query-builder/QueryBuilder";
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {QueryRunnerProvider} from "../query-runner/QueryRunnerProvider";
|
||||
import {Migration} from "./Migration";
|
||||
@ -186,17 +184,13 @@ export class MigrationExecutor {
|
||||
await queryRunner.createTable(new TableSchema("migrations", [
|
||||
new ColumnSchema({
|
||||
name: "timestamp",
|
||||
type: queryRunner.normalizeType({
|
||||
type: ColumnTypes.NUMBER
|
||||
}),
|
||||
type: this.connection.driver.mappedDataTypes.migrationTimestamp as string,
|
||||
isPrimary: true,
|
||||
isNullable: false
|
||||
}),
|
||||
new ColumnSchema({
|
||||
name: "name",
|
||||
type: queryRunner.normalizeType({
|
||||
type: ColumnTypes.STRING
|
||||
}),
|
||||
type: this.connection.driver.mappedDataTypes.migrationName as string,
|
||||
isNullable: false
|
||||
}),
|
||||
]));
|
||||
|
||||
@ -2,7 +2,6 @@ import {ObjectLiteral} from "../common/ObjectLiteral";
|
||||
import {EntityMetadata} from "../metadata/EntityMetadata";
|
||||
import {ColumnMetadata} from "../metadata/ColumnMetadata";
|
||||
import {RelationMetadata} from "../metadata/RelationMetadata";
|
||||
import {ColumnTypes} from "../metadata/types/ColumnTypes";
|
||||
import {DataUtils} from "../util/DataUtils";
|
||||
|
||||
/**
|
||||
@ -324,29 +323,24 @@ export class Subject {
|
||||
if (entityValue === undefined)
|
||||
return false;
|
||||
|
||||
// normalize special values to make proper comparision
|
||||
// normalize special values to make proper comparision (todo: arent they already normalized at this point?!)
|
||||
if (entityValue !== null && entityValue !== undefined) {
|
||||
if (column.type === ColumnTypes.DATE) {
|
||||
if (column.type === "date") {
|
||||
entityValue = DataUtils.mixedDateToDateString(entityValue);
|
||||
|
||||
} else if (column.type === ColumnTypes.TIME) {
|
||||
} else if (column.type === "time") {
|
||||
entityValue = DataUtils.mixedDateToTimeString(entityValue);
|
||||
|
||||
} else if (column.type === ColumnTypes.DATETIME) {
|
||||
// if (column.loadInLocalTimezone) {
|
||||
// entityValue = DataTransformationUtils.mixedDateToDatetimeString(entityValue);
|
||||
// databaseValue = DataTransformationUtils.mixedDateToDatetimeString(databaseValue);
|
||||
// } else {
|
||||
entityValue = DataUtils.mixedDateToUtcDatetimeString(entityValue);
|
||||
databaseValue = DataUtils.mixedDateToUtcDatetimeString(databaseValue);
|
||||
// }
|
||||
} else if (column.type === "datetime" || column.type === Date) {
|
||||
entityValue = DataUtils.mixedDateToUtcDatetimeString(entityValue);
|
||||
databaseValue = DataUtils.mixedDateToUtcDatetimeString(databaseValue);
|
||||
|
||||
} else if (column.type === ColumnTypes.JSON) {
|
||||
} else if (column.type === "json" || column.type === "jsonb" || column.type === Object) {
|
||||
entityValue = JSON.stringify(entityValue);
|
||||
if (databaseValue !== null && databaseValue !== undefined)
|
||||
databaseValue = JSON.stringify(databaseValue);
|
||||
|
||||
} else if (column.type === ColumnTypes.SIMPLE_ARRAY) {
|
||||
} else if (column.type === "sample-array") {
|
||||
entityValue = DataUtils.simpleArrayToString(entityValue);
|
||||
databaseValue = DataUtils.simpleArrayToString(databaseValue);
|
||||
}
|
||||
|
||||
@ -3,7 +3,8 @@ import {ColumnMetadata} from "../metadata/ColumnMetadata";
|
||||
import {TableSchema} from "../schema-builder/schema/TableSchema";
|
||||
import {ForeignKeySchema} from "../schema-builder/schema/ForeignKeySchema";
|
||||
import {IndexSchema} from "../schema-builder/schema/IndexSchema";
|
||||
import {ColumnType} from "../metadata/types/ColumnTypes";
|
||||
import {ColumnType} from "../driver/types/ColumnTypes";
|
||||
import {ColumnOptions} from "../decorator/options/ColumnOptions";
|
||||
|
||||
/**
|
||||
* Runs queries on a single database connection.
|
||||
@ -78,8 +79,10 @@ export interface QueryRunner {
|
||||
|
||||
/**
|
||||
* Converts a column type of the metadata to the database column's type.
|
||||
*
|
||||
* todo: move to driver?
|
||||
*/
|
||||
normalizeType(typeOptions: { type: ColumnType, length?: string|number, precision?: number, scale?: number, timezone?: boolean, fixedLength?: boolean }): string;
|
||||
normalizeType(column: ColumnMetadata): string;
|
||||
|
||||
/**
|
||||
* Checks if "DEFAULT" values in the column metadata and in the database schema are equal.
|
||||
|
||||
@ -88,7 +88,7 @@ export class SchemaBuilder {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
protected get entityToSyncMetadatas(): EntityMetadata[] {
|
||||
return this.connection.entityMetadatas.filter(metadata => !metadata.skipSchemaSync && metadata.tableType !== "single-table-child");
|
||||
return this.connection.entityMetadatas.filter(metadata => !metadata.skipSync && metadata.tableType !== "single-table-child");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -10,22 +10,22 @@ export class DataUtils {
|
||||
/**
|
||||
* Normalizes date object hydrated from the database.
|
||||
*/
|
||||
static normalizeHydratedDate(mixedDate: Date|string|undefined, storedInLocal: boolean): Date|string|undefined {
|
||||
static normalizeHydratedDate(mixedDate: Date|string|undefined): Date|string|undefined {
|
||||
if (!mixedDate)
|
||||
return mixedDate;
|
||||
|
||||
const date = typeof mixedDate === "string" ? new Date(mixedDate) : mixedDate as Date;
|
||||
if (!storedInLocal) {
|
||||
// if (!storedInLocal) {
|
||||
|
||||
// else if it was not stored in local timezone, means it was stored in UTC
|
||||
// because driver hydrates it with timezone applied why we need to add timezone hours to match a local timezone
|
||||
// else if it was not stored in local timezone, means it was stored in UTC
|
||||
// because driver hydrates it with timezone applied why we need to add timezone hours to match a local timezone
|
||||
|
||||
const correctedDate = new Date();
|
||||
correctedDate.setUTCFullYear(date.getFullYear(), date.getMonth(), date.getDate());
|
||||
correctedDate.setUTCHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
|
||||
return correctedDate;
|
||||
}
|
||||
return date;
|
||||
const correctedDate = new Date();
|
||||
correctedDate.setUTCFullYear(date.getFullYear(), date.getMonth(), date.getDate());
|
||||
correctedDate.setUTCHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
|
||||
return correctedDate;
|
||||
// }
|
||||
// return date;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -213,7 +213,7 @@ describe("Connection", () => {
|
||||
|
||||
});
|
||||
|
||||
describe("skip schema generation when skipSchemaSync option is used", function() {
|
||||
describe("skip schema generation when skipSync option is used", function() {
|
||||
|
||||
let connections: Connection[];
|
||||
beforeEach(() => createTestingConnections({ entities: [View], dropSchemaOnConnection: true }).then(all => connections = all));
|
||||
|
||||
@ -2,7 +2,7 @@ import {Entity} from "../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryColumn} from "../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Column} from "../../../../src/decorator/columns/Column";
|
||||
|
||||
@Entity("view", {skipSchemaSync: true})
|
||||
@Entity("view", {skipSync: true})
|
||||
export class View {
|
||||
|
||||
@PrimaryColumn()
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
"generated": true
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
"generated": true
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
"generated": true
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,11 +10,11 @@
|
||||
"generated": true
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,11 +10,11 @@
|
||||
"generated": true
|
||||
},
|
||||
"firstName": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
},
|
||||
"secondName": {
|
||||
"type": "string",
|
||||
"type": "varchar",
|
||||
"nullable": false
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
import "reflect-metadata";
|
||||
import {expect} from "chai";
|
||||
import {Post} from "./entity/Post";
|
||||
import {Connection} from "../../../../../src/connection/Connection";
|
||||
import {closeTestingConnections, createTestingConnections} from "../../../../utils/test-utils";
|
||||
|
||||
// todo: finish those tests
|
||||
|
||||
describe.skip("database schema > column types > mysql", () => {
|
||||
|
||||
let connections: Connection[];
|
||||
before(async () => {
|
||||
connections = await createTestingConnections({
|
||||
entities: [Post],
|
||||
enabledDrivers: ["mysql"]
|
||||
});
|
||||
});
|
||||
// beforeEach(() => reloadTestingDatabases(connections));
|
||||
after(() => closeTestingConnections(connections));
|
||||
|
||||
it("all types should work correctly - persist and hydrate", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post();
|
||||
})));
|
||||
|
||||
});
|
||||
@ -0,0 +1,86 @@
|
||||
import {Entity} from "../../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryColumn} from "../../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Column} from "../../../../../../src/decorator/columns/Column";
|
||||
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@PrimaryColumn()
|
||||
id: string;
|
||||
|
||||
@Column()
|
||||
name: string;
|
||||
|
||||
@Column("int")
|
||||
int: number;
|
||||
|
||||
@Column("tinyint")
|
||||
tinyint: number;
|
||||
|
||||
@Column("smallint")
|
||||
smallint: number;
|
||||
|
||||
@Column("mediumint")
|
||||
mediumint: number;
|
||||
|
||||
@Column("bigint")
|
||||
bigint: number;
|
||||
|
||||
@Column("float")
|
||||
float: number;
|
||||
|
||||
@Column("double")
|
||||
double: number;
|
||||
|
||||
@Column("decimal")
|
||||
decimal: number;
|
||||
|
||||
@Column("date")
|
||||
date: string;
|
||||
|
||||
@Column("datetime")
|
||||
datetime: Date;
|
||||
|
||||
@Column("timestamp")
|
||||
timestamp: number;
|
||||
|
||||
@Column("time")
|
||||
time: string;
|
||||
|
||||
@Column("year")
|
||||
year: number;
|
||||
|
||||
@Column("char")
|
||||
char: string;
|
||||
|
||||
@Column("varchar")
|
||||
varchar: string;
|
||||
|
||||
@Column("blob")
|
||||
blob: string;
|
||||
|
||||
@Column("text")
|
||||
text: string;
|
||||
|
||||
@Column("tinyblob")
|
||||
tinyblob: string;
|
||||
|
||||
@Column("tinytext")
|
||||
tinytext: string;
|
||||
|
||||
@Column("mediumblob")
|
||||
mediumblob: string;
|
||||
|
||||
@Column("mediumtext")
|
||||
mediumtext: string;
|
||||
|
||||
@Column("longblob")
|
||||
longblob: string;
|
||||
|
||||
@Column("longtext")
|
||||
longtext: string;
|
||||
|
||||
@Column("enum")
|
||||
enum: string[];
|
||||
|
||||
}
|
||||
@ -16,7 +16,7 @@ export class Post {
|
||||
@Column()
|
||||
text: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -16,7 +16,7 @@ export class Post {
|
||||
@Column()
|
||||
text: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -19,7 +19,7 @@ export class Counters {
|
||||
@Column()
|
||||
favorites: number;
|
||||
|
||||
@Embedded(() => Subcounters)
|
||||
@Column(() => Subcounters)
|
||||
subcounters: Subcounters;
|
||||
|
||||
@ManyToMany(type => User, user => user.likedPosts)
|
||||
|
||||
@ -13,7 +13,7 @@ export class Post {
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -18,7 +18,7 @@ export class Counters {
|
||||
@Column()
|
||||
favorites: number;
|
||||
|
||||
@Embedded(() => Subcounters)
|
||||
@Column(() => Subcounters)
|
||||
subcounters: Subcounters;
|
||||
|
||||
@ManyToMany(type => User, user => user.likedPosts)
|
||||
|
||||
@ -13,7 +13,7 @@ export class Post {
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -20,7 +20,7 @@ export class Counters {
|
||||
@Column()
|
||||
favorites: number;
|
||||
|
||||
@Embedded(() => Subcounters)
|
||||
@Column(() => Subcounters)
|
||||
subcounters: Subcounters;
|
||||
|
||||
@ManyToMany(type => User, user => user.likedPosts)
|
||||
|
||||
@ -15,7 +15,7 @@ export class Post {
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -19,7 +19,7 @@ export class Counters {
|
||||
@Column()
|
||||
favorites: number;
|
||||
|
||||
@Embedded(() => Subcounters)
|
||||
@Column(() => Subcounters)
|
||||
subcounters: Subcounters;
|
||||
|
||||
@ManyToMany(type => User, user => user.likedPosts)
|
||||
|
||||
@ -13,7 +13,7 @@ export class Post {
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -20,7 +20,7 @@ export class Counters {
|
||||
@Column()
|
||||
favorites: number;
|
||||
|
||||
@Embedded(() => Subcounters)
|
||||
@Column(() => Subcounters)
|
||||
subcounters: Subcounters;
|
||||
|
||||
@ManyToMany(type => User, user => user.likedPosts)
|
||||
|
||||
@ -15,7 +15,7 @@ export class Post {
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ export class Counters {
|
||||
@Column()
|
||||
favorites: number;
|
||||
|
||||
@Embedded(() => Subcounters)
|
||||
@Column(() => Subcounters)
|
||||
subcounters: Subcounters;
|
||||
|
||||
@ManyToOne(type => User)
|
||||
|
||||
@ -13,7 +13,7 @@ export class Post {
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -18,7 +18,7 @@ export class Counters {
|
||||
@Column()
|
||||
favorites: number;
|
||||
|
||||
@Embedded(() => Subcounters)
|
||||
@Column(() => Subcounters)
|
||||
subcounters: Subcounters;
|
||||
|
||||
@OneToMany(type => User, user => user.likedPost)
|
||||
|
||||
@ -13,7 +13,7 @@ export class Post {
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -20,7 +20,7 @@ export class Counters {
|
||||
@Column()
|
||||
favorites: number;
|
||||
|
||||
@Embedded(() => Subcounters)
|
||||
@Column(() => Subcounters)
|
||||
subcounters: Subcounters;
|
||||
|
||||
@ManyToOne(type => User)
|
||||
|
||||
@ -15,7 +15,7 @@ export class Post {
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -19,7 +19,7 @@ export class Counters {
|
||||
@Column()
|
||||
favorites: number;
|
||||
|
||||
@Embedded(() => Subcounters)
|
||||
@Column(() => Subcounters)
|
||||
subcounters: Subcounters;
|
||||
|
||||
@ManyToOne(type => User)
|
||||
|
||||
@ -13,7 +13,7 @@ export class Post {
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -20,7 +20,7 @@ export class Counters {
|
||||
@Column()
|
||||
favorites: number;
|
||||
|
||||
@Embedded(() => Subcounters)
|
||||
@Column(() => Subcounters)
|
||||
subcounters: Subcounters;
|
||||
|
||||
@ManyToOne(type => User)
|
||||
|
||||
@ -15,7 +15,7 @@ export class Post {
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -19,7 +19,7 @@ export class Counters {
|
||||
@Column()
|
||||
favorites: number;
|
||||
|
||||
@Embedded(() => Subcounters)
|
||||
@Column(() => Subcounters)
|
||||
subcounters: Subcounters;
|
||||
|
||||
@OneToOne(type => User)
|
||||
|
||||
@ -13,7 +13,7 @@ export class Post {
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
@ -15,7 +15,7 @@ export class Counters {
|
||||
@Column()
|
||||
favorites: number;
|
||||
|
||||
@Embedded(() => Subcounters)
|
||||
@Column(() => Subcounters)
|
||||
subcounters: Subcounters;
|
||||
|
||||
@CreateDateColumn()
|
||||
|
||||
@ -13,7 +13,7 @@ export class Post {
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Embedded(() => Counters)
|
||||
@Column(() => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user