typeorm
Version:
Data-Mapper ORM for TypeScript, ES7, ES6, ES5. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, MongoDB databases.
140 lines (138 loc) • 6.61 kB
JavaScript
import { ObjectUtils } from "../util/ObjectUtils";
/**
* Allows to work with entity relations and perform specific operations with those relations.
*
* todo: add transactions everywhere
*/
export class RelationRemover {
// -------------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------------
constructor(queryBuilder, expressionMap) {
this.queryBuilder = queryBuilder;
this.expressionMap = expressionMap;
}
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
/**
* Performs remove operation on a relation.
*/
async remove(value) {
const relation = this.expressionMap.relationMetadata;
if (relation.isOneToMany) {
// if (this.expressionMap.of instanceof Array)
// throw new TypeORMError(`You cannot update relations of multiple entities with the same related object. Provide a single entity into .of method.`);
// DELETE FROM post WHERE post.categoryId = of AND post.id = id
const ofs = Array.isArray(this.expressionMap.of)
? this.expressionMap.of
: [this.expressionMap.of];
const values = Array.isArray(value) ? value : [value];
const updateSet = {};
relation.inverseRelation.joinColumns.forEach((column) => {
updateSet[column.propertyName] = null;
});
const parameters = {};
const conditions = [];
ofs.forEach((of, ofIndex) => {
conditions.push(...values.map((value, valueIndex) => {
return [
...relation.inverseRelation.joinColumns.map((column, columnIndex) => {
const parameterName = "joinColumn_" +
ofIndex +
"_" +
valueIndex +
"_" +
columnIndex;
parameters[parameterName] =
ObjectUtils.isObject(of)
? column.referencedColumn.getEntityValue(of)
: of;
return `${column.propertyPath} = :${parameterName}`;
}),
...relation.inverseRelation.entityMetadata.primaryColumns.map((column, columnIndex) => {
const parameterName = "primaryColumn_" +
valueIndex +
"_" +
valueIndex +
"_" +
columnIndex;
parameters[parameterName] =
ObjectUtils.isObject(value)
? column.getEntityValue(value)
: value;
return `${column.propertyPath} = :${parameterName}`;
}),
].join(" AND ");
}));
});
const condition = conditions
.map((str) => "(" + str + ")")
.join(" OR ");
if (!condition)
return;
await this.queryBuilder
.createQueryBuilder()
.update(relation.inverseEntityMetadata.target)
.set(updateSet)
.where(condition)
.setParameters(parameters)
.execute();
}
else {
// many to many
const junctionMetadata = relation.junctionEntityMetadata;
const ofs = Array.isArray(this.expressionMap.of)
? this.expressionMap.of
: [this.expressionMap.of];
const values = Array.isArray(value) ? value : [value];
const firstColumnValues = relation.isManyToManyOwner ? ofs : values;
const secondColumnValues = relation.isManyToManyOwner ? values : ofs;
const parameters = {};
const conditions = [];
firstColumnValues.forEach((firstColumnVal, firstColumnValIndex) => {
conditions.push(...secondColumnValues.map((secondColumnVal, secondColumnValIndex) => {
return [
...junctionMetadata.ownerColumns.map((column, columnIndex) => {
const parameterName = "firstValue_" +
firstColumnValIndex +
"_" +
secondColumnValIndex +
"_" +
columnIndex;
parameters[parameterName] =
ObjectUtils.isObject(firstColumnVal)
? column.referencedColumn.getEntityValue(firstColumnVal)
: firstColumnVal;
return `${column.databaseName} = :${parameterName}`;
}),
...junctionMetadata.inverseColumns.map((column, columnIndex) => {
const parameterName = "secondValue_" +
firstColumnValIndex +
"_" +
secondColumnValIndex +
"_" +
columnIndex;
parameters[parameterName] =
ObjectUtils.isObject(secondColumnVal)
? column.referencedColumn.getEntityValue(secondColumnVal)
: secondColumnVal;
return `${column.databaseName} = :${parameterName}`;
}),
].join(" AND ");
}));
});
const condition = conditions
.map((str) => "(" + str + ")")
.join(" OR ");
await this.queryBuilder
.createQueryBuilder()
.delete()
.from(junctionMetadata.tableName)
.where(condition)
.setParameters(parameters)
.execute();
}
}
}
//# sourceMappingURL=RelationRemover.js.map