{"version":3,"sources":["../../src/persistence/SubjectChangedColumnsComputer.ts"],"names":[],"mappings":"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","file":"SubjectChangedColumnsComputer.js","sourcesContent":["import {Subject} from \"./Subject\";\nimport {DateUtils} from \"../util/DateUtils\";\nimport {ObjectLiteral} from \"../common/ObjectLiteral\";\nimport {EntityMetadata} from \"../metadata/EntityMetadata\";\nimport {OrmUtils} from \"../util/OrmUtils\";\n\n/**\n * Finds what columns are changed in the subject entities.\n */\nexport class SubjectChangedColumnsComputer {\n\n // -------------------------------------------------------------------------\n // Public Methods\n // -------------------------------------------------------------------------\n\n /**\n * Finds what columns are changed in the subject entities.\n */\n compute(subjects: Subject[]) {\n subjects.forEach(subject => {\n this.computeDiffColumns(subject);\n this.computeDiffRelationalColumns(subjects, subject);\n });\n }\n\n // -------------------------------------------------------------------------\n // Protected Methods\n // -------------------------------------------------------------------------\n\n /**\n * Differentiate columns from the updated entity and entity stored in the database.\n */\n protected computeDiffColumns(subject: Subject): void {\n\n // if there is no persisted entity then nothing to compute changed in it\n if (!subject.entity)\n return;\n\n subject.metadata.columns.forEach(column => {\n\n // ignore special columns\n if (column.isVirtual ||\n column.isDiscriminator ||\n column.isUpdateDate ||\n column.isVersion ||\n column.isCreateDate)\n return;\n\n const changeMap = subject.changeMaps.find(changeMap => changeMap.column === column);\n if (changeMap) {\n subject.changeMaps.splice(subject.changeMaps.indexOf(changeMap), 1);\n }\n\n // get user provided value - column value from the user provided persisted entity\n const entityValue = column.getEntityValue(subject.entity!);\n\n // we don't perform operation over undefined properties (but we DO need null properties!)\n if (entityValue === undefined)\n return;\n\n // if there is no database entity then all columns are treated as new, e.g. changed\n if (subject.databaseEntity) {\n\n // get database value of the column\n let databaseValue = column.getEntityValue(subject.databaseEntity);\n\n // filter out \"relational columns\" only in the case if there is a relation object in entity\n if (column.relationMetadata) {\n const value = column.relationMetadata.getEntityValue(subject.entity!);\n if (value !== null && value !== undefined)\n return;\n }\n let normalizedValue = entityValue;\n // normalize special values to make proper comparision\n if (entityValue !== null) {\n if (column.type === \"date\") {\n normalizedValue = DateUtils.mixedDateToDateString(entityValue);\n\n } else if (column.type === \"time\") {\n normalizedValue = DateUtils.mixedDateToTimeString(entityValue);\n\n } else if (column.type === \"datetime\" || column.type === Date) {\n normalizedValue = DateUtils.mixedDateToUtcDatetimeString(entityValue);\n databaseValue = DateUtils.mixedDateToUtcDatetimeString(databaseValue);\n\n } else if (column.type === \"json\" || column.type === \"jsonb\") {\n // JSON.stringify doesn't work because postgresql sorts jsonb before save.\n // If you try to save json '[{\"messages\": \"\", \"attribute Key\": \"\", \"level\":\"\"}] ' as jsonb,\n // then postgresql will save it as '[{\"level\": \"\", \"message\":\"\", \"attributeKey\": \"\"}]'\n if (OrmUtils.deepCompare(entityValue, databaseValue)) return;\n\n } else if (column.type === \"simple-array\") {\n normalizedValue = DateUtils.simpleArrayToString(entityValue);\n databaseValue = DateUtils.simpleArrayToString(databaseValue);\n } else if (column.type === \"simple-enum\") {\n normalizedValue = DateUtils.simpleEnumToString(entityValue);\n databaseValue = DateUtils.simpleEnumToString(databaseValue);\n }\n }\n\n // if value is not changed - then do nothing\n if (normalizedValue === databaseValue)\n return;\n }\n subject.diffColumns.push(column);\n subject.changeMaps.push({\n column: column,\n value: entityValue\n });\n });\n }\n\n /**\n * Difference columns of the owning one-to-one and many-to-one columns.\n */\n protected computeDiffRelationalColumns(allSubjects: Subject[], subject: Subject): void {\n\n // if there is no persisted entity then nothing to compute changed in it\n if (!subject.entity)\n return;\n\n subject.metadata.relationsWithJoinColumns.forEach(relation => {\n\n // get the related entity from the persisted entity\n let relatedEntity = relation.getEntityValue(subject.entity!);\n\n // we don't perform operation over undefined properties (but we DO need null properties!)\n if (relatedEntity === undefined)\n return;\n\n // if there is no database entity then all relational columns are treated as new, e.g. changed\n if (subject.databaseEntity) {\n\n // here we cover two scenarios:\n // 1. related entity can be another entity which is natural way\n // 2. related entity can be just an entity id\n // if relation entity is just a relation id set (for example post.tag = 1)\n // then we create an id map from it to make a proper comparision\n let relatedEntityRelationIdMap: ObjectLiteral = relatedEntity;\n if (relatedEntityRelationIdMap !== null && relatedEntityRelationIdMap instanceof Object)\n relatedEntityRelationIdMap = relation.getRelationIdMap(relatedEntityRelationIdMap)!;\n\n // get database related entity. Since loadRelationIds are used on databaseEntity\n // related entity will contain only its relation ids\n const databaseRelatedEntityRelationIdMap = relation.getEntityValue(subject.databaseEntity);\n\n // if relation ids are equal then we don't need to update anything\n const areRelatedIdsEqual = EntityMetadata.compareIds(relatedEntityRelationIdMap, databaseRelatedEntityRelationIdMap);\n if (areRelatedIdsEqual) {\n return;\n } else {\n subject.diffRelations.push(relation);\n }\n }\n\n // if there is an inserted subject for the related entity of the persisted entity then use it as related entity\n // this code is used for related entities without ids to be properly inserted (and then updated if needed)\n const valueSubject = allSubjects.find(subject => subject.mustBeInserted && subject.entity === relatedEntity);\n if (valueSubject)\n relatedEntity = valueSubject;\n\n // find if there is already a relation to be changed\n const changeMap = subject.changeMaps.find(changeMap => changeMap.relation === relation);\n if (changeMap) { // and update its value if it was found\n changeMap.value = relatedEntity;\n\n } else { // if it wasn't found add a new relation for change\n subject.changeMaps.push({\n relation: relation,\n value: relatedEntity\n });\n }\n });\n }\n\n}\n"],"sourceRoot":".."}
|