mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
removed table metadata
This commit is contained in:
parent
77b177e0ab
commit
d401b4f3ed
@ -225,7 +225,7 @@ export class MongoDriver implements Driver {
|
||||
metadata.indices.forEach(index => {
|
||||
const columns = index.buildColumnsAsMap(1);
|
||||
const options = { name: index.name };
|
||||
promises.push(queryRunner.createCollectionIndex(metadata.table.name, columns, options));
|
||||
promises.push(queryRunner.createCollectionIndex(metadata.tableName, columns, options));
|
||||
});
|
||||
}));
|
||||
await Promise.all(promises);
|
||||
|
||||
@ -94,7 +94,7 @@ export class LazyRelationsWrapper {
|
||||
} else { // ManyToMany
|
||||
|
||||
const mainAlias = relation.propertyName;
|
||||
const joinAlias = relation.junctionEntityMetadata.table.name;
|
||||
const joinAlias = relation.junctionEntityMetadata.tableName;
|
||||
let joinColumnConditions: string[] = [];
|
||||
let inverseJoinColumnConditions: string[] = [];
|
||||
let parameters: ObjectLiteral;
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import {ColumnMetadata} from "../metadata/ColumnMetadata";
|
||||
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
|
||||
import {TableMetadata} from "../metadata/TableMetadata";
|
||||
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.
|
||||
@ -16,10 +17,11 @@ 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 tableMetadata: TableMetadata;
|
||||
readonly columnMetadatas?: ColumnMetadata[];
|
||||
readonly relationMetadatas?: RelationMetadata[];
|
||||
readonly relationIdMetadatas?: RelationIdMetadata[];
|
||||
@ -27,5 +29,8 @@ export interface EntityMetadataArgs {
|
||||
readonly indexMetadatas?: IndexMetadata[];
|
||||
readonly foreignKeyMetadatas?: ForeignKeyMetadata[];
|
||||
readonly embeddedMetadatas?: EmbeddedMetadata[];
|
||||
readonly engine?: string;
|
||||
readonly skipSchemaSync?: boolean;
|
||||
readonly orderBy?: OrderByCondition|((object: any) => OrderByCondition|any);
|
||||
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterfac
|
||||
import {ColumnMetadata} from "../metadata/ColumnMetadata";
|
||||
import {ColumnOptions} from "../decorator/options/ColumnOptions";
|
||||
import {ForeignKeyMetadata} from "../metadata/ForeignKeyMetadata";
|
||||
import {TableMetadata} from "../metadata/TableMetadata";
|
||||
import {ColumnMetadataArgs} from "../metadata-args/ColumnMetadataArgs";
|
||||
import {ColumnTypes} from "../metadata/types/ColumnTypes";
|
||||
import {LazyRelationsWrapper} from "../lazy-loading/LazyRelationsWrapper";
|
||||
@ -14,7 +13,7 @@ import {Driver} from "../driver/Driver";
|
||||
*/
|
||||
export interface ClosureJunctionEntityMetadataBuilderArgs {
|
||||
namingStrategy: NamingStrategyInterface;
|
||||
table: TableMetadata;
|
||||
entityMetadata: EntityMetadata;
|
||||
primaryColumn: ColumnMetadata;
|
||||
hasTreeLevelColumn: boolean;
|
||||
}
|
||||
@ -64,22 +63,17 @@ export class ClosureJunctionEntityMetadataBuilder {
|
||||
}));
|
||||
}
|
||||
|
||||
const closureJunctionTableMetadata = new TableMetadata({
|
||||
target: "__virtual__",
|
||||
name: args.table.name,
|
||||
type: "closure-junction"
|
||||
});
|
||||
|
||||
return new EntityMetadata({
|
||||
junction: true,
|
||||
target: "__virtual__",
|
||||
tablesPrefix: driver.options.tablesPrefix,
|
||||
namingStrategy: args.namingStrategy,
|
||||
tableMetadata: closureJunctionTableMetadata,
|
||||
tableName: args.entityMetadata.tableName,
|
||||
tableType: "closure-junction",
|
||||
columnMetadatas: columns,
|
||||
foreignKeyMetadatas: [
|
||||
new ForeignKeyMetadata([columns[0]], args.table, [args.primaryColumn]),
|
||||
new ForeignKeyMetadata([columns[1]], args.table, [args.primaryColumn])
|
||||
new ForeignKeyMetadata([columns[0]], args.entityMetadata, [args.primaryColumn]),
|
||||
new ForeignKeyMetadata([columns[1]], args.entityMetadata, [args.primaryColumn])
|
||||
]
|
||||
}, lazyRelationsWrapper);
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import {ColumnOptions} from "../decorator/options/ColumnOptions";
|
||||
import {ForeignKeyMetadata} from "../metadata/ForeignKeyMetadata";
|
||||
import {EntityMetadataValidator} from "./EntityMetadataValidator";
|
||||
import {IndexMetadata} from "../metadata/IndexMetadata";
|
||||
import {TableMetadata} from "../metadata/TableMetadata";
|
||||
import {RelationMetadata} from "../metadata/RelationMetadata";
|
||||
import {ClosureJunctionEntityMetadataBuilder} from "./ClosureJunctionEntityMetadataBuilder";
|
||||
import {EmbeddedMetadata} from "../metadata/EmbeddedMetadata";
|
||||
@ -37,10 +36,10 @@ export class EntityMetadataBuilder {
|
||||
* Builds a complete metadata aggregations for the given entity classes.
|
||||
*/
|
||||
build(driver: Driver,
|
||||
lazyRelationsWrapper: LazyRelationsWrapper,
|
||||
metadataArgsStorage: MetadataArgsStorage,
|
||||
namingStrategy: NamingStrategyInterface,
|
||||
entityClasses?: Function[]): EntityMetadata[] {
|
||||
lazyRelationsWrapper: LazyRelationsWrapper,
|
||||
metadataArgsStorage: MetadataArgsStorage,
|
||||
namingStrategy: NamingStrategyInterface,
|
||||
entityClasses?: Function[]): EntityMetadata[] {
|
||||
const embeddableMergedArgs = metadataArgsStorage.getMergedEmbeddableTableMetadatas(entityClasses);
|
||||
const entityMetadatas: EntityMetadata[] = [];
|
||||
const allMergedArgs = metadataArgsStorage.getMergedTableMetadatas(entityClasses);
|
||||
@ -55,10 +54,9 @@ export class EntityMetadataBuilder {
|
||||
embeddedArgs.forEach(embedded => {
|
||||
const embeddableTable = embeddableMergedArgs.find(embeddedMergedArgs => embeddedMergedArgs.table.target === embedded.type());
|
||||
if (embeddableTable) {
|
||||
const table = new TableMetadata(embeddableTable.table);
|
||||
const columns = embeddableTable.columns.toArray().map(args => new ColumnMetadata(args));
|
||||
const subEmbeddeds = findEmbeddedsRecursively(embeddableTable.embeddeds.toArray());
|
||||
embeddeds.push(new EmbeddedMetadata(table, columns, subEmbeddeds, embedded));
|
||||
embeddeds.push(new EmbeddedMetadata(columns, subEmbeddeds, embedded));
|
||||
}
|
||||
});
|
||||
return embeddeds;
|
||||
@ -68,7 +66,7 @@ export class EntityMetadataBuilder {
|
||||
// create metadatas from args
|
||||
const argsForTable = mergedArgs.inheritance && mergedArgs.inheritance.type === "single-table" ? mergedArgs.table : tableArgs;
|
||||
|
||||
const table = new TableMetadata(argsForTable);
|
||||
// const table = new TableMetadata(argsForTable);
|
||||
const columns = mergedArgs.columns.toArray().map(args => {
|
||||
|
||||
// if column's target is a child table then this column should have all nullable columns
|
||||
@ -92,7 +90,11 @@ export class EntityMetadataBuilder {
|
||||
target: tableArgs.target,
|
||||
tablesPrefix: driver.options.tablesPrefix,
|
||||
namingStrategy: namingStrategy,
|
||||
tableMetadata: table,
|
||||
tableName: argsForTable.name,
|
||||
tableType: argsForTable.type,
|
||||
orderBy: argsForTable.orderBy,
|
||||
engine: argsForTable.engine,
|
||||
skipSchemaSync: argsForTable.skipSchemaSync,
|
||||
columnMetadatas: columns,
|
||||
relationMetadatas: relations,
|
||||
relationIdMetadatas: relationIds,
|
||||
@ -133,7 +135,7 @@ export class EntityMetadataBuilder {
|
||||
return mergedArgs.table.target === entityMetadata.target;
|
||||
});
|
||||
if (mergedArgs && mergedArgs.parent) {
|
||||
const parentEntityMetadata = entityMetadatas.find(entityMetadata => entityMetadata.table.target === (mergedArgs!.parent! as any).target); // todo: weird compiler error here, thats why type casing is used
|
||||
const parentEntityMetadata = entityMetadatas.find(entityMetadata => entityMetadata.target === (mergedArgs!.parent! as any).target); // todo: weird compiler error here, thats why type casing is used
|
||||
if (parentEntityMetadata)
|
||||
entityMetadata.parentEntityMetadata = parentEntityMetadata;
|
||||
}
|
||||
@ -144,9 +146,9 @@ export class EntityMetadataBuilder {
|
||||
.filter(metadata => !!metadata.parentEntityMetadata)
|
||||
.forEach(metadata => {
|
||||
const parentEntityMetadataPrimaryColumn = metadata.parentEntityMetadata.firstPrimaryColumn; // todo: make sure to create columns for all its primary columns
|
||||
const columnName = namingStrategy.classTableInheritanceParentColumnName(metadata.parentEntityMetadata.table.name, parentEntityMetadataPrimaryColumn.propertyName);
|
||||
const columnName = namingStrategy.classTableInheritanceParentColumnName(metadata.parentEntityMetadata.tableName, parentEntityMetadataPrimaryColumn.propertyName);
|
||||
const parentRelationColumn = new ColumnMetadata({
|
||||
target: metadata.parentEntityMetadata.table.target,
|
||||
target: metadata.parentEntityMetadata.target,
|
||||
propertyName: parentEntityMetadataPrimaryColumn.propertyName,
|
||||
// propertyType: parentEntityMetadataPrimaryColumn.propertyType,
|
||||
mode: "parentId",
|
||||
@ -165,7 +167,7 @@ export class EntityMetadataBuilder {
|
||||
// add foreign key
|
||||
const foreignKey = new ForeignKeyMetadata(
|
||||
[parentRelationColumn],
|
||||
metadata.parentEntityMetadata.table,
|
||||
metadata.parentEntityMetadata,
|
||||
[parentEntityMetadataPrimaryColumn],
|
||||
"CASCADE"
|
||||
);
|
||||
@ -260,7 +262,7 @@ export class EntityMetadataBuilder {
|
||||
|
||||
const foreignKey = new ForeignKeyMetadata(
|
||||
columns,
|
||||
relation.inverseEntityMetadata.table,
|
||||
relation.inverseEntityMetadata,
|
||||
referencedColumns,
|
||||
relation.onDelete
|
||||
);
|
||||
@ -283,8 +285,8 @@ export class EntityMetadataBuilder {
|
||||
if (!joinTableMetadataArgs) return;
|
||||
|
||||
const joinTableName = joinTableMetadataArgs.name || relation.entityMetadata.namingStrategy.joinTableName(
|
||||
relation.entityMetadata.table.nameWithoutPrefix,
|
||||
relation.inverseEntityMetadata.table.nameWithoutPrefix,
|
||||
relation.entityMetadata.tableNameWithoutPrefix,
|
||||
relation.inverseEntityMetadata.tableNameWithoutPrefix,
|
||||
relation.propertyName,
|
||||
relation.hasInverseSide ? relation.inverseRelation.propertyName : ""
|
||||
);
|
||||
@ -350,18 +352,12 @@ export class EntityMetadataBuilder {
|
||||
// (columnName => namingStrategy.joinTableColumnName(relation.inverseEntityMetadata.table.nameWithoutPrefix, columnName))
|
||||
// );
|
||||
|
||||
const tableMetadata = new TableMetadata({
|
||||
target: "",
|
||||
name: joinTableName,
|
||||
type: "junction"
|
||||
});
|
||||
|
||||
const junctionColumns = referencedColumns.map(referencedColumn => {
|
||||
const joinColumn = joinTableMetadataArgs.joinColumns ? joinTableMetadataArgs.joinColumns.find(joinColumnArgs => {
|
||||
return (!joinColumnArgs.referencedColumnName || joinColumnArgs.referencedColumnName === referencedColumn.propertyName) &&
|
||||
!!joinColumnArgs.name;
|
||||
}) : undefined;
|
||||
const columnName = joinColumn && joinColumn.name ? joinColumn.name : namingStrategy.joinTableColumnName(relation.entityMetadata.table.nameWithoutPrefix, referencedColumn.fullName);
|
||||
const columnName = joinColumn && joinColumn.name ? joinColumn.name : namingStrategy.joinTableColumnName(relation.entityMetadata.tableNameWithoutPrefix, referencedColumn.fullName);
|
||||
|
||||
return new ColumnMetadata({
|
||||
target: "__virtual__",
|
||||
@ -382,7 +378,7 @@ export class EntityMetadataBuilder {
|
||||
return (!joinColumnArgs.referencedColumnName || joinColumnArgs.referencedColumnName === inverseReferencedColumn.propertyName) &&
|
||||
!!joinColumnArgs.name;
|
||||
}) : undefined;
|
||||
const columnName = joinColumn && joinColumn.name ? joinColumn.name : namingStrategy.joinTableColumnName(relation.inverseEntityMetadata.table.nameWithoutPrefix, inverseReferencedColumn.fullName);
|
||||
const columnName = joinColumn && joinColumn.name ? joinColumn.name : namingStrategy.joinTableColumnName(relation.inverseEntityMetadata.tableNameWithoutPrefix, inverseReferencedColumn.fullName);
|
||||
|
||||
return new ColumnMetadata({
|
||||
target: "__virtual__",
|
||||
@ -399,8 +395,8 @@ export class EntityMetadataBuilder {
|
||||
});
|
||||
|
||||
const foreignKeys = [
|
||||
new ForeignKeyMetadata(junctionColumns, relation.entityMetadata.table, referencedColumns),
|
||||
new ForeignKeyMetadata(inverseJunctionColumns, relation.inverseEntityMetadata.table, inverseReferencedColumns)
|
||||
new ForeignKeyMetadata(junctionColumns, relation.entityMetadata, referencedColumns),
|
||||
new ForeignKeyMetadata(inverseJunctionColumns, relation.inverseEntityMetadata, inverseReferencedColumns)
|
||||
];
|
||||
|
||||
junctionColumns.concat(inverseJunctionColumns).forEach(column => column.relationMetadata = relation);
|
||||
@ -410,7 +406,8 @@ export class EntityMetadataBuilder {
|
||||
target: "__virtual__",
|
||||
tablesPrefix: driver.options.tablesPrefix,
|
||||
namingStrategy: namingStrategy,
|
||||
tableMetadata: tableMetadata,
|
||||
tableName: joinTableName,
|
||||
tableType: "junction",
|
||||
columnMetadatas: junctionColumns.concat(inverseJunctionColumns),
|
||||
foreignKeyMetadatas: foreignKeys,
|
||||
indexMetadatas: [ // todo: shall we remove indices?
|
||||
@ -499,7 +496,7 @@ export class EntityMetadataBuilder {
|
||||
|
||||
// generate junction tables for all closure tables
|
||||
entityMetadatas.forEach(metadata => {
|
||||
if (!metadata.table.isClosure)
|
||||
if (!metadata.isClosure)
|
||||
return;
|
||||
|
||||
if (metadata.primaryColumns.length > 1)
|
||||
@ -507,7 +504,7 @@ export class EntityMetadataBuilder {
|
||||
|
||||
const closureJunctionEntityMetadata = getFromContainer(ClosureJunctionEntityMetadataBuilder).build(driver, lazyRelationsWrapper, {
|
||||
namingStrategy: namingStrategy,
|
||||
table: metadata.table,
|
||||
entityMetadata: metadata,
|
||||
primaryColumn: metadata.firstPrimaryColumn,
|
||||
hasTreeLevelColumn: metadata.hasTreeLevelColumn
|
||||
});
|
||||
@ -525,47 +522,4 @@ export class EntityMetadataBuilder {
|
||||
// Private Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/*private createJoinColumns(joinColumnArgsArray: JoinColumnMetadataArgs[],
|
||||
primaryColumns: ColumnMetadata[],
|
||||
columnMetadatas: ColumnMetadata[],
|
||||
relation: RelationMetadata,
|
||||
columnNameFactory: (columnName: string) => string): ColumnMetadata[] {
|
||||
|
||||
const hasAnyReferencedColumnName = joinColumnArgsArray.find(joinColumnArgs => !!joinColumnArgs.referencedColumnName);
|
||||
const createColumns = (joinColumnArgsArray.length === 0 && relation.isManyToOne) ||
|
||||
(joinColumnArgsArray.length > 0 && !hasAnyReferencedColumnName) ||
|
||||
(relation.isManyToMany && !hasAnyReferencedColumnName);
|
||||
|
||||
if (createColumns) { // covers case3 and case1
|
||||
|
||||
joinColumnArgsArray = primaryColumns.map(primaryColumn => {
|
||||
|
||||
// in the case if relation has join column with only name set we need this check
|
||||
const joinColumnMetadataArg = joinColumnArgsArray.find(joinColumnArgs => !joinColumnArgs.referencedColumnName && !!joinColumnArgs.name);
|
||||
return {
|
||||
target: relation.entityMetadata.target,
|
||||
propertyName: relation.propertyName,
|
||||
referencedColumnName: primaryColumn.propertyName,
|
||||
name: joinColumnMetadataArg ? joinColumnMetadataArg.name : undefined
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return joinColumnArgsArray.map(joinColumnMetadataArgs => {
|
||||
const joinColumn = new JoinColumnMetadata();
|
||||
joinColumn.relation = relation;
|
||||
joinColumn.target = joinColumnMetadataArgs.target;
|
||||
joinColumn.propertyName = joinColumnMetadataArgs.propertyName;
|
||||
const referencedColumn = columnMetadatas.find(column => {
|
||||
return column.propertyName === joinColumnMetadataArgs.referencedColumnName;
|
||||
});
|
||||
if (!referencedColumn)
|
||||
throw new Error(`Referenced column ${joinColumnMetadataArgs.referencedColumnName} was not found in entity ${relation.inverseEntityMetadata.name}`); // todo: fix ${relation.inverseEntityMetadata.name}
|
||||
|
||||
joinColumn.referencedColumn = referencedColumn;
|
||||
joinColumn.name = joinColumnMetadataArgs.name || columnNameFactory(joinColumn.referencedColumn.propertyName);
|
||||
return joinColumn;
|
||||
});
|
||||
}*/
|
||||
|
||||
}
|
||||
@ -29,7 +29,7 @@ export class EntityMetadataValidator {
|
||||
validate(entityMetadata: EntityMetadata, allEntityMetadatas: EntityMetadata[]) {
|
||||
|
||||
// check if table metadata has an id
|
||||
if (!entityMetadata.table.isClassTableChild && !entityMetadata.primaryColumns.length && !entityMetadata.junction)
|
||||
if (!entityMetadata.isClassTableChild && !entityMetadata.primaryColumns.length && !entityMetadata.junction)
|
||||
throw new MissingPrimaryColumnError(entityMetadata);
|
||||
|
||||
// validate if table is using inheritance it has a discriminator
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import {EntityMetadata} from "./EntityMetadata";
|
||||
import {TableMetadata} from "./TableMetadata";
|
||||
import {ColumnMetadata} from "./ColumnMetadata";
|
||||
import {EmbeddedMetadataArgs} from "../metadata-args/EmbeddedMetadataArgs";
|
||||
|
||||
@ -31,11 +30,6 @@ export class EmbeddedMetadata {
|
||||
*/
|
||||
readonly propertyName: string;
|
||||
|
||||
/**
|
||||
* Embeddable table.
|
||||
*/
|
||||
readonly table: TableMetadata;
|
||||
|
||||
/**
|
||||
* Embeddable table's columns.
|
||||
*/
|
||||
@ -66,15 +60,13 @@ export class EmbeddedMetadata {
|
||||
// Constructor
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
constructor(table: TableMetadata,
|
||||
columns: ColumnMetadata[],
|
||||
constructor(columns: ColumnMetadata[],
|
||||
embeddeds: EmbeddedMetadata[],
|
||||
args: EmbeddedMetadataArgs) {
|
||||
this.type = args.type ? args.type() : undefined;
|
||||
this.propertyName = args.propertyName;
|
||||
this.isArray = args.isArray;
|
||||
this.customPrefix = args.prefix;
|
||||
this.table = table;
|
||||
this.columns = columns;
|
||||
this.embeddeds = embeddeds;
|
||||
this.embeddeds.forEach(embedded => {
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import {TableMetadata} from "./TableMetadata";
|
||||
import {ColumnMetadata} from "./ColumnMetadata";
|
||||
import {RelationMetadata, PropertyTypeInFunction} from "./RelationMetadata";
|
||||
import {PropertyTypeInFunction, RelationMetadata} from "./RelationMetadata";
|
||||
import {IndexMetadata} from "./IndexMetadata";
|
||||
import {RelationTypes} from "./types/RelationTypes";
|
||||
import {ForeignKeyMetadata} from "./ForeignKeyMetadata";
|
||||
@ -11,6 +10,8 @@ import {ObjectLiteral} from "../common/ObjectLiteral";
|
||||
import {LazyRelationsWrapper} from "../lazy-loading/LazyRelationsWrapper";
|
||||
import {RelationIdMetadata} from "./RelationIdMetadata";
|
||||
import {RelationCountMetadata} from "./RelationCountMetadata";
|
||||
import {TableType, TableTypes} from "./types/TableTypes";
|
||||
import {OrderByCondition} from "../find-options/OrderByCondition";
|
||||
|
||||
// todo: IDEA. store all entity metadata in the EntityMetadata too? (this will open more features for metadata objects + no need to access connection in lot of places)
|
||||
|
||||
@ -56,7 +57,12 @@ export class EntityMetadata {
|
||||
/**
|
||||
* Entity's table metadata.
|
||||
*/
|
||||
readonly table: TableMetadata;
|
||||
readonly _tableName?: string;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Entity's relation metadatas.
|
||||
@ -105,6 +111,21 @@ export class EntityMetadata {
|
||||
*/
|
||||
readonly tablesPrefix?: string;
|
||||
|
||||
/**
|
||||
* Table's database engine type (like "InnoDB", "MyISAM", etc).
|
||||
*/
|
||||
readonly engine?: string;
|
||||
|
||||
/**
|
||||
* Whether table must be synced during schema build or not
|
||||
*/
|
||||
readonly skipSchemaSync?: boolean;
|
||||
|
||||
/**
|
||||
* Table type. Tables can be abstract, closure, junction, embedded, etc.
|
||||
*/
|
||||
tableType: TableType = "regular";
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private properties
|
||||
// -------------------------------------------------------------------------
|
||||
@ -124,7 +145,8 @@ export class EntityMetadata {
|
||||
this.junction = args.junction;
|
||||
this.tablesPrefix = args.tablesPrefix;
|
||||
this.namingStrategy = args.namingStrategy;
|
||||
this.table = args.tableMetadata;
|
||||
this._tableName = args.tableName;
|
||||
this.tableType = args.tableType;
|
||||
this._columns = args.columnMetadatas || [];
|
||||
this.relations = args.relationMetadatas || [];
|
||||
this.relationIds = args.relationIdMetadatas || [];
|
||||
@ -134,8 +156,9 @@ export class EntityMetadata {
|
||||
this.embeddeds = args.embeddedMetadatas || [];
|
||||
this.discriminatorValue = args.discriminatorValue;
|
||||
this.inheritanceType = args.inheritanceType;
|
||||
|
||||
this.table.entityMetadata = this;
|
||||
this.engine = args.engine;
|
||||
this.skipSchemaSync = args.skipSchemaSync;
|
||||
this._orderBy = args.orderBy;
|
||||
this._columns.forEach(column => column.entityMetadata = this);
|
||||
this.relations.forEach(relation => relation.entityMetadata = this);
|
||||
this.relationIds.forEach(relationId => relationId.entityMetadata = this);
|
||||
@ -161,10 +184,43 @@ export class EntityMetadata {
|
||||
* Entity's name. Equal to entity target class's name if target is set to table, or equals to table name if its set.
|
||||
*/
|
||||
get name(): string {
|
||||
if (!this.table)
|
||||
throw new Error("No table target set to the entity metadata.");
|
||||
return this.targetName ? this.targetName : this.tableName;
|
||||
}
|
||||
|
||||
return this.targetName ? this.targetName : this.table.name;
|
||||
/**
|
||||
* Entity's name. Equal to entity target class's name if target is set to table, or equals to table name if its set.
|
||||
*/
|
||||
get tableName(): string {
|
||||
if (this.tablesPrefix)
|
||||
return this.namingStrategy.prefixTableName(this.tablesPrefix, this.tableNameWithoutPrefix);
|
||||
|
||||
return this.tableNameWithoutPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the table name without global table prefix.
|
||||
* When querying table you need a table name with prefix, but in some scenarios,
|
||||
* for example when you want to name a junction table that contains names of two other tables,
|
||||
* you may want a table name without prefix.
|
||||
*/
|
||||
get tableNameWithoutPrefix() {
|
||||
if (this.isClosureJunction && this._tableName)
|
||||
return this.namingStrategy.closureJunctionTableName(this._tableName);
|
||||
|
||||
// otherwise generate table name from target's name
|
||||
const name = this.target instanceof Function ? (this.target as any).name : this.target;
|
||||
return this.namingStrategy.tableName(name, this._tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a default order by used for queries from this table when no explicit order by is specified.
|
||||
* If default order by was not set, then returns undefined.
|
||||
*/
|
||||
get orderBy(): OrderByCondition|undefined {
|
||||
if (this._orderBy instanceof Function)
|
||||
return this._orderBy(this.createPropertiesMap());
|
||||
|
||||
return this._orderBy;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -963,4 +1019,70 @@ export class EntityMetadata {
|
||||
// return this.relationsWithJoinColumns.some(relation => relation.isNullable || relation.isPrimary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is regular.
|
||||
* All non-specific tables are just regular tables. Its a default table type.
|
||||
*/
|
||||
get isRegular() {
|
||||
return this.tableType === TableTypes.REGULAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is abstract.
|
||||
* This type is for the tables that does not exist in the database,
|
||||
* but provide columns and relations for the tables of the child classes who inherit them.
|
||||
*/
|
||||
get isAbstract() {
|
||||
return this.tableType === TableTypes.ABSTRACT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is abstract.
|
||||
* Junction table is a table automatically created by many-to-many relationship.
|
||||
*/
|
||||
get isJunction() {
|
||||
return this.tableType === TableTypes.JUNCTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is a closure table.
|
||||
* Closure table is one of the tree-specific tables that supports closure database pattern.
|
||||
*/
|
||||
get isClosure() {
|
||||
return this.tableType === TableTypes.CLOSURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is a junction table of the closure table.
|
||||
* This type is for tables that contain junction metadata of the closure tables.
|
||||
*/
|
||||
get isClosureJunction() {
|
||||
return this.tableType === TableTypes.CLOSURE_JUNCTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is an embeddable table.
|
||||
* Embeddable tables are not stored in the database as separate tables.
|
||||
* Instead their columns are embed into tables who owns them.
|
||||
*/
|
||||
get isEmbeddable() {
|
||||
return this.tableType === TableTypes.EMBEDDABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is a single table child.
|
||||
* Special table type for tables that are mapped into single table using Single Table Inheritance pattern.
|
||||
*/
|
||||
get isSingleTableChild() {
|
||||
return this.tableType === TableTypes.SINGLE_TABLE_CHILD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is a class table child.
|
||||
* Special table type for tables that are mapped into multiple tables using Class Table Inheritance pattern.
|
||||
*/
|
||||
get isClassTableChild() {
|
||||
return this.tableType === TableTypes.CLASS_TABLE_CHILD;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
import {ColumnMetadata} from "./ColumnMetadata";
|
||||
import {TableMetadata} from "./TableMetadata";
|
||||
import {EntityMetadata} from "./EntityMetadata";
|
||||
|
||||
/**
|
||||
@ -21,6 +20,11 @@ export class ForeignKeyMetadata {
|
||||
*/
|
||||
entityMetadata: EntityMetadata;
|
||||
|
||||
/**
|
||||
* Entity metadata which this foreign key is references.
|
||||
*/
|
||||
referencedEntityMetadata: EntityMetadata;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Readonly Properties
|
||||
// -------------------------------------------------------------------------
|
||||
@ -30,11 +34,6 @@ export class ForeignKeyMetadata {
|
||||
*/
|
||||
readonly columns: ColumnMetadata[];
|
||||
|
||||
/**
|
||||
* Table to which this foreign key is references.
|
||||
*/
|
||||
readonly referencedTable: TableMetadata;
|
||||
|
||||
/**
|
||||
* Array of referenced columns.
|
||||
*/
|
||||
@ -50,11 +49,11 @@ export class ForeignKeyMetadata {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(columns: ColumnMetadata[],
|
||||
referencedTable: TableMetadata,
|
||||
referencedEntityMetadata: EntityMetadata,
|
||||
referencedColumns: ColumnMetadata[],
|
||||
onDelete?: OnDeleteType) {
|
||||
this.columns = columns;
|
||||
this.referencedTable = referencedTable;
|
||||
this.referencedEntityMetadata = referencedEntityMetadata;
|
||||
this.referencedColumns = referencedColumns;
|
||||
if (onDelete)
|
||||
this.onDelete = onDelete;
|
||||
@ -68,21 +67,21 @@ export class ForeignKeyMetadata {
|
||||
* Gets the table name to which this foreign key is applied.
|
||||
*/
|
||||
get tableName() {
|
||||
return this.entityMetadata.table.name;
|
||||
return this.entityMetadata.tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the table name to which this foreign key is referenced.
|
||||
*/
|
||||
get referencedTableName() {
|
||||
return this.referencedTable.name;
|
||||
return this.referencedEntityMetadata.tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets foreign key name.
|
||||
*/
|
||||
get name() {
|
||||
return this.entityMetadata.namingStrategy.foreignKeyName(this.tableName, this.columnNames, this.referencedTable.name, this.referencedColumnNames);
|
||||
return this.entityMetadata.namingStrategy.foreignKeyName(this.tableName, this.columnNames, this.referencedEntityMetadata.tableName, this.referencedColumnNames);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -62,14 +62,14 @@ export class IndexMetadata {
|
||||
* Gets index's name.
|
||||
*/
|
||||
get name() {
|
||||
return this.entityMetadata.namingStrategy.indexName(this._name, this.entityMetadata.table.name, this.columns);
|
||||
return this.entityMetadata.namingStrategy.indexName(this._name, this.entityMetadata.tableName, this.columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the table name on which index is applied.
|
||||
*/
|
||||
get tableName() {
|
||||
return this.entityMetadata.table.name;
|
||||
return this.entityMetadata.tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {RelationTypes, RelationType} from "./types/RelationTypes";
|
||||
import {RelationType, RelationTypes} from "./types/RelationTypes";
|
||||
import {EntityMetadata} from "./EntityMetadata";
|
||||
import {OnDeleteType, ForeignKeyMetadata} from "./ForeignKeyMetadata";
|
||||
import {ForeignKeyMetadata, OnDeleteType} from "./ForeignKeyMetadata";
|
||||
import {RelationMetadataArgs} from "../metadata-args/RelationMetadataArgs";
|
||||
import {ObjectLiteral} from "../common/ObjectLiteral";
|
||||
import {ColumnMetadata} from "./ColumnMetadata";
|
||||
@ -209,7 +209,7 @@ export class RelationMetadata {
|
||||
* Join table name.
|
||||
*/
|
||||
get joinTableName(): string {
|
||||
return this.junctionEntityMetadata.table.name;
|
||||
return this.junctionEntityMetadata.tableName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,205 +0,0 @@
|
||||
import {EntityMetadata} from "./EntityMetadata";
|
||||
import {TableMetadataArgs} from "../metadata-args/TableMetadataArgs";
|
||||
import {OrderByCondition} from "../find-options/OrderByCondition";
|
||||
import {TableType, TableTypes} from "./types/TableTypes";
|
||||
import {EntityMetadataAlreadySetError} from "./error/EntityMetadataAlreadySetError";
|
||||
import {EntityMetadataNotSetError} from "./error/EntityMetadataNotSetError";
|
||||
|
||||
/**
|
||||
* TableMetadata contains all entity's table metadata and information.
|
||||
*/
|
||||
export class TableMetadata {
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Public Properties
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Target class to which metadata is applied.
|
||||
* Function target is a table defined in the class.
|
||||
* String target is a table defined in a json schema.
|
||||
* "__virtual__" is a table defined without target class (like junction tables).
|
||||
*/
|
||||
readonly target: Function|string|"__virtual__";
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Table's database engine type (like "InnoDB", "MyISAM", etc).
|
||||
*/
|
||||
readonly engine?: string;
|
||||
|
||||
/**
|
||||
* Whether table must be synced during schema build or not
|
||||
*/
|
||||
readonly skipSchemaSync?: boolean;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Private Properties
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Table type. Tables can be abstract, closure, junction, embedded, etc.
|
||||
*/
|
||||
private readonly tableType: TableType = "regular";
|
||||
|
||||
/**
|
||||
* Table name in the database. If name is not set then table's name will be generated from target's name.
|
||||
*/
|
||||
private readonly _name?: string;
|
||||
|
||||
/**
|
||||
* EntityMetadata of this table metadata, where this table metadata contained.
|
||||
*/
|
||||
private _entityMetadata?: EntityMetadata;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates a new TableMetadata based on the given arguments object.
|
||||
*/
|
||||
constructor(args: TableMetadataArgs) {
|
||||
this.target = args.target;
|
||||
this.tableType = args.type;
|
||||
this._name = args.name;
|
||||
this._orderBy = args.orderBy;
|
||||
this.engine = args.engine;
|
||||
this.skipSchemaSync = args.skipSchemaSync;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Accessors
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Sets the entity metadata of this table metadata.
|
||||
* Note that entity metadata can be set only once.
|
||||
* Once you set it, you can't change it anymore.
|
||||
*/
|
||||
set entityMetadata(metadata: EntityMetadata) {
|
||||
if (this._entityMetadata)
|
||||
throw new EntityMetadataAlreadySetError(TableMetadata, this.target, this._name);
|
||||
|
||||
this._entityMetadata = metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets entity metadata of this table metadata.
|
||||
* If entity metadata was not set then exception will be thrown.
|
||||
*/
|
||||
get entityMetadata(): EntityMetadata {
|
||||
if (!this._entityMetadata)
|
||||
throw new EntityMetadataNotSetError(TableMetadata, this.target, this._name);
|
||||
|
||||
return this._entityMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the table name without global table prefix.
|
||||
* When querying table you need a table name with prefix, but in some scenarios,
|
||||
* for example when you want to name a junction table that contains names of two other tables,
|
||||
* you may want a table name without prefix.
|
||||
*/
|
||||
get nameWithoutPrefix() {
|
||||
if (this.isClosureJunction && this._name)
|
||||
return this.entityMetadata.namingStrategy.closureJunctionTableName(this._name);
|
||||
|
||||
// otherwise generate table name from target's name
|
||||
const name = this.target instanceof Function ? (this.target as any).name : this.target;
|
||||
return this.entityMetadata.namingStrategy.tableName(name, this._name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Table name in the database.
|
||||
* This name includes global table prefix if it was set.
|
||||
*/
|
||||
get name(): string {
|
||||
if (this.entityMetadata.tablesPrefix)
|
||||
return this.entityMetadata.namingStrategy.prefixTableName(this.entityMetadata.tablesPrefix, this.nameWithoutPrefix);
|
||||
|
||||
return this.nameWithoutPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a default order by used for queries from this table when no explicit order by is specified.
|
||||
* If default order by was not set, then returns undefined.
|
||||
*/
|
||||
get orderBy(): OrderByCondition|undefined {
|
||||
if (this._orderBy instanceof Function)
|
||||
return this._orderBy(this.entityMetadata.createPropertiesMap());
|
||||
|
||||
return this._orderBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is regular.
|
||||
* All non-specific tables are just regular tables. Its a default table type.
|
||||
*/
|
||||
get isRegular() {
|
||||
return this.tableType === TableTypes.REGULAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is abstract.
|
||||
* This type is for the tables that does not exist in the database,
|
||||
* but provide columns and relations for the tables of the child classes who inherit them.
|
||||
*/
|
||||
get isAbstract() {
|
||||
return this.tableType === TableTypes.ABSTRACT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is abstract.
|
||||
* Junction table is a table automatically created by many-to-many relationship.
|
||||
*/
|
||||
get isJunction() {
|
||||
return this.tableType === TableTypes.JUNCTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is a closure table.
|
||||
* Closure table is one of the tree-specific tables that supports closure database pattern.
|
||||
*/
|
||||
get isClosure() {
|
||||
return this.tableType === TableTypes.CLOSURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is a junction table of the closure table.
|
||||
* This type is for tables that contain junction metadata of the closure tables.
|
||||
*/
|
||||
get isClosureJunction() {
|
||||
return this.tableType === TableTypes.CLOSURE_JUNCTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is an embeddable table.
|
||||
* Embeddable tables are not stored in the database as separate tables.
|
||||
* Instead their columns are embed into tables who owns them.
|
||||
*/
|
||||
get isEmbeddable() {
|
||||
return this.tableType === TableTypes.EMBEDDABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is a single table child.
|
||||
* Special table type for tables that are mapped into single table using Single Table Inheritance pattern.
|
||||
*/
|
||||
get isSingleTableChild() {
|
||||
return this.tableType === TableTypes.SINGLE_TABLE_CHILD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this table is a class table child.
|
||||
* Special table type for tables that are mapped into multiple tables using Class Table Inheritance pattern.
|
||||
*/
|
||||
get isClassTableChild() {
|
||||
return this.tableType === TableTypes.CLASS_TABLE_CHILD;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
/**
|
||||
* Thrown when user tries to execute operation that requires connection to be established.
|
||||
*/
|
||||
export class EntityMetadataAlreadySetError extends Error {
|
||||
name = "EntityMetadataAlreadySetError";
|
||||
|
||||
constructor(type: Function, target: Function|string|undefined, tableName: string|undefined) {
|
||||
super();
|
||||
const targetMessage = target ? ` for ${ target instanceof Function ? (target.constructor as any).name : target }` : "";
|
||||
const tableNameMessage = tableName ? ` with ${ tableName } table name` : "";
|
||||
this.message = "Entity metadata" + targetMessage + tableNameMessage + " has been already set to this " + (type.constructor as any).name;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
/**
|
||||
* Thrown when accessed to the class with entity metadata,
|
||||
* however on that time entity metadata is not set in the class.
|
||||
*/
|
||||
export class EntityMetadataNotSetError extends Error {
|
||||
name = "EntityMetadataNotSetError";
|
||||
|
||||
constructor(type: Function, target: Function|string|undefined, tableName: string|undefined) {
|
||||
super();
|
||||
const targetMessage = target ? ` for ${ target instanceof Function ? (target.constructor as any).name : target }` : "";
|
||||
const tableNameMessage = tableName ? ` with ${ tableName } table name` : "";
|
||||
this.message = "Entity metadata" + targetMessage + tableNameMessage + " is not set in " + (type.constructor as any).name;
|
||||
}
|
||||
|
||||
}
|
||||
@ -300,7 +300,7 @@ export class SubjectBuilder<Entity extends ObjectLiteral> {
|
||||
// note: we can't use extractRelationValuesFromEntity here because it does not handle empty arrays
|
||||
const promises = subject.metadata.relations.map(async relation => {
|
||||
const valueMetadata = relation.inverseEntityMetadata;
|
||||
const qbAlias = valueMetadata.table.name;
|
||||
const qbAlias = valueMetadata.tableName;
|
||||
|
||||
// added for type-safety, but subject without databaseEntity cant come here anyway because of checks on upper levels
|
||||
if (!subject.hasDatabaseEntity) return;
|
||||
@ -555,7 +555,7 @@ export class SubjectBuilder<Entity extends ObjectLiteral> {
|
||||
databaseEntities = await this.connection
|
||||
.getRepository<ObjectLiteral>(valueMetadata.target)
|
||||
.createQueryBuilder(qbAlias, this.queryRunnerProvider) // todo: this wont work for mongodb. implement this in some method and call it here instead?
|
||||
.innerJoin(relation.junctionEntityMetadata.table.name, joinAlias, conditions)
|
||||
.innerJoin(relation.junctionEntityMetadata.tableName, joinAlias, conditions)
|
||||
.setParameters(parameters)
|
||||
.enableAutoRelationIdsLoad()
|
||||
.getMany();
|
||||
@ -586,7 +586,7 @@ export class SubjectBuilder<Entity extends ObjectLiteral> {
|
||||
databaseEntities = await this.connection
|
||||
.getRepository<ObjectLiteral>(valueMetadata.target)
|
||||
.createQueryBuilder(qbAlias, this.queryRunnerProvider) // todo: this wont work for mongodb. implement this in some method and call it here instead?
|
||||
.innerJoin(relation.junctionEntityMetadata.table.name, joinAlias, conditions)
|
||||
.innerJoin(relation.junctionEntityMetadata.tableName, joinAlias, conditions)
|
||||
.setParameters(parameters)
|
||||
.enableAutoRelationIdsLoad()
|
||||
.getMany();
|
||||
|
||||
@ -2,7 +2,7 @@ import {ObjectLiteral} from "../common/ObjectLiteral";
|
||||
import {EntityMetadata} from "../metadata/EntityMetadata";
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {QueryRunner} from "../query-runner/QueryRunner";
|
||||
import {Subject, JunctionInsert, JunctionRemove} from "./Subject";
|
||||
import {JunctionInsert, JunctionRemove, Subject} from "./Subject";
|
||||
import {OrmUtils} from "../util/OrmUtils";
|
||||
import {QueryRunnerProvider} from "../query-runner/QueryRunnerProvider";
|
||||
import {EntityManager} from "../entity-manager/EntityManager";
|
||||
@ -318,7 +318,7 @@ export class SubjectOperationExecutor {
|
||||
if (!Object.keys(conditions).length)
|
||||
return;
|
||||
|
||||
const updatePromise = this.queryRunner.update(subject.metadata.table.name, updateOptions, conditions);
|
||||
const updatePromise = this.queryRunner.update(subject.metadata.tableName, updateOptions, conditions);
|
||||
updatePromises.push(updatePromise);
|
||||
}
|
||||
|
||||
@ -397,7 +397,7 @@ export class SubjectOperationExecutor {
|
||||
updateOptions[joinColumn.fullName] = subject.entity[referencedColumn.propertyName] || subject.newlyGeneratedId || subRelatedEntity.generatedObjectId;
|
||||
}
|
||||
|
||||
const updatePromise = this.queryRunner.update(relation.inverseEntityMetadata.table.name, updateOptions, conditions);
|
||||
const updatePromise = this.queryRunner.update(relation.inverseEntityMetadata.tableName, updateOptions, conditions);
|
||||
updatePromises.push(updatePromise);
|
||||
|
||||
});
|
||||
@ -423,21 +423,21 @@ export class SubjectOperationExecutor {
|
||||
let newlyGeneratedId: any, parentGeneratedId: any;
|
||||
|
||||
// if entity uses class table inheritance then we need to separate entity into sub values that will be inserted into multiple tables
|
||||
if (metadata.table.isClassTableChild) { // todo: with current implementation inheritance of multiple class table children will not work
|
||||
if (metadata.isClassTableChild) { // todo: with current implementation inheritance of multiple class table children will not work
|
||||
|
||||
// first insert entity values into parent class table
|
||||
const parentValuesMap = this.collectColumnsAndValues(parentEntityMetadata, entity, subject.date, undefined, metadata.discriminatorValue, alreadyInsertedSubjects);
|
||||
newlyGeneratedId = parentGeneratedId = await this.queryRunner.insert(parentEntityMetadata.table.name, parentValuesMap, parentEntityMetadata.generatedColumnIfExist);
|
||||
newlyGeneratedId = parentGeneratedId = await this.queryRunner.insert(parentEntityMetadata.tableName, parentValuesMap, parentEntityMetadata.generatedColumnIfExist);
|
||||
|
||||
// second insert entity values into child class table
|
||||
const childValuesMap = this.collectColumnsAndValues(metadata, entity, subject.date, newlyGeneratedId, undefined, alreadyInsertedSubjects);
|
||||
const secondGeneratedId = await this.queryRunner.insert(metadata.table.name, childValuesMap, metadata.generatedColumnIfExist);
|
||||
const secondGeneratedId = await this.queryRunner.insert(metadata.tableName, childValuesMap, metadata.generatedColumnIfExist);
|
||||
if (!newlyGeneratedId && secondGeneratedId) newlyGeneratedId = secondGeneratedId;
|
||||
|
||||
} else { // in the case when class table inheritance is not used
|
||||
|
||||
const valuesMap = this.collectColumnsAndValues(metadata, entity, subject.date, undefined, undefined, alreadyInsertedSubjects);
|
||||
newlyGeneratedId = await this.queryRunner.insert(metadata.table.name, valuesMap, metadata.generatedColumnIfExist);
|
||||
newlyGeneratedId = await this.queryRunner.insert(metadata.tableName, valuesMap, metadata.generatedColumnIfExist);
|
||||
}
|
||||
|
||||
if (parentGeneratedId)
|
||||
@ -637,7 +637,7 @@ export class SubjectOperationExecutor {
|
||||
*/
|
||||
private executeInsertClosureTableOperations(/*, updatesByRelations: Subject[]*/) { // todo: what to do with updatesByRelations
|
||||
const promises = this.insertSubjects
|
||||
.filter(subject => subject.metadata.table.isClosure)
|
||||
.filter(subject => subject.metadata.isClosure)
|
||||
.map(async subject => {
|
||||
// const relationsUpdateMap = this.findUpdateOperationForEntity(updatesByRelations, insertSubjects, subject.entity);
|
||||
// subject.treeLevel = await this.insertIntoClosureTable(subject, relationsUpdateMap);
|
||||
@ -652,7 +652,7 @@ export class SubjectOperationExecutor {
|
||||
private async insertClosureTableValues(subject: Subject): Promise<void> {
|
||||
// todo: since closure tables do not support compose primary keys - throw an exception?
|
||||
// todo: what if parent entity or parentEntityId is empty?!
|
||||
const tableName = subject.metadata.closureJunctionTable.table.name;
|
||||
const tableName = subject.metadata.closureJunctionTable.tableName;
|
||||
const referencedColumn = subject.metadata.treeParentRelation.joinColumns[0].referencedColumn; // todo: check if joinColumn works
|
||||
// todo: fix joinColumns[0] usage
|
||||
|
||||
@ -676,7 +676,7 @@ export class SubjectOperationExecutor {
|
||||
// try to find parent entity id in some other entity that has this entity in its children
|
||||
if (!parentEntityId) {
|
||||
const parentSubject = this.allSubjects.find(allSubject => {
|
||||
if (!allSubject.hasEntity || !allSubject.metadata.table.isClosure || !allSubject.metadata.hasTreeChildrenRelation)
|
||||
if (!allSubject.hasEntity || !allSubject.metadata.isClosure || !allSubject.metadata.hasTreeChildrenRelation)
|
||||
return false;
|
||||
|
||||
const children = allSubject.entity[subject.metadata.treeChildrenRelation.propertyName];
|
||||
@ -696,7 +696,7 @@ export class SubjectOperationExecutor {
|
||||
|
||||
if (subject.metadata.hasTreeLevelColumn) {
|
||||
const values = { [subject.metadata.treeLevelColumn.fullName]: subject.treeLevel };
|
||||
await this.queryRunner.update(subject.metadata.table.name, values, { [referencedColumn.fullName]: newEntityId });
|
||||
await this.queryRunner.update(subject.metadata.tableName, values, { [referencedColumn.fullName]: newEntityId });
|
||||
}
|
||||
}
|
||||
|
||||
@ -765,7 +765,7 @@ export class SubjectOperationExecutor {
|
||||
if (subject.metadata.hasVersionColumn)
|
||||
value[subject.metadata.versionColumn.fullName] = this.connection.driver.preparePersistentValue(entity[subject.metadata.versionColumn.propertyName] + 1, subject.metadata.versionColumn);
|
||||
|
||||
return this.queryRunner.update(subject.metadata.table.name, value, idMap);
|
||||
return this.queryRunner.update(subject.metadata.tableName, value, idMap);
|
||||
}
|
||||
|
||||
// we group by table name, because metadata can have different table names
|
||||
@ -774,9 +774,9 @@ export class SubjectOperationExecutor {
|
||||
subject.diffColumns.forEach(column => {
|
||||
if (!column.entityTarget) return; // todo: how this can be possible?
|
||||
const metadata = this.connection.getMetadata(column.entityTarget);
|
||||
let valueMap = valueMaps.find(valueMap => valueMap.tableName === metadata.table.name);
|
||||
let valueMap = valueMaps.find(valueMap => valueMap.tableName === metadata.tableName);
|
||||
if (!valueMap) {
|
||||
valueMap = { tableName: metadata.table.name, metadata: metadata, values: {} };
|
||||
valueMap = { tableName: metadata.tableName, metadata: metadata, values: {} };
|
||||
valueMaps.push(valueMap);
|
||||
}
|
||||
|
||||
@ -785,9 +785,9 @@ export class SubjectOperationExecutor {
|
||||
|
||||
subject.diffRelations.forEach(relation => {
|
||||
const metadata = this.connection.getMetadata(relation.entityTarget);
|
||||
let valueMap = valueMaps.find(valueMap => valueMap.tableName === metadata.table.name);
|
||||
let valueMap = valueMaps.find(valueMap => valueMap.tableName === metadata.tableName);
|
||||
if (!valueMap) {
|
||||
valueMap = { tableName: metadata.table.name, metadata: metadata, values: {} };
|
||||
valueMap = { tableName: metadata.tableName, metadata: metadata, values: {} };
|
||||
valueMaps.push(valueMap);
|
||||
}
|
||||
|
||||
@ -802,9 +802,9 @@ export class SubjectOperationExecutor {
|
||||
return;
|
||||
|
||||
if (subject.metadata.hasUpdateDateColumn) {
|
||||
let valueMap = valueMaps.find(valueMap => valueMap.tableName === subject.metadata.table.name);
|
||||
let valueMap = valueMaps.find(valueMap => valueMap.tableName === subject.metadata.tableName);
|
||||
if (!valueMap) {
|
||||
valueMap = { tableName: subject.metadata.table.name, metadata: subject.metadata, values: {} };
|
||||
valueMap = { tableName: subject.metadata.tableName, metadata: subject.metadata, values: {} };
|
||||
valueMaps.push(valueMap);
|
||||
}
|
||||
|
||||
@ -812,9 +812,9 @@ export class SubjectOperationExecutor {
|
||||
}
|
||||
|
||||
if (subject.metadata.hasVersionColumn) {
|
||||
let valueMap = valueMaps.find(valueMap => valueMap.tableName === subject.metadata.table.name);
|
||||
let valueMap = valueMaps.find(valueMap => valueMap.tableName === subject.metadata.tableName);
|
||||
if (!valueMap) {
|
||||
valueMap = { tableName: subject.metadata.table.name, metadata: subject.metadata, values: {} };
|
||||
valueMap = { tableName: subject.metadata.tableName, metadata: subject.metadata, values: {} };
|
||||
valueMaps.push(valueMap);
|
||||
}
|
||||
|
||||
@ -823,10 +823,10 @@ export class SubjectOperationExecutor {
|
||||
|
||||
if (subject.metadata.parentEntityMetadata) {
|
||||
if (subject.metadata.parentEntityMetadata.hasUpdateDateColumn) {
|
||||
let valueMap = valueMaps.find(valueMap => valueMap.tableName === subject.metadata.parentEntityMetadata.table.name);
|
||||
let valueMap = valueMaps.find(valueMap => valueMap.tableName === subject.metadata.parentEntityMetadata.tableName);
|
||||
if (!valueMap) {
|
||||
valueMap = {
|
||||
tableName: subject.metadata.parentEntityMetadata.table.name,
|
||||
tableName: subject.metadata.parentEntityMetadata.tableName,
|
||||
metadata: subject.metadata.parentEntityMetadata,
|
||||
values: {}
|
||||
};
|
||||
@ -837,10 +837,10 @@ export class SubjectOperationExecutor {
|
||||
}
|
||||
|
||||
if (subject.metadata.parentEntityMetadata.hasVersionColumn) {
|
||||
let valueMap = valueMaps.find(valueMap => valueMap.tableName === subject.metadata.parentEntityMetadata.table.name);
|
||||
let valueMap = valueMaps.find(valueMap => valueMap.tableName === subject.metadata.parentEntityMetadata.tableName);
|
||||
if (!valueMap) {
|
||||
valueMap = {
|
||||
tableName: subject.metadata.parentEntityMetadata.table.name,
|
||||
tableName: subject.metadata.parentEntityMetadata.tableName,
|
||||
metadata: subject.metadata.parentEntityMetadata,
|
||||
values: {}
|
||||
};
|
||||
@ -887,7 +887,7 @@ export class SubjectOperationExecutor {
|
||||
if (!idMap)
|
||||
throw new Error(`Internal error. Cannot get id of the updating entity.`);
|
||||
|
||||
return this.queryRunner.update(subject.metadata.table.name, values, idMap);
|
||||
return this.queryRunner.update(subject.metadata.tableName, values, idMap);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -910,15 +910,15 @@ export class SubjectOperationExecutor {
|
||||
subject.metadata.parentPrimaryColumns.forEach(column => {
|
||||
parentConditions[column.fullName] = subject.databaseEntity[column.propertyName];
|
||||
});
|
||||
await this.queryRunner.delete(subject.metadata.parentEntityMetadata.table.name, parentConditions);
|
||||
await this.queryRunner.delete(subject.metadata.parentEntityMetadata.tableName, parentConditions);
|
||||
|
||||
const childConditions: ObjectLiteral = {};
|
||||
subject.metadata.primaryColumnsWithParentIdColumns.forEach(column => {
|
||||
childConditions[column.fullName] = subject.databaseEntity[column.propertyName];
|
||||
});
|
||||
await this.queryRunner.delete(subject.metadata.table.name, childConditions);
|
||||
await this.queryRunner.delete(subject.metadata.tableName, childConditions);
|
||||
} else {
|
||||
await this.queryRunner.delete(subject.metadata.table.name, subject.metadata.getEntityIdColumnMap(subject.databaseEntity)!);
|
||||
await this.queryRunner.delete(subject.metadata.tableName, subject.metadata.getEntityIdColumnMap(subject.databaseEntity)!);
|
||||
}
|
||||
}
|
||||
|
||||
@ -985,7 +985,7 @@ export class SubjectOperationExecutor {
|
||||
const columns = relation.junctionEntityMetadata.columnsWithoutEmbeddeds.map(column => column.fullName);
|
||||
const values = relation.isOwning ? [...ownId, ...relationId] : [...relationId, ...ownId];
|
||||
|
||||
return this.queryRunner.insert(relation.junctionEntityMetadata.table.name, OrmUtils.zipObject(columns, values));
|
||||
return this.queryRunner.insert(relation.junctionEntityMetadata.tableName, OrmUtils.zipObject(columns, values));
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
@ -1029,7 +1029,7 @@ export class SubjectOperationExecutor {
|
||||
const joinColumn = secondJoinColumns.find(column => column.referencedColumn.propertyName === key);
|
||||
inverseConditions[joinColumn!.fullName] = entity[joinColumn!.referencedColumn.propertyName];
|
||||
});
|
||||
return this.queryRunner.delete(junctionMetadata.table.name, Object.assign({}, inverseConditions, conditions));
|
||||
return this.queryRunner.delete(junctionMetadata.tableName, Object.assign({}, inverseConditions, conditions));
|
||||
});
|
||||
|
||||
await Promise.all(removePromises);
|
||||
|
||||
@ -78,7 +78,7 @@ export class JoinAttribute {
|
||||
* Name of the table which we should join.
|
||||
*/
|
||||
get tableName(): string {
|
||||
return this.metadata ? this.metadata.table.name : this.entityOrProperty as string;
|
||||
return this.metadata ? this.metadata.tableName : this.entityOrProperty as string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -146,7 +146,7 @@ export class JoinAttribute {
|
||||
return metadata;
|
||||
|
||||
// check if we have entity with such table name, and use its metadata if found
|
||||
return this.connection.entityMetadatas.find(metadata => metadata.table.name === this.entityOrProperty);
|
||||
return this.connection.entityMetadatas.find(metadata => metadata.tableName === this.entityOrProperty);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
||||
@ -214,7 +214,7 @@ export class QueryBuilder<Entity> {
|
||||
fromTable(tableName: string, aliasName: string) {
|
||||
|
||||
// if table has a metadata then find it to properly escape its properties
|
||||
const metadata = this.connection.entityMetadatas.find(metadata => metadata.table.name === tableName);
|
||||
const metadata = this.connection.entityMetadatas.find(metadata => metadata.tableName === tableName);
|
||||
if (metadata) {
|
||||
this.expressionMap.createMainAlias({
|
||||
name: aliasName,
|
||||
@ -1256,7 +1256,7 @@ export class QueryBuilder<Entity> {
|
||||
const aliasName = this.expressionMap.mainAlias.name;
|
||||
|
||||
if (this.expressionMap.mainAlias.hasMetadata) {
|
||||
tableName = this.expressionMap.mainAlias.metadata.table.name;
|
||||
tableName = this.expressionMap.mainAlias.metadata.tableName;
|
||||
|
||||
allSelects.push(...this.buildEscapedEntityColumnSelects(aliasName, this.expressionMap.mainAlias.metadata));
|
||||
excludedSelects.push(...this.findEntityColumnSelects(aliasName, this.expressionMap.mainAlias.metadata));
|
||||
@ -1282,7 +1282,7 @@ export class QueryBuilder<Entity> {
|
||||
|
||||
if (!this.expressionMap.ignoreParentTablesJoins && this.expressionMap.mainAlias.hasMetadata) {
|
||||
if (this.expressionMap.mainAlias!.metadata.parentEntityMetadata && this.expressionMap.mainAlias!.metadata.parentIdColumns) {
|
||||
const alias = "parentIdColumn_" + ea(this.expressionMap.mainAlias!.metadata.parentEntityMetadata.table.name);
|
||||
const alias = "parentIdColumn_" + ea(this.expressionMap.mainAlias!.metadata.parentEntityMetadata.tableName);
|
||||
this.expressionMap.mainAlias!.metadata.parentEntityMetadata.columns.forEach(column => {
|
||||
// TODO implement partial select
|
||||
allSelects.push({ selection: ea(alias + "." + column.fullName), aliasName: alias + "_" + column.fullName });
|
||||
@ -1470,7 +1470,7 @@ export class QueryBuilder<Entity> {
|
||||
return " " + joinAttr.direction + " JOIN " + et(destinationTableName) + " " + ea(destinationTableAlias) + " ON " + condition + appendedCondition;
|
||||
|
||||
} else { // means many-to-many
|
||||
const junctionTableName = relation.junctionEntityMetadata.table.name;
|
||||
const junctionTableName = relation.junctionEntityMetadata.tableName;
|
||||
|
||||
const junctionAlias = joinAttr.junctionAlias;
|
||||
let junctionCondition = "", destinationCondition = "";
|
||||
@ -1509,8 +1509,8 @@ export class QueryBuilder<Entity> {
|
||||
if (!this.expressionMap.ignoreParentTablesJoins && this.expressionMap.mainAlias!.hasMetadata) {
|
||||
const metadata = this.expressionMap.mainAlias!.metadata;
|
||||
if (metadata.parentEntityMetadata && metadata.parentIdColumns) {
|
||||
const alias = "parentIdColumn_" + metadata.parentEntityMetadata.table.name;
|
||||
const parentJoin = " JOIN " + et(metadata.parentEntityMetadata.table.name) + " " + ea(alias) + " ON " +
|
||||
const alias = "parentIdColumn_" + metadata.parentEntityMetadata.tableName;
|
||||
const parentJoin = " JOIN " + et(metadata.parentEntityMetadata.tableName) + " " + ea(alias) + " ON " +
|
||||
metadata.parentIdColumns.map(parentIdColumn => {
|
||||
return this.expressionMap.mainAlias!.name + "." + parentIdColumn.fullName + "=" + ea(alias) + "." + parentIdColumn.propertyName;
|
||||
});
|
||||
@ -1531,7 +1531,7 @@ export class QueryBuilder<Entity> {
|
||||
// if table has a default order then apply it
|
||||
let orderBys = this.expressionMap.orderBys;
|
||||
if (!Object.keys(orderBys).length && this.expressionMap.mainAlias!.hasMetadata) {
|
||||
orderBys = this.expressionMap.mainAlias!.metadata.table.orderBy || {};
|
||||
orderBys = this.expressionMap.mainAlias!.metadata.orderBy || {};
|
||||
}
|
||||
|
||||
const selectString = Object.keys(orderBys)
|
||||
@ -1557,7 +1557,7 @@ export class QueryBuilder<Entity> {
|
||||
|
||||
// if table has a default order then apply it
|
||||
if (!Object.keys(orderBys).length && this.expressionMap.mainAlias!.hasMetadata) {
|
||||
orderBys = this.expressionMap.mainAlias!.metadata.table.orderBy || {};
|
||||
orderBys = this.expressionMap.mainAlias!.metadata.orderBy || {};
|
||||
}
|
||||
|
||||
// if user specified a custom order then apply it
|
||||
|
||||
@ -33,8 +33,8 @@ export class RelationCountLoader {
|
||||
const relation = relationCountAttr.relation; // "category.posts"
|
||||
const inverseRelation = relation.inverseRelation; // "post.category"
|
||||
const referenceColumnName = inverseRelation.joinColumns[0].referencedColumn.propertyName; // post id
|
||||
const inverseSideTable = relation.inverseEntityMetadata.table.target; // Post
|
||||
const inverseSideTableName = relation.inverseEntityMetadata.table.name; // post
|
||||
const inverseSideTable = relation.inverseEntityMetadata.target; // Post
|
||||
const inverseSideTableName = relation.inverseEntityMetadata.tableName; // post
|
||||
const inverseSideTableAlias = relationCountAttr.alias || inverseSideTableName; // if condition (custom query builder factory) is set then relationIdAttr.alias defined
|
||||
const inverseSidePropertyName = inverseRelation.propertyName; // "category" from "post.category"
|
||||
|
||||
@ -100,9 +100,9 @@ export class RelationCountLoader {
|
||||
return { relationCountAttribute: relationCountAttr, results: [] };
|
||||
|
||||
const junctionAlias = relationCountAttr.junctionAlias;
|
||||
const inverseSideTableName = relationCountAttr.joinInverseSideMetadata.table.name;
|
||||
const inverseSideTableName = relationCountAttr.joinInverseSideMetadata.tableName;
|
||||
const inverseSideTableAlias = relationCountAttr.alias || inverseSideTableName;
|
||||
const junctionTableName = relationCountAttr.relation.junctionEntityMetadata.table.name;
|
||||
const junctionTableName = relationCountAttr.relation.junctionEntityMetadata.tableName;
|
||||
const condition = junctionAlias + "." + firstJunctionColumn.propertyName + " IN (" + referenceColumnValues + ")" +
|
||||
" AND " + junctionAlias + "." + secondJunctionColumn.propertyName + " = " + inverseSideTableAlias + "." + inverseJoinColumnName;
|
||||
|
||||
|
||||
@ -56,8 +56,8 @@ export class RelationIdLoader {
|
||||
const relation = relationIdAttr.relation; // "category.posts"
|
||||
const inverseRelation = relation.inverseRelation; // "post.category"
|
||||
const referenceColumnName = inverseRelation.joinColumns[0].referencedColumn.propertyName; // post id
|
||||
const inverseSideTable = relation.inverseEntityMetadata.table.target; // Post
|
||||
const inverseSideTableName = relation.inverseEntityMetadata.table.name; // post
|
||||
const inverseSideTable = relation.inverseEntityMetadata.target; // Post
|
||||
const inverseSideTableName = relation.inverseEntityMetadata.tableName; // post
|
||||
const inverseSideTableAlias = relationIdAttr.alias || inverseSideTableName; // if condition (custom query builder factory) is set then relationIdAttr.alias defined
|
||||
const inverseSidePropertyName = inverseRelation.propertyName; // "category" from "post.category"
|
||||
|
||||
@ -162,9 +162,9 @@ export class RelationIdLoader {
|
||||
return { relationIdAttribute: relationIdAttr, results: [] };
|
||||
|
||||
const junctionAlias = relationIdAttr.junctionAlias;
|
||||
const inverseSideTableName = relationIdAttr.joinInverseSideMetadata.table.name;
|
||||
const inverseSideTableName = relationIdAttr.joinInverseSideMetadata.tableName;
|
||||
const inverseSideTableAlias = relationIdAttr.alias || inverseSideTableName;
|
||||
const junctionTableName = relationIdAttr.relation.junctionEntityMetadata.table.name;
|
||||
const junctionTableName = relationIdAttr.relation.junctionEntityMetadata.tableName;
|
||||
const condition = junctionAlias + "." + firstJunctionColumn.propertyName + " IN (" + referenceColumnValues + ")" +
|
||||
" AND " + junctionAlias + "." + secondJunctionColumn.propertyName + " = " + inverseSideTableAlias + "." + inverseJoinColumnName;
|
||||
|
||||
|
||||
@ -9,36 +9,38 @@ import {DocumentToEntityTransformer} from "../query-builder/transformer/Document
|
||||
import {FindOneOptions} from "../find-options/FindOneOptions";
|
||||
import {FindOptionsUtils} from "../find-options/FindOptionsUtils";
|
||||
import {
|
||||
Cursor,
|
||||
Collection,
|
||||
MongoCountPreferences,
|
||||
CollectionAggregationOptions,
|
||||
AggregationCursor,
|
||||
CollectionBluckWriteOptions,
|
||||
BulkWriteOpResultObject,
|
||||
IndexOptions,
|
||||
Code,
|
||||
Collection,
|
||||
CollectionAggregationOptions,
|
||||
CollectionBluckWriteOptions,
|
||||
CollectionInsertManyOptions,
|
||||
CollectionInsertOneOptions,
|
||||
CollectionOptions,
|
||||
CollStats,
|
||||
CommandCursor,
|
||||
Cursor,
|
||||
CursorResult,
|
||||
DeleteWriteOpResultObject,
|
||||
FindAndModifyWriteOpResultObject,
|
||||
FindOneAndReplaceOption,
|
||||
GeoHaystackSearchOptions,
|
||||
GeoNearOptions,
|
||||
ReadPreference,
|
||||
Code,
|
||||
OrderedBulkOperation,
|
||||
UnorderedBulkOperation,
|
||||
InsertWriteOpResult,
|
||||
CollectionInsertManyOptions,
|
||||
CollectionInsertOneOptions,
|
||||
IndexOptions,
|
||||
InsertOneWriteOpResult,
|
||||
CommandCursor,
|
||||
InsertWriteOpResult,
|
||||
MapReduceOptions,
|
||||
MongoCallback,
|
||||
MongoCountPreferences,
|
||||
MongoError,
|
||||
OrderedBulkOperation,
|
||||
ParallelCollectionScanOptions,
|
||||
ReadPreference,
|
||||
ReplaceOneOptions,
|
||||
UpdateWriteOpResult,
|
||||
CollStats, MongoCallback, MongoError, CursorResult
|
||||
UnorderedBulkOperation,
|
||||
UpdateWriteOpResult
|
||||
} from "mongodb";
|
||||
import {DeepPartial} from "../common/DeepPartial";
|
||||
|
||||
/**
|
||||
* Repository used to manage mongodb documents of a single entity type.
|
||||
@ -110,7 +112,7 @@ export class MongoRepository<Entity extends ObjectLiteral> extends Repository<En
|
||||
}
|
||||
const [results, count] = await Promise.all<any>([
|
||||
cursor.toArray(),
|
||||
this.queryRunner.count(this.metadata.table.name, query),
|
||||
this.queryRunner.count(this.metadata.tableName, query),
|
||||
]);
|
||||
return [results, parseInt(count)];
|
||||
}
|
||||
@ -173,7 +175,7 @@ export class MongoRepository<Entity extends ObjectLiteral> extends Repository<En
|
||||
* Creates a cursor for a query that can be used to iterate over results from MongoDB.
|
||||
*/
|
||||
createCursor(query?: ObjectLiteral): Cursor<Entity> {
|
||||
return this.queryRunner.cursor(this.metadata.table.name, query);
|
||||
return this.queryRunner.cursor(this.metadata.tableName, query);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -227,28 +229,28 @@ export class MongoRepository<Entity extends ObjectLiteral> extends Repository<En
|
||||
* Execute an aggregation framework pipeline against the collection.
|
||||
*/
|
||||
aggregate(pipeline: ObjectLiteral[], options?: CollectionAggregationOptions): AggregationCursor<Entity> {
|
||||
return this.queryRunner.aggregate(this.metadata.table.name, pipeline, options);
|
||||
return this.queryRunner.aggregate(this.metadata.tableName, pipeline, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a bulkWrite operation without a fluent API.
|
||||
*/
|
||||
async bulkWrite(operations: ObjectLiteral[], options?: CollectionBluckWriteOptions): Promise<BulkWriteOpResultObject> {
|
||||
return await this.queryRunner.bulkWrite(this.metadata.table.name, operations, options);
|
||||
return await this.queryRunner.bulkWrite(this.metadata.tableName, operations, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count number of matching documents in the db to a query.
|
||||
*/
|
||||
async count(query?: ObjectLiteral, options?: MongoCountPreferences): Promise<any> {
|
||||
return await this.queryRunner.count(this.metadata.table.name, query || {}, options);
|
||||
return await this.queryRunner.count(this.metadata.tableName, query || {}, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an index on the db and collection.
|
||||
*/
|
||||
async createCollectionIndex(fieldOrSpec: string|any, options?: IndexOptions): Promise<string> {
|
||||
return await this.queryRunner.createCollectionIndex(this.metadata.table.name, fieldOrSpec, options);
|
||||
return await this.queryRunner.createCollectionIndex(this.metadata.tableName, fieldOrSpec, options);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -257,154 +259,154 @@ export class MongoRepository<Entity extends ObjectLiteral> extends Repository<En
|
||||
* Index specifications are defined at http://docs.mongodb.org/manual/reference/command/createIndexes/.
|
||||
*/
|
||||
async createCollectionIndexes(indexSpecs: ObjectLiteral[]): Promise<void> {
|
||||
return await this.queryRunner.createCollectionIndexes(this.metadata.table.name, indexSpecs);
|
||||
return await this.queryRunner.createCollectionIndexes(this.metadata.tableName, indexSpecs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete multiple documents on MongoDB.
|
||||
*/
|
||||
async deleteMany(query: ObjectLiteral, options?: CollectionOptions): Promise<DeleteWriteOpResultObject> {
|
||||
return await this.queryRunner.deleteMany(this.metadata.table.name, query, options);
|
||||
return await this.queryRunner.deleteMany(this.metadata.tableName, query, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a document on MongoDB.
|
||||
*/
|
||||
async deleteOne(query: ObjectLiteral, options?: CollectionOptions): Promise<DeleteWriteOpResultObject> {
|
||||
return await this.queryRunner.deleteOne(this.metadata.table.name, query, options);
|
||||
return await this.queryRunner.deleteOne(this.metadata.tableName, query, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* The distinct command returns returns a list of distinct values for the given key across a collection.
|
||||
*/
|
||||
async distinct(key: string, query: ObjectLiteral, options?: { readPreference?: ReadPreference|string }): Promise<any> {
|
||||
return await this.queryRunner.distinct(this.metadata.table.name, key, query, options);
|
||||
return await this.queryRunner.distinct(this.metadata.tableName, key, query, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops an index from this collection.
|
||||
*/
|
||||
async dropCollectionIndex(indexName: string, options?: CollectionOptions): Promise<any> {
|
||||
return await this.queryRunner.dropCollectionIndex(this.metadata.table.name, indexName, options);
|
||||
return await this.queryRunner.dropCollectionIndex(this.metadata.tableName, indexName, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops all indexes from the collection.
|
||||
*/
|
||||
async dropCollectionIndexes(): Promise<any> {
|
||||
return await this.queryRunner.dropCollectionIndexes(this.metadata.table.name);
|
||||
return await this.queryRunner.dropCollectionIndexes(this.metadata.tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a document and delete it in one atomic operation, requires a write lock for the duration of the operation.
|
||||
*/
|
||||
async findOneAndDelete(query: ObjectLiteral, options?: { projection?: Object, sort?: Object, maxTimeMS?: number }): Promise<FindAndModifyWriteOpResultObject> {
|
||||
return await this.queryRunner.findOneAndDelete(this.metadata.table.name, query, options);
|
||||
return await this.queryRunner.findOneAndDelete(this.metadata.tableName, query, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a document and replace it in one atomic operation, requires a write lock for the duration of the operation.
|
||||
*/
|
||||
async findOneAndReplace(query: ObjectLiteral, replacement: Object, options?: FindOneAndReplaceOption): Promise<FindAndModifyWriteOpResultObject> {
|
||||
return await this.queryRunner.findOneAndReplace(this.metadata.table.name, query, replacement, options);
|
||||
return await this.queryRunner.findOneAndReplace(this.metadata.tableName, query, replacement, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a document and update it in one atomic operation, requires a write lock for the duration of the operation.
|
||||
*/
|
||||
async findOneAndUpdate(query: ObjectLiteral, update: Object, options?: FindOneAndReplaceOption): Promise<FindAndModifyWriteOpResultObject> {
|
||||
return await this.queryRunner.findOneAndUpdate(this.metadata.table.name, query, update, options);
|
||||
return await this.queryRunner.findOneAndUpdate(this.metadata.tableName, query, update, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a geo search using a geo haystack index on a collection.
|
||||
*/
|
||||
async geoHaystackSearch(x: number, y: number, options?: GeoHaystackSearchOptions): Promise<any> {
|
||||
return await this.queryRunner.geoHaystackSearch(this.metadata.table.name, x, y, options);
|
||||
return await this.queryRunner.geoHaystackSearch(this.metadata.tableName, x, y, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the geoNear command to search for items in the collection.
|
||||
*/
|
||||
async geoNear(x: number, y: number, options?: GeoNearOptions): Promise<any> {
|
||||
return await this.queryRunner.geoNear(this.metadata.table.name, x, y, options);
|
||||
return await this.queryRunner.geoNear(this.metadata.tableName, x, y, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a group command across a collection.
|
||||
*/
|
||||
async group(keys: Object|Array<any>|Function|Code, condition: Object, initial: Object, reduce: Function|Code, finalize: Function|Code, command: boolean, options?: { readPreference?: ReadPreference | string }): Promise<any> {
|
||||
return await this.queryRunner.group(this.metadata.table.name, keys, condition, initial, reduce, finalize, command, options);
|
||||
return await this.queryRunner.group(this.metadata.tableName, keys, condition, initial, reduce, finalize, command, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all the indexes on the collection.
|
||||
*/
|
||||
async collectionIndexes(): Promise<any> {
|
||||
return await this.queryRunner.collectionIndexes(this.metadata.table.name);
|
||||
return await this.queryRunner.collectionIndexes(this.metadata.tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all the indexes on the collection.
|
||||
*/
|
||||
async collectionIndexExists(indexes: string|string[]): Promise<boolean> {
|
||||
return await this.queryRunner.collectionIndexExists(this.metadata.table.name, indexes);
|
||||
return await this.queryRunner.collectionIndexExists(this.metadata.tableName, indexes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves this collections index info.
|
||||
*/
|
||||
async collectionIndexInformation(options?: { full: boolean }): Promise<any> {
|
||||
return await this.queryRunner.collectionIndexInformation(this.metadata.table.name, options);
|
||||
return await this.queryRunner.collectionIndexInformation(this.metadata.tableName, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate an In order bulk write operation, operations will be serially executed in the order they are added, creating a new operation for each switch in types.
|
||||
*/
|
||||
initializeOrderedBulkOp(options?: CollectionOptions): OrderedBulkOperation {
|
||||
return this.queryRunner.initializeOrderedBulkOp(this.metadata.table.name, options);
|
||||
return this.queryRunner.initializeOrderedBulkOp(this.metadata.tableName, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate a Out of order batch write operation. All operations will be buffered into insert/update/remove commands executed out of order.
|
||||
*/
|
||||
initializeUnorderedBulkOp(options?: CollectionOptions): UnorderedBulkOperation {
|
||||
return this.queryRunner.initializeUnorderedBulkOp(this.metadata.table.name, options);
|
||||
return this.queryRunner.initializeUnorderedBulkOp(this.metadata.tableName, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an array of documents into MongoDB.
|
||||
*/
|
||||
async insertMany(docs: ObjectLiteral[], options?: CollectionInsertManyOptions): Promise<InsertWriteOpResult> {
|
||||
return await this.queryRunner.insertMany(this.metadata.table.name, docs, options);
|
||||
return await this.queryRunner.insertMany(this.metadata.tableName, docs, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a single document into MongoDB.
|
||||
*/
|
||||
async insertOne(doc: ObjectLiteral, options?: CollectionInsertOneOptions): Promise<InsertOneWriteOpResult> {
|
||||
return await this.queryRunner.insertOne(this.metadata.table.name, doc, options);
|
||||
return await this.queryRunner.insertOne(this.metadata.tableName, doc, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the collection is a capped collection.
|
||||
*/
|
||||
async isCapped(): Promise<any> {
|
||||
return await this.queryRunner.isCapped(this.metadata.table.name);
|
||||
return await this.queryRunner.isCapped(this.metadata.tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of all indexes information for the collection.
|
||||
*/
|
||||
listCollectionIndexes(options?: { batchSize?: number, readPreference?: ReadPreference|string }): CommandCursor {
|
||||
return this.queryRunner.listCollectionIndexes(this.metadata.table.name, options);
|
||||
return this.queryRunner.listCollectionIndexes(this.metadata.tableName, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Map Reduce across a collection. Be aware that the inline option for out will return an array of results not a collection.
|
||||
*/
|
||||
async mapReduce(map: Function|string, reduce: Function|string, options?: MapReduceOptions): Promise<any> {
|
||||
return await this.queryRunner.mapReduce(this.metadata.table.name, map, reduce, options);
|
||||
return await this.queryRunner.mapReduce(this.metadata.tableName, map, reduce, options);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -412,49 +414,49 @@ export class MongoRepository<Entity extends ObjectLiteral> extends Repository<En
|
||||
* There are no ordering guarantees for returned results.
|
||||
*/
|
||||
async parallelCollectionScan(options?: ParallelCollectionScanOptions): Promise<Cursor<Entity>[]> {
|
||||
return await this.queryRunner.parallelCollectionScan(this.metadata.table.name, options);
|
||||
return await this.queryRunner.parallelCollectionScan(this.metadata.tableName, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reindex all indexes on the collection Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections.
|
||||
*/
|
||||
async reIndex(): Promise<any> {
|
||||
return await this.queryRunner.reIndex(this.metadata.table.name);
|
||||
return await this.queryRunner.reIndex(this.metadata.tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reindex all indexes on the collection Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections.
|
||||
*/
|
||||
async rename(newName: string, options?: { dropTarget?: boolean }): Promise<Collection> {
|
||||
return await this.queryRunner.rename(this.metadata.table.name, newName, options);
|
||||
return await this.queryRunner.rename(this.metadata.tableName, newName, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace a document on MongoDB.
|
||||
*/
|
||||
async replaceOne(query: ObjectLiteral, doc: ObjectLiteral, options?: ReplaceOneOptions): Promise<UpdateWriteOpResult> {
|
||||
return await this.queryRunner.replaceOne(this.metadata.table.name, query, doc, options);
|
||||
return await this.queryRunner.replaceOne(this.metadata.tableName, query, doc, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the collection statistics.
|
||||
*/
|
||||
async stats(options?: { scale: number }): Promise<CollStats> {
|
||||
return await this.queryRunner.stats(this.metadata.table.name, options);
|
||||
return await this.queryRunner.stats(this.metadata.tableName, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update multiple documents on MongoDB.
|
||||
*/
|
||||
async updateMany(query: ObjectLiteral, update: ObjectLiteral, options?: { upsert?: boolean, w?: any, wtimeout?: number, j?: boolean }): Promise<UpdateWriteOpResult> {
|
||||
return await this.queryRunner.updateMany(this.metadata.table.name, query, update, options);
|
||||
return await this.queryRunner.updateMany(this.metadata.tableName, query, update, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a single document on MongoDB.
|
||||
*/
|
||||
async updateOne(query: ObjectLiteral, update: ObjectLiteral, options?: ReplaceOneOptions): Promise<UpdateWriteOpResult> {
|
||||
return await this.queryRunner.updateOne(this.metadata.table.name, query, update, options);
|
||||
return await this.queryRunner.updateOne(this.metadata.tableName, query, update, options);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -279,7 +279,7 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
* Counts entities that match given find options or conditions.
|
||||
*/
|
||||
count(optionsOrConditions?: FindManyOptions<Entity>|DeepPartial<Entity>): Promise<number> {
|
||||
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || this.metadata.table.name);
|
||||
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || this.metadata.tableName);
|
||||
return FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions).getCount();
|
||||
}
|
||||
|
||||
@ -297,7 +297,7 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
* Finds entities that match given find options or conditions.
|
||||
*/
|
||||
find(optionsOrConditions?: FindManyOptions<Entity>|DeepPartial<Entity>): Promise<Entity[]> {
|
||||
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || this.metadata.table.name);
|
||||
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || this.metadata.tableName);
|
||||
return FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions).getMany();
|
||||
}
|
||||
|
||||
@ -321,7 +321,7 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
* but ignores pagination settings (from and take options).
|
||||
*/
|
||||
findAndCount(optionsOrConditions?: FindManyOptions<Entity>|DeepPartial<Entity>): Promise<[ Entity[], number ]> {
|
||||
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || this.metadata.table.name);
|
||||
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || this.metadata.tableName);
|
||||
return FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions).getManyAndCount();
|
||||
}
|
||||
|
||||
@ -342,7 +342,7 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
* Optionally find options can be applied.
|
||||
*/
|
||||
findByIds(ids: any[], optionsOrConditions?: FindManyOptions<Entity>|DeepPartial<Entity>): Promise<Entity[]> {
|
||||
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || this.metadata.table.name);
|
||||
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || this.metadata.tableName);
|
||||
return FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions)
|
||||
.andWhereInIds(ids)
|
||||
.getMany();
|
||||
@ -362,7 +362,7 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
* Finds first entity that matches given conditions.
|
||||
*/
|
||||
findOne(optionsOrConditions?: FindOneOptions<Entity>|DeepPartial<Entity>): Promise<Entity|undefined> {
|
||||
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindOneOptionsAlias(optionsOrConditions) || this.metadata.table.name);
|
||||
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindOneOptionsAlias(optionsOrConditions) || this.metadata.tableName);
|
||||
return FindOptionsUtils.applyFindOneOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions).getOne();
|
||||
}
|
||||
|
||||
@ -383,7 +383,7 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
* Optionally find options or conditions can be applied.
|
||||
*/
|
||||
findOneById(id: any, optionsOrConditions?: FindOneOptions<Entity>|DeepPartial<Entity>): Promise<Entity|undefined> {
|
||||
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindOneOptionsAlias(optionsOrConditions) || this.metadata.table.name);
|
||||
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindOneOptionsAlias(optionsOrConditions) || this.metadata.tableName);
|
||||
return FindOptionsUtils.applyFindOneOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions)
|
||||
.andWhereInIds([id])
|
||||
.getOne();
|
||||
@ -451,7 +451,7 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
const queryRunnerProvider = this.queryRunnerProvider || new QueryRunnerProvider(this.connection.driver);
|
||||
const queryRunner = await queryRunnerProvider.provide();
|
||||
try {
|
||||
return await queryRunner.truncate(this.metadata.table.name); // await is needed here because we are using finally
|
||||
return await queryRunner.truncate(this.metadata.tableName); // await is needed here because we are using finally
|
||||
|
||||
} finally {
|
||||
await queryRunnerProvider.release(queryRunner);
|
||||
|
||||
@ -45,7 +45,7 @@ export class RepositoryAggregator {
|
||||
|
||||
const factory = getFromContainer(RepositoryFactory);
|
||||
|
||||
if (metadata.table.isClosure) {
|
||||
if (metadata.isClosure) {
|
||||
this.repository = this.treeRepository = factory.createTreeRepository(connection, metadata, queryRunnerProvider);
|
||||
} else {
|
||||
this.repository = factory.createRepository(connection, metadata, queryRunnerProvider);
|
||||
|
||||
@ -61,11 +61,11 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
|
||||
let table: string, values: any = {}, conditions: any = {};
|
||||
if (relation.isOwning) {
|
||||
table = relation.entityMetadata.table.name;
|
||||
table = relation.entityMetadata.tableName;
|
||||
values[relation.name] = relatedEntityId;
|
||||
conditions[relation.joinColumns[0].referencedColumn.fullName] = entityId;
|
||||
} else {
|
||||
table = relation.inverseEntityMetadata.table.name;
|
||||
table = relation.inverseEntityMetadata.tableName;
|
||||
values[relation.inverseRelation.name] = relatedEntityId;
|
||||
conditions[relation.inverseRelation.joinColumns[0].referencedColumn.fullName] = entityId;
|
||||
}
|
||||
@ -112,11 +112,11 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
|
||||
let table: string, values: any = {}, conditions: any = {};
|
||||
if (relation.isOwning) {
|
||||
table = relation.inverseEntityMetadata.table.name;
|
||||
table = relation.inverseEntityMetadata.tableName;
|
||||
values[relation.inverseRelation.name] = relatedEntityId;
|
||||
conditions[relation.inverseRelation.joinColumns[0].referencedColumn.fullName] = entityId;
|
||||
} else {
|
||||
table = relation.entityMetadata.table.name;
|
||||
table = relation.entityMetadata.tableName;
|
||||
values[relation.name] = relatedEntityId;
|
||||
conditions[relation.joinColumns[0].referencedColumn.fullName] = entityId;
|
||||
}
|
||||
@ -168,7 +168,7 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
values[relation.junctionEntityMetadata.columns[0].fullName] = relatedEntityId;
|
||||
}
|
||||
|
||||
return queryRunner.insert(relation.junctionEntityMetadata.table.name, values);
|
||||
return queryRunner.insert(relation.junctionEntityMetadata.tableName, values);
|
||||
});
|
||||
await Promise.all(insertPromises);
|
||||
|
||||
@ -218,7 +218,7 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
values[relation.junctionEntityMetadata.columns[0].fullName] = relatedEntityId;
|
||||
}
|
||||
|
||||
return queryRunner.insert(relation.junctionEntityMetadata.table.name, values);
|
||||
return queryRunner.insert(relation.junctionEntityMetadata.tableName, values);
|
||||
});
|
||||
await Promise.all(insertPromises);
|
||||
|
||||
@ -262,7 +262,7 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
|
||||
const qb = new QueryBuilder(this.connection, this.queryRunnerProvider)
|
||||
.delete()
|
||||
.fromTable(relation.junctionEntityMetadata.table.name, "junctionEntity");
|
||||
.fromTable(relation.junctionEntityMetadata.tableName, "junctionEntity");
|
||||
|
||||
const firstColumnName = this.connection.driver.escapeColumnName(relation.isOwning ? relation.junctionEntityMetadata.columns[0].fullName : relation.junctionEntityMetadata.columns[1].fullName);
|
||||
const secondColumnName = this.connection.driver.escapeColumnName(relation.isOwning ? relation.junctionEntityMetadata.columns[1].fullName : relation.junctionEntityMetadata.columns[0].fullName);
|
||||
@ -311,7 +311,7 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
|
||||
const qb = new QueryBuilder(this.connection, this.queryRunnerProvider)
|
||||
.delete()
|
||||
.from(relation.junctionEntityMetadata.table.name, "junctionEntity");
|
||||
.from(relation.junctionEntityMetadata.tableName, "junctionEntity");
|
||||
|
||||
const firstColumnName = relation.isOwning ? relation.junctionEntityMetadata.columns[1].fullName : relation.junctionEntityMetadata.columns[0].fullName;
|
||||
const secondColumnName = relation.isOwning ? relation.junctionEntityMetadata.columns[0].fullName : relation.junctionEntityMetadata.columns[1].fullName;
|
||||
@ -381,7 +381,7 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation.
|
||||
*/
|
||||
async removeById(id: any): Promise<void> {
|
||||
const alias = this.metadata.table.name;
|
||||
const alias = this.metadata.tableName;
|
||||
const parameters: ObjectLiteral = {};
|
||||
let condition = "";
|
||||
|
||||
@ -408,7 +408,7 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation.
|
||||
*/
|
||||
async removeByIds(ids: any[]): Promise<void> {
|
||||
const alias = this.metadata.table.name;
|
||||
const alias = this.metadata.tableName;
|
||||
const parameters: ObjectLiteral = {};
|
||||
let condition = "";
|
||||
|
||||
@ -464,7 +464,7 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
inverseEntityColumnNames.forEach(columnName => {
|
||||
qb.select(ea("junction") + "." + ec(columnName) + " AS " + ea(columnName));
|
||||
});
|
||||
qb.fromTable(relation.junctionEntityMetadata.table.name, "junction");
|
||||
qb.fromTable(relation.junctionEntityMetadata.tableName, "junction");
|
||||
Object.keys(entityId).forEach((columnName) => {
|
||||
const junctionColumnName = ownerEntityColumns.find(joinColumn => joinColumn.referencedColumn.name === columnName);
|
||||
qb.andWhere(ea("junction") + "." + ec(junctionColumnName!.name) + "=:" + junctionColumnName!.name + "_entityId", {[junctionColumnName!.name + "_entityId"]: entityId[columnName]});
|
||||
|
||||
@ -49,7 +49,7 @@ export class TreeRepository<Entity> extends Repository<Entity> {
|
||||
|
||||
const joinCondition = `${escapeAlias(alias)}.${escapeColumn(this.metadata.firstPrimaryColumn.fullName)}=${escapeAlias(closureTableAlias)}.${escapeColumn("descendant")}`;
|
||||
return this.createQueryBuilder(alias)
|
||||
.innerJoin(this.metadata.closureJunctionTable.table.name, closureTableAlias, joinCondition)
|
||||
.innerJoin(this.metadata.closureJunctionTable.tableName, closureTableAlias, joinCondition)
|
||||
.where(`${escapeAlias(closureTableAlias)}.${escapeColumn("ancestor")}=${this.metadata.getEntityIdMap(entity)![this.metadata.firstPrimaryColumn.propertyName]}`);
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ export class TreeRepository<Entity> extends Repository<Entity> {
|
||||
|
||||
const joinCondition = `${escapeAlias(alias)}.${escapeColumn(this.metadata.firstPrimaryColumn.fullName)}=${escapeAlias(closureTableAlias)}.${escapeColumn("ancestor")}`;
|
||||
return this.createQueryBuilder(alias)
|
||||
.innerJoin(this.metadata.closureJunctionTable.table.name, closureTableAlias, joinCondition)
|
||||
.innerJoin(this.metadata.closureJunctionTable.tableName, closureTableAlias, joinCondition)
|
||||
.where(`${escapeAlias(closureTableAlias)}.${escapeColumn("descendant")}=${this.metadata.getEntityIdMap(entity)![this.metadata.firstPrimaryColumn.propertyName]}`);
|
||||
}
|
||||
|
||||
|
||||
@ -94,14 +94,14 @@ export class SchemaBuilder {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
protected get entityToSyncMetadatas(): EntityMetadata[] {
|
||||
return this.entityMetadatas.filter(metadata => !metadata.table.skipSchemaSync);
|
||||
return this.entityMetadatas.filter(metadata => !metadata.skipSchemaSync);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all table schemas from the database.
|
||||
*/
|
||||
protected loadTableSchemas(): Promise<TableSchema[]> {
|
||||
const tableNames = this.entityToSyncMetadatas.map(metadata => metadata.table.name);
|
||||
const tableNames = this.entityToSyncMetadatas.map(metadata => metadata.tableName);
|
||||
return this.queryRunner.loadTableSchemas(tableNames);
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ export class SchemaBuilder {
|
||||
protected async dropOldForeignKeys(): Promise<void> {
|
||||
await PromiseUtils.runInSequence(this.entityToSyncMetadatas, async metadata => {
|
||||
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.table.name);
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.tableName);
|
||||
if (!tableSchema)
|
||||
return;
|
||||
|
||||
@ -140,14 +140,14 @@ export class SchemaBuilder {
|
||||
protected async createNewTables(): Promise<void> {
|
||||
await PromiseUtils.runInSequence(this.entityToSyncMetadatas, async metadata => {
|
||||
// check if table does not exist yet
|
||||
const existTableSchema = this.tableSchemas.find(table => table.name === metadata.table.name);
|
||||
const existTableSchema = this.tableSchemas.find(table => table.name === metadata.tableName);
|
||||
if (existTableSchema)
|
||||
return;
|
||||
|
||||
this.logger.logSchemaBuild(`creating a new table: ${metadata.table.name}`);
|
||||
this.logger.logSchemaBuild(`creating a new table: ${metadata.tableName}`);
|
||||
|
||||
// create a new table schema and sync it in the database
|
||||
const tableSchema = new TableSchema(metadata.table.name, this.metadataColumnsToColumnSchemas(metadata.columns), true);
|
||||
const tableSchema = new TableSchema(metadata.tableName, this.metadataColumnsToColumnSchemas(metadata.columns), true);
|
||||
this.tableSchemas.push(tableSchema);
|
||||
await this.queryRunner.createTable(tableSchema);
|
||||
});
|
||||
@ -159,7 +159,7 @@ export class SchemaBuilder {
|
||||
*/
|
||||
protected dropRemovedColumns() {
|
||||
return PromiseUtils.runInSequence(this.entityToSyncMetadatas, async metadata => {
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.table.name);
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.tableName);
|
||||
if (!tableSchema) return;
|
||||
|
||||
// find columns that exist in the database but does not exist in the metadata
|
||||
@ -171,12 +171,12 @@ export class SchemaBuilder {
|
||||
|
||||
// drop all foreign keys that has column to be removed in its columns
|
||||
await Promise.all(droppedColumnSchemas.map(droppedColumnSchema => {
|
||||
return this.dropColumnReferencedForeignKeys(metadata.table.name, droppedColumnSchema.name);
|
||||
return this.dropColumnReferencedForeignKeys(metadata.tableName, droppedColumnSchema.name);
|
||||
}));
|
||||
|
||||
// drop all indices that point to this column
|
||||
await Promise.all(droppedColumnSchemas.map(droppedColumnSchema => {
|
||||
return this.dropColumnReferencedIndices(metadata.table.name, droppedColumnSchema.name);
|
||||
return this.dropColumnReferencedIndices(metadata.tableName, droppedColumnSchema.name);
|
||||
}));
|
||||
|
||||
this.logger.logSchemaBuild(`columns dropped in ${tableSchema.name}: ` + droppedColumnSchemas.map(column => column.name).join(", "));
|
||||
@ -196,7 +196,7 @@ export class SchemaBuilder {
|
||||
*/
|
||||
protected addNewColumns() {
|
||||
return PromiseUtils.runInSequence(this.entityToSyncMetadatas, async metadata => {
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.table.name);
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.tableName);
|
||||
if (!tableSchema)
|
||||
return;
|
||||
|
||||
@ -222,7 +222,7 @@ export class SchemaBuilder {
|
||||
*/
|
||||
protected updateExistColumns() {
|
||||
return PromiseUtils.runInSequence(this.entityToSyncMetadatas, async metadata => {
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.table.name);
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.tableName);
|
||||
if (!tableSchema)
|
||||
return;
|
||||
|
||||
@ -235,7 +235,7 @@ export class SchemaBuilder {
|
||||
// drop all foreign keys that point to this column
|
||||
const dropRelatedForeignKeysPromises = updatedColumnSchemas
|
||||
.filter(changedColumnSchema => !!metadata.columns.find(columnMetadata => columnMetadata.fullName === changedColumnSchema.name))
|
||||
.map(changedColumnSchema => this.dropColumnReferencedForeignKeys(metadata.table.name, changedColumnSchema.name));
|
||||
.map(changedColumnSchema => this.dropColumnReferencedForeignKeys(metadata.tableName, changedColumnSchema.name));
|
||||
|
||||
// wait until all related foreign keys are dropped
|
||||
await Promise.all(dropRelatedForeignKeysPromises);
|
||||
@ -243,7 +243,7 @@ export class SchemaBuilder {
|
||||
// drop all indices that point to this column
|
||||
const dropRelatedIndicesPromises = updatedColumnSchemas
|
||||
.filter(changedColumnSchema => !!metadata.columns.find(columnMetadata => columnMetadata.fullName === changedColumnSchema.name))
|
||||
.map(changedColumnSchema => this.dropColumnReferencedIndices(metadata.table.name, changedColumnSchema.name));
|
||||
.map(changedColumnSchema => this.dropColumnReferencedIndices(metadata.tableName, changedColumnSchema.name));
|
||||
|
||||
// wait until all related indices are dropped
|
||||
await Promise.all(dropRelatedIndicesPromises);
|
||||
@ -269,7 +269,7 @@ export class SchemaBuilder {
|
||||
*/
|
||||
protected updatePrimaryKeys() {
|
||||
return PromiseUtils.runInSequence(this.entityToSyncMetadatas, async metadata => {
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.table.name && !table.justCreated);
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.tableName && !table.justCreated);
|
||||
if (!tableSchema)
|
||||
return;
|
||||
|
||||
@ -299,7 +299,7 @@ export class SchemaBuilder {
|
||||
*/
|
||||
protected createForeignKeys() {
|
||||
return PromiseUtils.runInSequence(this.entityToSyncMetadatas, async metadata => {
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.table.name);
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.tableName);
|
||||
if (!tableSchema)
|
||||
return;
|
||||
|
||||
@ -323,7 +323,7 @@ export class SchemaBuilder {
|
||||
protected createIndices() {
|
||||
// return Promise.all(this.entityMetadatas.map(metadata => this.createIndices(metadata.table, metadata.indices)));
|
||||
return PromiseUtils.runInSequence(this.entityToSyncMetadatas, async metadata => {
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.table.name);
|
||||
const tableSchema = this.tableSchemas.find(table => table.name === metadata.tableName);
|
||||
if (!tableSchema)
|
||||
return;
|
||||
|
||||
@ -333,7 +333,7 @@ export class SchemaBuilder {
|
||||
.map(async indexSchema => {
|
||||
this.logger.logSchemaBuild(`dropping an index: ${indexSchema.name}`);
|
||||
tableSchema.removeIndex(indexSchema);
|
||||
await this.queryRunner.dropIndex(metadata.table.name, indexSchema.name);
|
||||
await this.queryRunner.dropIndex(metadata.tableName, indexSchema.name);
|
||||
});
|
||||
|
||||
// then create table indices for all composite indices we have
|
||||
|
||||
@ -60,7 +60,7 @@ export class IndexSchema {
|
||||
*/
|
||||
static create(indexMetadata: IndexMetadata): IndexSchema {
|
||||
return new IndexSchema(
|
||||
indexMetadata.entityMetadata.table.name,
|
||||
indexMetadata.entityMetadata.tableName,
|
||||
indexMetadata.name,
|
||||
indexMetadata.columns,
|
||||
indexMetadata.isUnique
|
||||
|
||||
@ -223,7 +223,7 @@ export class TableSchema {
|
||||
* todo: need deeper implementation
|
||||
*/
|
||||
static create(entityMetadata: EntityMetadata, queryRunner: QueryRunner) {
|
||||
const tableSchema = new TableSchema(entityMetadata.table.name);
|
||||
const tableSchema = new TableSchema(entityMetadata.tableName);
|
||||
entityMetadata.columns.forEach(column => {
|
||||
tableSchema.columns.push(ColumnSchema.create(column, queryRunner.normalizeType(column)));
|
||||
});
|
||||
|
||||
@ -3,7 +3,7 @@ import {expect} from "chai";
|
||||
import {Post} from "./entity/Post";
|
||||
import {View} from "./entity/View";
|
||||
import {Category} from "./entity/Category";
|
||||
import {createTestingConnections, closeTestingConnections, setupSingleTestingConnection} from "../../utils/test-utils";
|
||||
import {closeTestingConnections, createTestingConnections, setupSingleTestingConnection} from "../../utils/test-utils";
|
||||
import {Connection} from "../../../src/connection/Connection";
|
||||
import {Repository} from "../../../src/repository/Repository";
|
||||
import {TreeRepository} from "../../../src/repository/TreeRepository";
|
||||
@ -340,7 +340,7 @@ describe("Connection", () => {
|
||||
connection.importNamingStrategies([FirstCustomNamingStrategy]);
|
||||
connection.useNamingStrategy(FirstCustomNamingStrategy);
|
||||
await connection.connect();
|
||||
connection.getMetadata(Post).table.name.should.be.equal("POST");
|
||||
connection.getMetadata(Post).tableName.should.be.equal("POST");
|
||||
});
|
||||
|
||||
it("should use naming strategy when its name passed to useNamingStrategy method", async () => {
|
||||
@ -348,7 +348,7 @@ describe("Connection", () => {
|
||||
connection.importNamingStrategies([SecondCustomNamingStrategy]);
|
||||
connection.useNamingStrategy("secondCustomNamingStrategy");
|
||||
await connection.connect();
|
||||
connection.getMetadata(Category).table.name.should.be.equal("category");
|
||||
connection.getMetadata(Category).tableName.should.be.equal("category");
|
||||
});
|
||||
|
||||
it("should throw an error if not registered naming strategy was used (assert by name)", () => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user