mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
fixes #495
This commit is contained in:
parent
eb51cb3ef3
commit
95eff0746c
@ -19,7 +19,6 @@ export function PrimaryGeneratedColumn(options?: ColumnOptions): Function {
|
||||
if (!options) options = {} as ColumnOptions;
|
||||
|
||||
// check if there is no type in column options then set the int type - by default for auto generated column
|
||||
if (!options.type)
|
||||
options = Object.assign({type: "int"} as ColumnOptions, options);
|
||||
|
||||
// check if column is not nullable, because we cannot allow a primary key to be nullable
|
||||
|
||||
@ -8,36 +8,36 @@ export interface ColumnOptions {
|
||||
/**
|
||||
* Column type. Must be one of the value from the ColumnTypes class.
|
||||
*/
|
||||
readonly type?: ColumnType;
|
||||
type?: ColumnType;
|
||||
|
||||
/**
|
||||
* Column name in the database.
|
||||
*/
|
||||
readonly name?: string;
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* Column type's length. Used only on some column types.
|
||||
* For example type = "string" and length = "100" means that ORM will create a column with type varchar(100).
|
||||
*/
|
||||
readonly length?: string|number;
|
||||
length?: string|number;
|
||||
|
||||
/**
|
||||
* Indicates if this column is PRIMARY.
|
||||
* Same can be achieved if @PrimaryColumn decorator will be used.
|
||||
*/
|
||||
readonly primary?: boolean;
|
||||
primary?: boolean;
|
||||
|
||||
/**
|
||||
* Specifies if this column will use auto increment (sequence, generated identity).
|
||||
* Note that only one column in entity can be marked as generated, and it must be a primary column.
|
||||
* (todo: create validation logic for this condition)
|
||||
*/
|
||||
readonly generated?: boolean;
|
||||
generated?: boolean; // |"uuid"|"sequence";
|
||||
|
||||
/**
|
||||
* Specifies if column's value must be unique or not.
|
||||
*/
|
||||
readonly unique?: boolean;
|
||||
unique?: boolean;
|
||||
|
||||
/**
|
||||
* Indicates if column's value can be set to NULL.
|
||||
@ -47,43 +47,43 @@ export interface ColumnOptions {
|
||||
/**
|
||||
* Column comment.
|
||||
*/
|
||||
readonly comment?: string;
|
||||
comment?: string;
|
||||
|
||||
/**
|
||||
* Default database value.
|
||||
*/
|
||||
readonly default?: any;
|
||||
default?: any;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
readonly precision?: number;
|
||||
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.
|
||||
*/
|
||||
readonly scale?: number;
|
||||
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).
|
||||
*/
|
||||
readonly timezone?: boolean;
|
||||
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.
|
||||
*/
|
||||
readonly localTimezone?: boolean;
|
||||
localTimezone?: boolean;
|
||||
|
||||
/**
|
||||
* Indicates if column's type will be set as a fixed-length data type.
|
||||
* Works only with "string" columns.
|
||||
*/
|
||||
readonly fixedLength?: boolean;
|
||||
fixedLength?: boolean;
|
||||
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ export interface EntityOptions {
|
||||
/**
|
||||
* Specifies a default order by used for queries from this table when no explicit order by is specified.
|
||||
*/
|
||||
readonly orderBy?: OrderByCondition|((object: any) => OrderByCondition|any);
|
||||
orderBy?: OrderByCondition|((object: any) => OrderByCondition|any);
|
||||
|
||||
/**
|
||||
* Table's database engine type (like "InnoDB", "MyISAM", etc).
|
||||
@ -16,11 +16,11 @@ export interface EntityOptions {
|
||||
* If you update this value and table is already created, it will not change table's engine type.
|
||||
* Note that not all databases support this option.
|
||||
*/
|
||||
readonly engine?: string;
|
||||
engine?: string;
|
||||
|
||||
/**
|
||||
* Specifies if this table will be skipped during schema synchronization.
|
||||
*/
|
||||
readonly skipSchemaSync?: boolean;
|
||||
skipSchemaSync?: boolean;
|
||||
|
||||
}
|
||||
|
||||
@ -6,13 +6,13 @@ export interface IndexOptions {
|
||||
/**
|
||||
* Indicates if this composite index must be unique or not.
|
||||
*/
|
||||
readonly unique?: boolean;
|
||||
unique?: boolean;
|
||||
|
||||
/**
|
||||
* If true, the index only references documents with the specified field.
|
||||
* These indexes use less space but behave differently in some situations (particularly sorts).
|
||||
* This option is only supported for mongodb database.
|
||||
*/
|
||||
readonly sparse?: boolean;
|
||||
sparse?: boolean;
|
||||
|
||||
}
|
||||
@ -6,11 +6,11 @@ export interface JoinColumnOptions {
|
||||
/**
|
||||
* Name of the column.
|
||||
*/
|
||||
readonly name?: string;
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* Name of the column in the entity to which this column is referenced.
|
||||
*/
|
||||
readonly referencedColumnName?: string; // TODO rename to referencedColumn
|
||||
referencedColumnName?: string; // TODO rename to referencedColumn
|
||||
|
||||
}
|
||||
@ -9,16 +9,16 @@ export interface JoinTableMultipleColumnsOptions {
|
||||
* Name of the table that will be created to store values of the both tables (join table).
|
||||
* By default is auto generated.
|
||||
*/
|
||||
readonly name?: string;
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* First column of the join table.
|
||||
*/
|
||||
readonly joinColumns?: JoinColumnOptions[];
|
||||
joinColumns?: JoinColumnOptions[];
|
||||
|
||||
/**
|
||||
* Second (inverse) column of the join table.
|
||||
*/
|
||||
readonly inverseJoinColumns?: JoinColumnOptions[];
|
||||
inverseJoinColumns?: JoinColumnOptions[];
|
||||
|
||||
}
|
||||
@ -9,16 +9,16 @@ export interface JoinTableOptions {
|
||||
* Name of the table that will be created to store values of the both tables (join table).
|
||||
* By default is auto generated.
|
||||
*/
|
||||
readonly name?: string;
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* First column of the join table.
|
||||
*/
|
||||
readonly joinColumn?: JoinColumnOptions;
|
||||
joinColumn?: JoinColumnOptions;
|
||||
|
||||
/**
|
||||
* Second (inverse) column of the join table.
|
||||
*/
|
||||
readonly inverseJoinColumn?: JoinColumnOptions;
|
||||
inverseJoinColumn?: JoinColumnOptions;
|
||||
|
||||
}
|
||||
@ -11,43 +11,43 @@ export interface RelationOptions {
|
||||
* If set to true then it means that related object can be allowed to be inserted / updated / removed to the db.
|
||||
* This is option a shortcut if you would like to set cascadeInsert, cascadeUpdate and cascadeRemove to true.
|
||||
*/
|
||||
readonly cascadeAll?: boolean;
|
||||
cascadeAll?: boolean;
|
||||
|
||||
/**
|
||||
* If set to true then it means that related object can be allowed to be inserted to the db.
|
||||
*/
|
||||
readonly cascadeInsert?: boolean;
|
||||
cascadeInsert?: boolean;
|
||||
|
||||
/**
|
||||
* If set to true then it means that related object can be allowed to be updated in the db.
|
||||
*/
|
||||
readonly cascadeUpdate?: boolean;
|
||||
cascadeUpdate?: boolean;
|
||||
|
||||
/**
|
||||
* If set to true then it means that related object can be allowed to be remove from the db.
|
||||
*/
|
||||
readonly cascadeRemove?: boolean;
|
||||
cascadeRemove?: boolean;
|
||||
|
||||
/**
|
||||
* Indicates if relation column value can be nullable or not.
|
||||
*/
|
||||
readonly nullable?: boolean;
|
||||
nullable?: boolean;
|
||||
|
||||
/**
|
||||
* Database cascade action on delete.
|
||||
*/
|
||||
readonly onDelete?: OnDeleteType;
|
||||
onDelete?: OnDeleteType;
|
||||
|
||||
/**
|
||||
* Indicates if this relation will be a primary key.
|
||||
* Can be used only for many-to-one and owner one-to-one relations.
|
||||
*/
|
||||
readonly primary?: boolean;
|
||||
primary?: boolean;
|
||||
|
||||
/**
|
||||
* Set this relation to be lazy. Note: lazy relations are promises. When you call them they return promise
|
||||
* which resolve relation result then. If your property's type is Promise then this relation is set to lazy automatically.
|
||||
*/
|
||||
readonly lazy?: boolean;
|
||||
lazy?: boolean;
|
||||
|
||||
}
|
||||
@ -415,7 +415,7 @@ export class ColumnMetadata {
|
||||
if (this.embeddedMetadata && this.embeddedMetadata.parentPropertyNames.length)
|
||||
path = this.embeddedMetadata.parentPropertyNames.join(".") + ".";
|
||||
|
||||
if (this.referencedColumn)
|
||||
if (this.referencedColumn && this.referencedColumn.propertyName !== this.propertyName)
|
||||
path += this.referencedColumn.propertyName + ".";
|
||||
|
||||
return path + this.propertyName;
|
||||
|
||||
@ -112,7 +112,10 @@ export class IndexMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
// console.log("columnPropertyNames:", columnPropertyNames);
|
||||
// console.log("this.entityMetadata.columns:", this.entityMetadata.columns);
|
||||
const columns = this.entityMetadata.columns.filter(column => columnPropertyNames.indexOf(column.propertyPath) !== -1);
|
||||
// console.log("columns:", columns);
|
||||
this.entityMetadata.relations
|
||||
.filter(relation => relation.isWithJoinColumn && columnPropertyNames.indexOf(relation.propertyName) !== -1)
|
||||
.forEach(relation => columns.push(...relation.joinColumns));
|
||||
|
||||
26
test/github-issues/495/entity/Item.ts
Normal file
26
test/github-issues/495/entity/Item.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import {Entity} from "../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../src/decorator/columns/Column";
|
||||
import {Index} from "../../../../src/decorator/Index";
|
||||
import {OneToOne} from "../../../../src/decorator/relations/OneToOne";
|
||||
import {JoinColumn} from "../../../../src/decorator/relations/JoinColumn";
|
||||
import {User} from "./User";
|
||||
|
||||
@Entity()
|
||||
@Index("table_index_userId_mid", (post: Item) => [post.userId, post.mid])
|
||||
export class Item {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
postId: number;
|
||||
|
||||
@OneToOne(type => User, users => users.userId)
|
||||
@JoinColumn({ name: "userId" })
|
||||
userData: User;
|
||||
|
||||
@Column({ type: "int"})
|
||||
userId: number;
|
||||
|
||||
@Column({ type: "int" })
|
||||
mid: number;
|
||||
|
||||
}
|
||||
14
test/github-issues/495/entity/User.ts
Normal file
14
test/github-issues/495/entity/User.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import {Entity} from "../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../src/decorator/columns/Column";
|
||||
|
||||
@Entity()
|
||||
export class User {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
userId: number;
|
||||
|
||||
@Column()
|
||||
name: string;
|
||||
|
||||
}
|
||||
31
test/github-issues/495/issue-495.ts
Normal file
31
test/github-issues/495/issue-495.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import "reflect-metadata";
|
||||
import {createTestingConnections, closeTestingConnections, reloadTestingDatabases} from "../../utils/test-utils";
|
||||
import {Connection} from "../../../src/connection/Connection";
|
||||
import {Item} from "./entity/Item";
|
||||
import {User} from "./entity/User";
|
||||
|
||||
describe("github issues > #495 Unable to set multi-column indices", () => {
|
||||
|
||||
let connections: Connection[];
|
||||
before(async () => connections = await createTestingConnections({
|
||||
entities: [__dirname + "/entity/*{.js,.ts}"],
|
||||
schemaCreate: true,
|
||||
dropSchemaOnConnection: true,
|
||||
}));
|
||||
beforeEach(() => reloadTestingDatabases(connections));
|
||||
after(() => closeTestingConnections(connections));
|
||||
|
||||
it("should successfully create indices and save an object", () => Promise.all(connections.map(async connection => {
|
||||
|
||||
const user = new User();
|
||||
user.name = "stonecold";
|
||||
|
||||
const item = new Item();
|
||||
item.userData = user;
|
||||
item.mid = 1;
|
||||
|
||||
await connection.manager.save(user);
|
||||
await connection.manager.save(item);
|
||||
})));
|
||||
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user