diff --git a/src/metadata/EntityMetadata.ts b/src/metadata/EntityMetadata.ts index 7b5e0ae8bf..5b7c60fb2c 100644 --- a/src/metadata/EntityMetadata.ts +++ b/src/metadata/EntityMetadata.ts @@ -613,7 +613,7 @@ export class EntityMetadata { const secondEntityIdMap = this.getEntityIdMap(secondEntity); if (!secondEntityIdMap) return false; - return EntityMetadata.compareIds(firstEntityIdMap, secondEntityIdMap); + return OrmUtils.compareIds(firstEntityIdMap, secondEntityIdMap); } /** @@ -734,21 +734,10 @@ export class EntityMetadata { */ static difference(firstIdMaps: ObjectLiteral[], secondIdMaps: ObjectLiteral[]): ObjectLiteral[] { return firstIdMaps.filter(firstIdMap => { - return !secondIdMaps.find(secondIdMap => OrmUtils.deepCompare(firstIdMap, secondIdMap)); + return !secondIdMaps.find(secondIdMap => OrmUtils.compareIds(firstIdMap, secondIdMap)); }); } - /** - * Compares ids of the two entities. - * Returns true if they match, false otherwise. - */ - static compareIds(firstId: ObjectLiteral|undefined, secondId: ObjectLiteral|undefined): boolean { - if (firstId === undefined || firstId === null || secondId === undefined || secondId === null) - return false; - - return OrmUtils.deepCompare(firstId, secondId); - } - /** * Creates value map from the given values and columns. * Examples of usages are primary columns map and join columns map. diff --git a/src/persistence/SubjectChangedColumnsComputer.ts b/src/persistence/SubjectChangedColumnsComputer.ts index 9a55c0386d..2f2dc15ea8 100644 --- a/src/persistence/SubjectChangedColumnsComputer.ts +++ b/src/persistence/SubjectChangedColumnsComputer.ts @@ -1,7 +1,6 @@ import {Subject} from "./Subject"; import {DateUtils} from "../util/DateUtils"; import {ObjectLiteral} from "../common/ObjectLiteral"; -import {EntityMetadata} from "../metadata/EntityMetadata"; import {OrmUtils} from "../util/OrmUtils"; /** @@ -167,7 +166,7 @@ export class SubjectChangedColumnsComputer { const databaseRelatedEntityRelationIdMap = relation.getEntityValue(subject.databaseEntity); // if relation ids are equal then we don't need to update anything - const areRelatedIdsEqual = EntityMetadata.compareIds(relatedEntityRelationIdMap, databaseRelatedEntityRelationIdMap); + const areRelatedIdsEqual = OrmUtils.compareIds(relatedEntityRelationIdMap, databaseRelatedEntityRelationIdMap); if (areRelatedIdsEqual) { return; } else { diff --git a/src/persistence/subject-builder/ManyToManySubjectBuilder.ts b/src/persistence/subject-builder/ManyToManySubjectBuilder.ts index 850af6ef39..7d896cdc68 100644 --- a/src/persistence/subject-builder/ManyToManySubjectBuilder.ts +++ b/src/persistence/subject-builder/ManyToManySubjectBuilder.ts @@ -2,7 +2,6 @@ import {Subject} from "../Subject"; import {OrmUtils} from "../../util/OrmUtils"; import {ObjectLiteral} from "../../common/ObjectLiteral"; import {RelationMetadata} from "../../metadata/RelationMetadata"; -import {EntityMetadata} from "../../metadata/EntityMetadata"; /** * Builds operations needs to be executed for many-to-many relations of the given subjects. @@ -150,7 +149,7 @@ export class ManyToManySubjectBuilder { // try to find related entity in the database // by example: find post's category in the database post's categories const relatedEntityExistInDatabase = databaseRelatedEntityIds.find(databaseRelatedEntityRelationId => { - return EntityMetadata.compareIds(databaseRelatedEntityRelationId, relatedEntityRelationIdMap); + return OrmUtils.compareIds(databaseRelatedEntityRelationId, relatedEntityRelationIdMap); }); // if entity is found then don't do anything - it means binding in junction table already exist, we don't need to add anything @@ -207,7 +206,7 @@ export class ManyToManySubjectBuilder { // now from all entities in the persisted entity find only those which aren't found in the db const removedJunctionEntityIds = databaseRelatedEntityIds.filter(existRelationId => { return !changedInverseEntityRelationIds.find(changedRelationId => { - return EntityMetadata.compareIds(changedRelationId, existRelationId); + return OrmUtils.compareIds(changedRelationId, existRelationId); }); }); diff --git a/src/persistence/subject-builder/OneToManySubjectBuilder.ts b/src/persistence/subject-builder/OneToManySubjectBuilder.ts index 25250dfc5a..2578bf1cdb 100644 --- a/src/persistence/subject-builder/OneToManySubjectBuilder.ts +++ b/src/persistence/subject-builder/OneToManySubjectBuilder.ts @@ -117,7 +117,7 @@ export class OneToManySubjectBuilder { // check if this binding really exist in the database // by example: find our category if its already bind in the database const relationIdInDatabaseSubjectRelation = relatedEntityDatabaseRelationIds.find(relatedDatabaseEntityRelationId => { - return OrmUtils.deepCompare(relationIdMap, relatedDatabaseEntityRelationId); + return OrmUtils.compareIds(relationIdMap, relatedDatabaseEntityRelationId); }); // if relationIdMap DOES NOT exist in the subject's relation in the database it means its a new relation and we need to "bind" them diff --git a/src/persistence/subject-builder/OneToOneInverseSideSubjectBuilder.ts b/src/persistence/subject-builder/OneToOneInverseSideSubjectBuilder.ts index f421c5abc7..6912768fdd 100644 --- a/src/persistence/subject-builder/OneToOneInverseSideSubjectBuilder.ts +++ b/src/persistence/subject-builder/OneToOneInverseSideSubjectBuilder.ts @@ -139,7 +139,7 @@ export class OneToOneInverseSideSubjectBuilder { // check if this binding really exist in the database // by example: find our post if its already bind to category in the database and its not equal to what user tries to set - const areRelatedIdEqualWithDatabase = relatedEntityDatabaseRelationId && OrmUtils.deepCompare(relationIdMap, relatedEntityDatabaseRelationId); + const areRelatedIdEqualWithDatabase = relatedEntityDatabaseRelationId && OrmUtils.compareIds(relationIdMap, relatedEntityDatabaseRelationId); // if they aren't equal it means its a new relation and we need to "bind" them // by example: this will tell category to insert into its post relation our post we are working with diff --git a/src/query-builder/transformer/RawSqlResultsToEntityTransformer.ts b/src/query-builder/transformer/RawSqlResultsToEntityTransformer.ts index c1d0d670c0..1d3bde4b3e 100644 --- a/src/query-builder/transformer/RawSqlResultsToEntityTransformer.ts +++ b/src/query-builder/transformer/RawSqlResultsToEntityTransformer.ts @@ -214,7 +214,7 @@ export class RawSqlResultsToEntityTransformer { const idMaps = rawRelationIdResult.results.map(result => { const entityPrimaryIds = this.extractEntityPrimaryIds(relation, result); - if (EntityMetadata.compareIds(entityPrimaryIds, valueMap) === false) + if (OrmUtils.compareIds(entityPrimaryIds, valueMap) === false) return; let columns: ColumnMetadata[]; diff --git a/src/util/OrmUtils.ts b/src/util/OrmUtils.ts index 1691567d39..3df26494cb 100644 --- a/src/util/OrmUtils.ts +++ b/src/util/OrmUtils.ts @@ -100,7 +100,7 @@ export class OrmUtils { * * @see http://stackoverflow.com/a/1144249 */ - static deepCompare(...args: any[]) { + static deepCompare(...args: any[]): boolean { let i: any, l: any, leftChain: any, rightChain: any; if (arguments.length < 1) { @@ -121,6 +121,26 @@ export class OrmUtils { return true; } + /** + * Check if two entity-id-maps are the same + */ + static compareIds(firstId: ObjectLiteral|undefined, secondId: ObjectLiteral|undefined): boolean { + if (firstId === undefined || firstId === null || secondId === undefined || secondId === null) + return false; + + // Optimized version for the common case + if ( + ((typeof firstId.id === "string" && typeof secondId.id === "string") || + (typeof firstId.id === "number" && typeof secondId.id === "number")) && + Object.keys(firstId).length === 1 && + Object.keys(secondId).length === 1 + ) { + return firstId.id === secondId.id; + } + + return OrmUtils.deepCompare(firstId, secondId); + } + /** * Transforms given value into boolean value. */