mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
refactoring entity metadata stuff
This commit is contained in:
parent
32505c6f47
commit
76924c63b8
@ -212,19 +212,19 @@ export class EntityMetadataBuilder {
|
||||
entityMetadata.manyToManyRelations = entityMetadata.relations.filter(relation => relation.isManyToMany);
|
||||
entityMetadata.ownerOneToOneRelations = entityMetadata.relations.filter(relation => relation.isOneToOneOwner);
|
||||
entityMetadata.ownerManyToManyRelations = entityMetadata.relations.filter(relation => relation.isManyToManyOwner);
|
||||
entityMetadata.treeParentRelation = entityMetadata.relations.find(relation => relation.isTreeParent)!; // todo: fix ! later
|
||||
entityMetadata.treeChildrenRelation = entityMetadata.relations.find(relation => relation.isTreeChildren)!; // todo: fix ! later
|
||||
entityMetadata.treeParentRelation = entityMetadata.relations.find(relation => relation.isTreeParent);
|
||||
entityMetadata.treeChildrenRelation = entityMetadata.relations.find(relation => relation.isTreeChildren);
|
||||
entityMetadata.columns = entityMetadata.embeddeds.reduce((columns, embedded) => columns.concat(embedded.columnsFromTree), entityMetadata.ownColumns);
|
||||
entityMetadata.primaryColumns = entityMetadata.columns.filter(column => column.isPrimary);
|
||||
entityMetadata.hasMultiplePrimaryKeys = entityMetadata.primaryColumns.length > 1;
|
||||
entityMetadata.generatedColumn = entityMetadata.columns.find(column => column.isGenerated)!; // todo: fix ! later
|
||||
entityMetadata.createDateColumn = entityMetadata.columns.find(column => column.mode === "createDate")!; // todo: fix ! later
|
||||
entityMetadata.updateDateColumn = entityMetadata.columns.find(column => column.mode === "updateDate")!; // todo: fix ! later
|
||||
entityMetadata.versionColumn = entityMetadata.columns.find(column => column.mode === "version")!; // todo: fix ! later
|
||||
entityMetadata.discriminatorColumn = entityMetadata.columns.find(column => column.mode === "discriminator")!; // todo: fix ! later
|
||||
entityMetadata.treeLevelColumn = entityMetadata.columns.find(column => column.mode === "treeLevel")!; // todo: fix ! later
|
||||
entityMetadata.parentIdColumns = entityMetadata.columns.filter(column => column.mode === "parentId")!; // todo: fix ! later
|
||||
entityMetadata.objectIdColumn = entityMetadata.columns.find(column => column.mode === "objectId")!; // todo: fix ! later
|
||||
entityMetadata.generatedColumn = entityMetadata.columns.find(column => column.isGenerated);
|
||||
entityMetadata.createDateColumn = entityMetadata.columns.find(column => column.mode === "createDate");
|
||||
entityMetadata.updateDateColumn = entityMetadata.columns.find(column => column.mode === "updateDate");
|
||||
entityMetadata.versionColumn = entityMetadata.columns.find(column => column.mode === "version");
|
||||
entityMetadata.discriminatorColumn = entityMetadata.columns.find(column => column.mode === "discriminator");
|
||||
entityMetadata.treeLevelColumn = entityMetadata.columns.find(column => column.mode === "treeLevel");
|
||||
entityMetadata.parentIdColumns = entityMetadata.columns.filter(column => column.mode === "parentId");
|
||||
entityMetadata.objectIdColumn = entityMetadata.columns.find(column => column.mode === "objectId");
|
||||
entityMetadata.foreignKeys.forEach(foreignKey => foreignKey.build(this.connection.driver.namingStrategy));
|
||||
entityMetadata.indices.forEach(index => index.build(this.connection.driver.namingStrategy));
|
||||
entityMetadata.propertiesMap = entityMetadata.createPropertiesMap();
|
||||
@ -257,7 +257,7 @@ export class EntityMetadataBuilder {
|
||||
entityMetadata.indices.push(
|
||||
new IndexMetadata({
|
||||
entityMetadata: entityMetadata,
|
||||
columns: [entityMetadata.discriminatorColumn],
|
||||
columns: [entityMetadata.discriminatorColumn!],
|
||||
args: {
|
||||
target: entityMetadata.target,
|
||||
unique: false
|
||||
@ -265,7 +265,7 @@ export class EntityMetadataBuilder {
|
||||
}),
|
||||
new IndexMetadata({
|
||||
entityMetadata: entityMetadata,
|
||||
columns: [...entityMetadata.primaryColumns, entityMetadata.discriminatorColumn],
|
||||
columns: [...entityMetadata.primaryColumns, entityMetadata.discriminatorColumn!],
|
||||
args: {
|
||||
target: entityMetadata.target,
|
||||
unique: false
|
||||
|
||||
@ -10,7 +10,6 @@ import {RelationCountMetadata} from "./RelationCountMetadata";
|
||||
import {TableType} from "./types/TableTypes";
|
||||
import {OrderByCondition} from "../find-options/OrderByCondition";
|
||||
import {OrmUtils} from "../util/OrmUtils";
|
||||
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
|
||||
import {TableMetadataArgs} from "../metadata-args/TableMetadataArgs";
|
||||
import {Connection} from "../connection/Connection";
|
||||
|
||||
@ -34,7 +33,7 @@ export class EntityMetadata {
|
||||
closureJunctionTable: EntityMetadata;
|
||||
|
||||
/**
|
||||
* If this is entity metadata for a junction closure table then its owner closure table metadata will be there.
|
||||
* If this is entity metadata for a junction closure table then its owner closure table metadata will be set here.
|
||||
*/
|
||||
parentClosureEntityMetadata: EntityMetadata;
|
||||
|
||||
@ -43,68 +42,6 @@ export class EntityMetadata {
|
||||
*/
|
||||
parentEntityMetadata: EntityMetadata;
|
||||
|
||||
/**
|
||||
* Specifies a default order by used for queries from this table when no explicit order by is specified.
|
||||
*/
|
||||
orderBy?: OrderByCondition;
|
||||
|
||||
/**
|
||||
* Entity's column metadatas defined by user.
|
||||
*/
|
||||
ownColumns: ColumnMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Entity's relation metadatas.
|
||||
*/
|
||||
ownRelations: RelationMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Relations of the entity, including relations that are coming from the embeddeds of this entity.
|
||||
*/
|
||||
relations: RelationMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Columns of the entity, including columns that are coming from the embeddeds of this entity.
|
||||
*/
|
||||
columns: ColumnMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Entity's relation id metadatas.
|
||||
*/
|
||||
relationIds: RelationIdMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Entity's relation id metadatas.
|
||||
*/
|
||||
relationCounts: RelationCountMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Entity's index metadatas.
|
||||
*/
|
||||
indices: IndexMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Entity's foreign key metadatas.
|
||||
*/
|
||||
foreignKeys: ForeignKeyMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Entity's embedded metadatas.
|
||||
*/
|
||||
embeddeds: EmbeddedMetadata[] = [];
|
||||
|
||||
/**
|
||||
* If this entity metadata's table using one of the inheritance patterns,
|
||||
* then this will contain what pattern it uses.
|
||||
*/
|
||||
inheritanceType?: "single-table"|"class-table";
|
||||
|
||||
/**
|
||||
* If this entity metadata is a child table of some table, it should have a discriminator value.
|
||||
* Used to store a value in a discriminator column.
|
||||
*/
|
||||
discriminatorValue?: string;
|
||||
|
||||
/**
|
||||
* Table type. Tables can be abstract, closure, junction, embedded, etc.
|
||||
*/
|
||||
@ -169,6 +106,68 @@ export class EntityMetadata {
|
||||
*/
|
||||
engine?: string;
|
||||
|
||||
/**
|
||||
* Specifies a default order by used for queries from this table when no explicit order by is specified.
|
||||
*/
|
||||
orderBy?: OrderByCondition;
|
||||
|
||||
/**
|
||||
* Entity's column metadatas defined by user.
|
||||
*/
|
||||
ownColumns: ColumnMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Entity's relation metadatas.
|
||||
*/
|
||||
ownRelations: RelationMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Relations of the entity, including relations that are coming from the embeddeds of this entity.
|
||||
*/
|
||||
relations: RelationMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Columns of the entity, including columns that are coming from the embeddeds of this entity.
|
||||
*/
|
||||
columns: ColumnMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Entity's relation id metadatas.
|
||||
*/
|
||||
relationIds: RelationIdMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Entity's relation id metadatas.
|
||||
*/
|
||||
relationCounts: RelationCountMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Entity's index metadatas.
|
||||
*/
|
||||
indices: IndexMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Entity's foreign key metadatas.
|
||||
*/
|
||||
foreignKeys: ForeignKeyMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Entity's embedded metadatas.
|
||||
*/
|
||||
embeddeds: EmbeddedMetadata[] = [];
|
||||
|
||||
/**
|
||||
* If this entity metadata's table using one of the inheritance patterns,
|
||||
* then this will contain what pattern it uses.
|
||||
*/
|
||||
inheritanceType?: "single-table"|"class-table";
|
||||
|
||||
/**
|
||||
* If this entity metadata is a child table of some table, it should have a discriminator value.
|
||||
* Used to store a value in a discriminator column.
|
||||
*/
|
||||
discriminatorValue?: string;
|
||||
|
||||
/**
|
||||
* Checks if entity's table has multiple primary columns.
|
||||
*/
|
||||
@ -177,7 +176,7 @@ export class EntityMetadata {
|
||||
/**
|
||||
* Gets the column with generated flag.
|
||||
*/
|
||||
generatedColumn: ColumnMetadata;
|
||||
generatedColumn?: ColumnMetadata;
|
||||
|
||||
/**
|
||||
* Gets the primary columns.
|
||||
@ -187,31 +186,31 @@ export class EntityMetadata {
|
||||
/**
|
||||
* Gets entity column which contains a create date value.
|
||||
*/
|
||||
createDateColumn: ColumnMetadata;
|
||||
createDateColumn?: ColumnMetadata;
|
||||
|
||||
/**
|
||||
* Gets entity column which contains an update date value.
|
||||
*/
|
||||
updateDateColumn: ColumnMetadata;
|
||||
updateDateColumn?: ColumnMetadata;
|
||||
|
||||
/**
|
||||
* Gets entity column which contains an entity version.
|
||||
*/
|
||||
versionColumn: ColumnMetadata;
|
||||
versionColumn?: ColumnMetadata;
|
||||
|
||||
/**
|
||||
* Gets the discriminator column used to store entity identificator in single-table inheritance tables.
|
||||
*/
|
||||
discriminatorColumn: ColumnMetadata;
|
||||
discriminatorColumn?: ColumnMetadata;
|
||||
|
||||
treeLevelColumn: ColumnMetadata;
|
||||
treeLevelColumn?: ColumnMetadata;
|
||||
|
||||
parentIdColumns: ColumnMetadata[];
|
||||
parentIdColumns: ColumnMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Gets the object id column used with mongodb database.
|
||||
*/
|
||||
objectIdColumn: ColumnMetadata;
|
||||
objectIdColumn?: ColumnMetadata;
|
||||
|
||||
/**
|
||||
* Gets only one-to-one relations of the entity.
|
||||
@ -251,12 +250,12 @@ export class EntityMetadata {
|
||||
/**
|
||||
* Tree parent relation. Used only in tree-tables.
|
||||
*/
|
||||
treeParentRelation: RelationMetadata;
|
||||
treeParentRelation?: RelationMetadata;
|
||||
|
||||
/**
|
||||
* Tree children relation. Used only in tree-tables.
|
||||
*/
|
||||
treeChildrenRelation: RelationMetadata;
|
||||
treeChildrenRelation?: RelationMetadata;
|
||||
|
||||
/**
|
||||
* Checks if there any non-nullable column exist in this entity.
|
||||
@ -373,6 +372,63 @@ export class EntityMetadata {
|
||||
return newObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if given entity has an id.
|
||||
*/
|
||||
hasId(entity: ObjectLiteral): boolean {
|
||||
if (!entity)
|
||||
return false;
|
||||
|
||||
return this.primaryColumns.every(primaryColumn => { /// todo: this.metadata.parentEntityMetadata ?
|
||||
const value = primaryColumn.getEntityValue(entity);
|
||||
return value !== null && value !== undefined && value !== "";
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares ids of the two entities.
|
||||
* Returns true if they match, false otherwise.
|
||||
*/
|
||||
compareIds(firstId: ObjectLiteral|undefined, secondId: ObjectLiteral|undefined): boolean {
|
||||
if (firstId === undefined || firstId === null || secondId === undefined || secondId === null)
|
||||
return false;
|
||||
|
||||
return OrmUtils.deepCompare(firstId, secondId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two different entity instances by their ids.
|
||||
* Returns true if they match, false otherwise.
|
||||
*/
|
||||
compareEntities(firstEntity: ObjectLiteral, secondEntity: ObjectLiteral): boolean {
|
||||
|
||||
// if any entity ids are empty then they aren't equal
|
||||
const isFirstEntityEmpty = this.isEntityMapEmpty(firstEntity);
|
||||
const isSecondEntityEmpty = this.isEntityMapEmpty(secondEntity);
|
||||
if (isFirstEntityEmpty || isSecondEntityEmpty)
|
||||
return false;
|
||||
|
||||
const firstEntityIds = this.getEntityIdMap(firstEntity);
|
||||
const secondEntityIds = this.getEntityIdMap(secondEntity);
|
||||
return this.compareIds(firstEntityIds, secondEntityIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds relation with the given name.
|
||||
*/
|
||||
findRelationWithDbName(dbName: string): RelationMetadata|undefined {
|
||||
return this.relationsWithJoinColumns.find(relation => {
|
||||
return !!relation.joinColumns.find(column => column.databaseName === dbName);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds relation with the given property path.
|
||||
*/
|
||||
findRelationWithPropertyPath(propertyPath: string): RelationMetadata|undefined {
|
||||
return this.relations.find(relation => relation.propertyPath === propertyPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes property name of the entity using given PropertyTypeInFunction.
|
||||
*/
|
||||
@ -460,97 +516,15 @@ export class EntityMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `getEntityIdMap` but the key of the map will be the column names instead of the property names.
|
||||
* Checks if given object contains ALL primary keys entity must have.
|
||||
* Returns true if it contains all of them, false if at least one of them is not defined.
|
||||
*/
|
||||
getEntityIdColumnMap(entity: any): ObjectLiteral|undefined {
|
||||
return this.getDatabaseEntityIdMap(entity);
|
||||
// return this.transformIdMapToColumnNames(this.getEntityIdMap(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if relation with the given property path exist.
|
||||
*
|
||||
* todo: check usages later
|
||||
*/
|
||||
hasRelationWithPropertyPath(propertyPath: string): boolean {
|
||||
return !!this.relations.find(relation => relation.propertyPath === propertyPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds relation with the given property name.
|
||||
*/
|
||||
findRelationWithPropertyName(propertyName: string): RelationMetadata {
|
||||
const relation = this.relations.find(relation => relation.propertyName === propertyName);
|
||||
if (!relation)
|
||||
throw new Error(`Relation with property name ${propertyName} in ${this.name} entity was not found.`);
|
||||
|
||||
return relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds relation with the given property path.
|
||||
*
|
||||
* todo: check usages later
|
||||
*/
|
||||
findRelationWithPropertyPath(propertyPath: string): RelationMetadata {
|
||||
const relation = this.relations.find(relation => relation.propertyPath === propertyPath);
|
||||
if (!relation)
|
||||
throw new Error(`Relation with property path ${propertyPath} in ${this.name} entity was not found.`);
|
||||
|
||||
return relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if relation with the given name exist.
|
||||
*/
|
||||
hasRelationWithDbName(dbName: string): boolean {
|
||||
return !!this.relationsWithJoinColumns.find(relation => {
|
||||
return !!relation.joinColumns.find(column => column.databaseName === dbName);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds relation with the given name.
|
||||
*/
|
||||
findRelationWithDbName(dbName: string): RelationMetadata {
|
||||
const relation = this.relationsWithJoinColumns.find(relation => {
|
||||
return !!relation.joinColumns.find(column => column.databaseName === dbName);
|
||||
});
|
||||
if (!relation)
|
||||
throw new Error(`Relation with name ${dbName} in ${this.name} entity was not found.`);
|
||||
|
||||
return relation;
|
||||
}
|
||||
|
||||
checkIfObjectContainsAllPrimaryKeys(object: ObjectLiteral) {
|
||||
return this.primaryColumns.every(primaryColumn => {
|
||||
return object.hasOwnProperty(primaryColumn.propertyName);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @stable
|
||||
*/
|
||||
compareEntities(firstEntity: any, secondEntity: any) {
|
||||
|
||||
// if any entity ids are empty then they aren't equal
|
||||
const isFirstEntityEmpty = this.isEntityMapEmpty(firstEntity);
|
||||
const isSecondEntityEmpty = this.isEntityMapEmpty(secondEntity);
|
||||
if (isFirstEntityEmpty || isSecondEntityEmpty)
|
||||
return false;
|
||||
|
||||
const firstEntityIds = this.getEntityIdMap(firstEntity);
|
||||
const secondEntityIds = this.getEntityIdMap(secondEntity);
|
||||
return this.compareIds(firstEntityIds, secondEntityIds);
|
||||
}
|
||||
|
||||
compareIds(firstId: ObjectLiteral|undefined, secondId: ObjectLiteral|undefined): boolean {
|
||||
if (firstId === undefined || firstId === null || secondId === undefined || secondId === null)
|
||||
return false;
|
||||
|
||||
return OrmUtils.deepCompare(firstId, secondId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates throw entity and finds and extracts all values from relations in the entity.
|
||||
* If relation value is an array its being flattened.
|
||||
@ -568,21 +542,8 @@ export class EntityMetadata {
|
||||
return relationsAndValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if given entity has an id.
|
||||
*/
|
||||
hasId(entity: ObjectLiteral): boolean {
|
||||
if (!entity)
|
||||
return false;
|
||||
|
||||
return this.primaryColumns.every(primaryColumn => { /// todo: this.metadata.parentEntityMetadata ?
|
||||
const value = primaryColumn.getEntityValue(entity);
|
||||
return value !== null && value !== undefined && value !== "";
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Public Builder Methods
|
||||
// Public Methods
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
registerColumn(column: ColumnMetadata) {
|
||||
@ -600,20 +561,4 @@ export class EntityMetadata {
|
||||
return map;
|
||||
}
|
||||
|
||||
// buildOnRelationsChange() {
|
||||
// this.relationsWithJoinColumns = this.relations.filter(relation => relation.isWithJoinColumn);
|
||||
// this.hasNonNullableRelations = this.relationsWithJoinColumns.some(relation => !relation.isNullable || relation.isPrimary);
|
||||
// }
|
||||
|
||||
// buildOnColumnsChange() {
|
||||
// this.columns = this.embeddeds.reduce((columns, embedded) => columns.concat(embedded.columnsFromTree), this.ownColumns);
|
||||
// this.primaryColumns = this.columns.filter(column => column.isPrimary);
|
||||
// this.hasMultiplePrimaryKeys = this.primaryColumns.length > 1;
|
||||
// this.propertiesMap = this.createPropertiesMap();
|
||||
// }
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
}
|
||||
@ -372,8 +372,8 @@ export class Subject {
|
||||
return false;
|
||||
|
||||
// filter out "relational columns" only in the case if there is a relation object in entity
|
||||
if (this.metadata.hasRelationWithDbName(column.databaseName)) {
|
||||
const relation = this.metadata.findRelationWithDbName(column.databaseName);
|
||||
const relation = this.metadata.findRelationWithDbName(column.databaseName);
|
||||
if (relation) {
|
||||
const value = relation.getEntityValue(this.entity);
|
||||
if (value !== null && value !== undefined)
|
||||
return false;
|
||||
|
||||
@ -606,7 +606,7 @@ export class SubjectOperationExecutor {
|
||||
// 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.tableName;
|
||||
const referencedColumn = subject.metadata.treeParentRelation.joinColumns[0].referencedColumn!; // todo: check if joinColumn works
|
||||
const referencedColumn = subject.metadata.treeParentRelation!.joinColumns[0].referencedColumn!; // todo: check if joinColumn works
|
||||
// todo: fix joinColumns[0] usage
|
||||
|
||||
let newEntityId = referencedColumn.getEntityValue(subject.entity);
|
||||
@ -615,7 +615,7 @@ export class SubjectOperationExecutor {
|
||||
// we should not handle object id here because closure tables are not supported by mongodb driver.
|
||||
} // todo: implement other special column types too
|
||||
|
||||
const parentEntity = subject.metadata.treeParentRelation.getEntityValue(subject.entity);
|
||||
const parentEntity = subject.metadata.treeParentRelation!.getEntityValue(subject.entity);
|
||||
let parentEntityId: any = 0; // zero is important
|
||||
if (parentEntity) {
|
||||
parentEntityId = referencedColumn.getEntityValue(parentEntity);
|
||||
@ -632,7 +632,7 @@ export class SubjectOperationExecutor {
|
||||
if (!allSubject.hasEntity || !allSubject.metadata.isClosure || !allSubject.metadata.treeChildrenRelation)
|
||||
return false;
|
||||
|
||||
const children = subject.metadata.treeChildrenRelation.getEntityValue(allSubject.entity);
|
||||
const children = subject.metadata.treeChildrenRelation!.getEntityValue(allSubject.entity);
|
||||
return children instanceof Array ? children.indexOf(subject.entity) !== -1 : false;
|
||||
});
|
||||
|
||||
@ -848,7 +848,7 @@ export class SubjectOperationExecutor {
|
||||
});
|
||||
await this.queryRunner.delete(subject.metadata.tableName, childConditions);
|
||||
} else {
|
||||
await this.queryRunner.delete(subject.metadata.tableName, subject.metadata.getEntityIdColumnMap(subject.databaseEntity)!);
|
||||
await this.queryRunner.delete(subject.metadata.tableName, subject.metadata.getDatabaseEntityIdMap(subject.databaseEntity)!);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -119,7 +119,10 @@ export class JoinAttribute {
|
||||
return undefined;
|
||||
|
||||
const relationOwnerSelection = this.queryExpressionMap.findAliasByName(this.parentAlias!);
|
||||
return relationOwnerSelection.metadata.findRelationWithPropertyPath(this.relationPropertyPath!);
|
||||
const relation = relationOwnerSelection.metadata.findRelationWithPropertyPath(this.relationPropertyPath!);
|
||||
if (!relation)
|
||||
throw new Error(`Relation with property path ${this.relationPropertyPath} in entity was not found.`);
|
||||
return relation;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1083,13 +1083,13 @@ export class QueryBuilder<Entity> {
|
||||
const metadata = this.expressionMap.mainAlias!.metadata;
|
||||
|
||||
if (this.expressionMap.lockVersion instanceof Date) {
|
||||
const actualVersion = result[metadata.updateDateColumn.propertyName];
|
||||
const actualVersion = result[metadata.updateDateColumn!.propertyName]; // what if columns arent set?
|
||||
this.expressionMap.lockVersion.setMilliseconds(0);
|
||||
if (actualVersion.getTime() !== this.expressionMap.lockVersion.getTime())
|
||||
throw new OptimisticLockVersionMismatchError(metadata.name, this.expressionMap.lockVersion, actualVersion);
|
||||
|
||||
} else {
|
||||
const actualVersion = result[metadata.versionColumn.propertyName];
|
||||
const actualVersion = result[metadata.versionColumn!.propertyName]; // what if columns arent set?
|
||||
if (actualVersion !== this.expressionMap.lockVersion)
|
||||
throw new OptimisticLockVersionMismatchError(metadata.name, this.expressionMap.lockVersion, actualVersion);
|
||||
}
|
||||
|
||||
@ -84,9 +84,12 @@ export class RelationCountAttribute {
|
||||
if (!QueryBuilderUtils.isAliasProperty(this.relationName))
|
||||
throw new Error(`Given value is a string representation of alias property`);
|
||||
|
||||
const [parentAlias, relationProperty] = this.relationName.split(".");
|
||||
const [parentAlias, propertyPath] = this.relationName.split(".");
|
||||
const relationOwnerSelection = this.expressionMap.findAliasByName(parentAlias);
|
||||
return relationOwnerSelection.metadata.findRelationWithPropertyName(relationProperty);
|
||||
const relation = relationOwnerSelection.metadata.findRelationWithPropertyPath(propertyPath);
|
||||
if (!relation)
|
||||
throw new Error(`Relation with property path ${propertyPath} in entity was not found.`);
|
||||
return relation;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -87,7 +87,10 @@ export class RelationIdAttribute {
|
||||
throw new Error(`Given value must be a string representation of alias property`);
|
||||
|
||||
const relationOwnerSelection = this.queryExpressionMap.findAliasByName(this.parentAlias!);
|
||||
return relationOwnerSelection.metadata.findRelationWithPropertyPath(this.relationPropertyPath!);
|
||||
const relation = relationOwnerSelection.metadata.findRelationWithPropertyPath(this.relationPropertyPath!);
|
||||
if (!relation)
|
||||
throw new Error(`Relation with property path ${this.relationPropertyPath} in entity was not found.`);
|
||||
return relation;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -50,6 +50,8 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
async setRelation(relationProperty: string|((t: Entity) => string|any), entityId: any, relatedEntityId: any): Promise<void> {
|
||||
const propertyPath = this.metadata.computePropertyPath(relationProperty);
|
||||
const relation = this.metadata.findRelationWithPropertyPath(propertyPath);
|
||||
if (!relation)
|
||||
throw new Error(`Relation with property path ${propertyPath} in entity was not found.`);
|
||||
// if (relation.isManyToMany || relation.isOneToMany || relation.isOneToOneNotOwner)
|
||||
// throw new Error(`Only many-to-one and one-to-one with join column are supported for this operation. ${this.metadata.name}#${propertyName} relation type is ${relation.relationType}`);
|
||||
if (relation.isManyToMany)
|
||||
@ -99,6 +101,8 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
const propertyPath = this.metadata.computePropertyPath(relationProperty);
|
||||
// todo: fix issues with joinColumns[0]
|
||||
const relation = this.metadata.findRelationWithPropertyPath(propertyPath);
|
||||
if (!relation)
|
||||
throw new Error(`Relation with property path ${propertyPath} in entity was not found.`);
|
||||
// if (relation.isManyToMany || relation.isOneToMany || relation.isOneToOneNotOwner)
|
||||
// throw new Error(`Only many-to-one and one-to-one with join column are supported for this operation. ${this.metadata.name}#${propertyName} relation type is ${relation.relationType}`);
|
||||
if (relation.isManyToMany)
|
||||
@ -144,6 +148,8 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
async addToRelation(relationProperty: string|((t: Entity) => string|any), entityId: any, relatedEntityIds: any[]): Promise<void> {
|
||||
const propertyPath = this.metadata.computePropertyPath(relationProperty);
|
||||
const relation = this.metadata.findRelationWithPropertyPath(propertyPath);
|
||||
if (!relation)
|
||||
throw new Error(`Relation with property path ${propertyPath} in entity was not found.`);
|
||||
if (!relation.isManyToMany)
|
||||
throw new Error(`Only many-to-many relation supported for this operation. However ${this.metadata.name}#${propertyPath} relation type is ${relation.relationType}`);
|
||||
|
||||
@ -188,7 +194,9 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
*/
|
||||
async addToInverseRelation(relationProperty: string|((t: Entity) => string|any), relatedEntityId: any, entityIds: any[]): Promise<void> {
|
||||
const propertyPath = this.metadata.computePropertyPath(relationProperty);
|
||||
const relation = this.metadata.findRelationWithPropertyName(propertyPath);
|
||||
const relation = this.metadata.findRelationWithPropertyPath(propertyPath);
|
||||
if (!relation)
|
||||
throw new Error(`Relation with property path ${propertyPath} in entity was not found.`);
|
||||
if (!relation.isManyToMany)
|
||||
throw new Error(`Only many-to-many relation supported for this operation. However ${this.metadata.name}#${propertyPath} relation type is ${relation.relationType}`);
|
||||
|
||||
@ -237,6 +245,8 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
async removeFromRelation(relationProperty: string|((t: Entity) => string|any), entityId: any, relatedEntityIds: any[]): Promise<void> {
|
||||
const propertyPath = this.metadata.computePropertyPath(relationProperty);
|
||||
const relation = this.metadata.findRelationWithPropertyPath(propertyPath);
|
||||
if (!relation)
|
||||
throw new Error(`Relation with property path ${propertyPath} in entity was not found.`);
|
||||
if (!relation.isManyToMany)
|
||||
throw new Error(`Only many-to-many relation supported for this operation. However ${this.metadata.name}#${propertyPath} relation type is ${relation.relationType}`);
|
||||
|
||||
@ -282,7 +292,9 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
*/
|
||||
async removeFromInverseRelation(relationProperty: string|((t: Entity) => string|any), relatedEntityId: any, entityIds: any[]): Promise<void> {
|
||||
const propertyPath = this.metadata.computePropertyPath(relationProperty);
|
||||
const relation = this.metadata.findRelationWithPropertyName(propertyPath);
|
||||
const relation = this.metadata.findRelationWithPropertyPath(propertyPath);
|
||||
if (!relation)
|
||||
throw new Error(`Relation with property path ${propertyPath} in entity was not found.`);
|
||||
if (!relation.isManyToMany)
|
||||
throw new Error(`Only many-to-many relation supported for this operation. However ${this.metadata.name}#${propertyPath} relation type is ${relation.relationType}`);
|
||||
|
||||
@ -511,7 +523,10 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
|
||||
return relationOrName;
|
||||
|
||||
const relationPropertyPath = relationOrName instanceof Function ? relationOrName(this.metadata.propertiesMap) : relationOrName;
|
||||
return this.metadata.findRelationWithPropertyPath(relationPropertyPath);
|
||||
const relation = this.metadata.findRelationWithPropertyPath(relationPropertyPath);
|
||||
if (!relation)
|
||||
throw new Error(`Relation with property path ${relationPropertyPath} in entity was not found.`);
|
||||
return relation;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -32,7 +32,7 @@ export class TreeRepository<Entity> extends Repository<Entity> {
|
||||
*/
|
||||
findRoots(): Promise<Entity[]> {
|
||||
|
||||
const parentPropertyName = this.metadata.treeParentRelation.propertyName;
|
||||
const parentPropertyName = this.metadata.treeParentRelation!.propertyName;
|
||||
return this.createQueryBuilder("treeEntity")
|
||||
.where(`treeEntity.${parentPropertyName} IS NULL`)
|
||||
.getMany();
|
||||
@ -149,13 +149,13 @@ export class TreeRepository<Entity> extends Repository<Entity> {
|
||||
return rawResults.map(rawResult => {
|
||||
return {
|
||||
id: rawResult[alias + "_" + this.metadata.primaryColumns[0].databaseName],
|
||||
parentId: rawResult[alias + "_" + this.metadata.treeParentRelation.joinColumns[0].referencedColumn!.databaseName]
|
||||
parentId: rawResult[alias + "_" + this.metadata.treeParentRelation!.joinColumns[0].referencedColumn!.databaseName]
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
protected buildChildrenEntityTree(entity: any, entities: any[], relationMaps: { id: any, parentId: any }[]): void {
|
||||
const childProperty = this.metadata.treeChildrenRelation.propertyName;
|
||||
const childProperty = this.metadata.treeChildrenRelation!.propertyName;
|
||||
const parentEntityId = this.metadata.primaryColumns[0].getEntityValue(entity);
|
||||
const childRelationMaps = relationMaps.filter(relationMap => relationMap.parentId === parentEntityId);
|
||||
const childIds = childRelationMaps.map(relationMap => relationMap.id);
|
||||
@ -166,7 +166,7 @@ export class TreeRepository<Entity> extends Repository<Entity> {
|
||||
}
|
||||
|
||||
protected buildParentEntityTree(entity: any, entities: any[], relationMaps: { id: any, parentId: any }[]): void {
|
||||
const parentProperty = this.metadata.treeParentRelation.propertyName;
|
||||
const parentProperty = this.metadata.treeParentRelation!.propertyName;
|
||||
const entityId = this.metadata.primaryColumns[0].getEntityValue(entity);
|
||||
const parentRelationMap = relationMaps.find(relationMap => relationMap.id === entityId);
|
||||
const parentEntity = entities.find(entity => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user