"use strict";
|
Object.defineProperty(exports, "__esModule", { value: true });
|
var tslib_1 = require("tslib");
|
var OrmUtils_1 = require("../util/OrmUtils");
|
var OracleDriver_1 = require("../driver/oracle/OracleDriver");
|
/**
|
* Updates entity with returning results in the entity insert and update operations.
|
*/
|
var ReturningResultsEntityUpdator = /** @class */ (function () {
|
// -------------------------------------------------------------------------
|
// Constructor
|
// -------------------------------------------------------------------------
|
function ReturningResultsEntityUpdator(queryRunner, expressionMap) {
|
this.queryRunner = queryRunner;
|
this.expressionMap = expressionMap;
|
}
|
// -------------------------------------------------------------------------
|
// Public Methods
|
// -------------------------------------------------------------------------
|
/**
|
* Updates entities with a special columns after updation query execution.
|
*/
|
ReturningResultsEntityUpdator.prototype.update = function (updateResult, entities) {
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
var metadata;
|
var _this = this;
|
return tslib_1.__generator(this, function (_a) {
|
switch (_a.label) {
|
case 0:
|
metadata = this.expressionMap.mainAlias.metadata;
|
return [4 /*yield*/, Promise.all(entities.map(function (entity, entityIndex) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
var result, returningColumns, updationColumns, entityId, loadedReturningColumns;
|
var _this = this;
|
return tslib_1.__generator(this, function (_a) {
|
switch (_a.label) {
|
case 0:
|
if (!this.queryRunner.connection.driver.isReturningSqlSupported()) return [3 /*break*/, 1];
|
if (this.queryRunner.connection.driver instanceof OracleDriver_1.OracleDriver && updateResult.raw instanceof Array && this.expressionMap.extraReturningColumns.length > 0) {
|
updateResult.raw = updateResult.raw.reduce(function (newRaw, rawItem, rawItemIndex) {
|
newRaw[_this.expressionMap.extraReturningColumns[rawItemIndex].databaseName] = rawItem[0];
|
return newRaw;
|
}, {});
|
}
|
result = updateResult.raw instanceof Array ? updateResult.raw[entityIndex] : updateResult.raw;
|
returningColumns = this.queryRunner.connection.driver.createGeneratedMap(metadata, result);
|
if (returningColumns) {
|
this.queryRunner.manager.merge(metadata.target, entity, returningColumns);
|
updateResult.generatedMaps.push(returningColumns);
|
}
|
return [3 /*break*/, 3];
|
case 1:
|
updationColumns = this.getUpdationReturningColumns();
|
if (!(updationColumns.length > 0)) return [3 /*break*/, 3];
|
entityId = this.expressionMap.mainAlias.metadata.getEntityIdMap(entity);
|
if (!entityId)
|
throw new Error("Cannot update entity because entity id is not set in the entity.");
|
return [4 /*yield*/, this.queryRunner.manager
|
.createQueryBuilder()
|
.select(metadata.primaryColumns.map(function (column) { return metadata.targetName + "." + column.propertyPath; }))
|
.addSelect(this.getUpdationReturningColumns().map(function (column) { return metadata.targetName + "." + column.propertyPath; }))
|
.from(metadata.target, metadata.targetName)
|
.where(entityId)
|
.setOption("create-pojo") // use POJO because created object can contain default values, e.g. property = null and those properties maight be overridden by merge process
|
.getOne()];
|
case 2:
|
loadedReturningColumns = _a.sent();
|
if (loadedReturningColumns) {
|
this.queryRunner.manager.merge(metadata.target, entity, loadedReturningColumns);
|
updateResult.generatedMaps.push(loadedReturningColumns);
|
}
|
_a.label = 3;
|
case 3: return [2 /*return*/];
|
}
|
});
|
}); }))];
|
case 1:
|
_a.sent();
|
return [2 /*return*/];
|
}
|
});
|
});
|
};
|
/**
|
* Updates entities with a special columns after insertion query execution.
|
*/
|
ReturningResultsEntityUpdator.prototype.insert = function (insertResult, entities) {
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
var metadata, insertionColumns, generatedMaps;
|
var _this = this;
|
return tslib_1.__generator(this, function (_a) {
|
switch (_a.label) {
|
case 0:
|
metadata = this.expressionMap.mainAlias.metadata;
|
insertionColumns = this.getInsertionReturningColumns();
|
generatedMaps = entities.map(function (entity, entityIndex) {
|
if (_this.queryRunner.connection.driver instanceof OracleDriver_1.OracleDriver && insertResult.raw instanceof Array && _this.expressionMap.extraReturningColumns.length > 0) {
|
insertResult.raw = insertResult.raw.reduce(function (newRaw, rawItem, rawItemIndex) {
|
newRaw[_this.expressionMap.extraReturningColumns[rawItemIndex].databaseName] = rawItem[0];
|
return newRaw;
|
}, {});
|
}
|
// get all values generated by a database for us
|
var result = insertResult.raw instanceof Array ? insertResult.raw[entityIndex] : insertResult.raw;
|
var generatedMap = _this.queryRunner.connection.driver.createGeneratedMap(metadata, result) || {};
|
// if database does not support uuid generation we need to get uuid values
|
// generated by orm and set them to the generatedMap
|
if (_this.queryRunner.connection.driver.isUUIDGenerationSupported() === false) {
|
metadata.generatedColumns.forEach(function (generatedColumn) {
|
if (generatedColumn.generationStrategy === "uuid") {
|
// uuid can be defined by user in a model, that's why first we get it
|
var uuid = generatedColumn.getEntityValue(entity);
|
if (!uuid) // if it was not defined by a user then InsertQueryBuilder generates it by its own, get this generated uuid value
|
uuid = _this.expressionMap.nativeParameters["uuid_" + generatedColumn.databaseName + entityIndex];
|
OrmUtils_1.OrmUtils.mergeDeep(generatedMap, generatedColumn.createValueMap(uuid));
|
}
|
});
|
}
|
_this.queryRunner.manager.merge(metadata.target, entity, generatedMap); // todo: this should not be here, but problem with below line
|
return generatedMap;
|
});
|
if (!(this.queryRunner.connection.driver.isReturningSqlSupported() === false && insertionColumns.length > 0)) return [3 /*break*/, 2];
|
return [4 /*yield*/, Promise.all(entities.map(function (entity, entityIndex) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
var entityId, returningResult;
|
return tslib_1.__generator(this, function (_a) {
|
switch (_a.label) {
|
case 0:
|
entityId = metadata.getEntityIdMap(entity);
|
return [4 /*yield*/, this.queryRunner.manager
|
.createQueryBuilder()
|
.select(metadata.primaryColumns.map(function (column) { return metadata.targetName + "." + column.propertyPath; }))
|
.addSelect(insertionColumns.map(function (column) { return metadata.targetName + "." + column.propertyPath; }))
|
.from(metadata.target, metadata.targetName)
|
.where(entityId)
|
.setOption("create-pojo") // use POJO because created object can contain default values, e.g. property = null and those properties maight be overridden by merge process
|
.getOne()];
|
case 1:
|
returningResult = _a.sent();
|
this.queryRunner.manager.merge(metadata.target, generatedMaps[entityIndex], returningResult);
|
return [2 /*return*/];
|
}
|
});
|
}); }))];
|
case 1:
|
_a.sent();
|
_a.label = 2;
|
case 2:
|
entities.forEach(function (entity, entityIndex) {
|
var entityId = metadata.getEntityIdMap(entity);
|
insertResult.identifiers.push(entityId);
|
insertResult.generatedMaps.push(generatedMaps[entityIndex]);
|
_this.queryRunner.manager.merge(_this.expressionMap.mainAlias.metadata.target, entity, generatedMaps[entityIndex], generatedMaps[entityIndex]); // todo: why twice?!
|
});
|
return [2 /*return*/];
|
}
|
});
|
});
|
};
|
/**
|
* Columns we need to be returned from the database when we insert entity.
|
*/
|
ReturningResultsEntityUpdator.prototype.getInsertionReturningColumns = function () {
|
// for databases which support returning statement we need to return extra columns like id
|
// for other databases we don't need to return id column since its returned by a driver already
|
var needToCheckGenerated = this.queryRunner.connection.driver.isReturningSqlSupported();
|
// filter out the columns of which we need database inserted values to update our entity
|
return this.expressionMap.mainAlias.metadata.columns.filter(function (column) {
|
return column.default !== undefined ||
|
(needToCheckGenerated && column.isGenerated) ||
|
column.isCreateDate ||
|
column.isUpdateDate ||
|
column.isVersion;
|
});
|
};
|
/**
|
* Columns we need to be returned from the database when we update entity.
|
*/
|
ReturningResultsEntityUpdator.prototype.getUpdationReturningColumns = function () {
|
return this.expressionMap.mainAlias.metadata.columns.filter(function (column) {
|
return column.isUpdateDate || column.isVersion;
|
});
|
};
|
return ReturningResultsEntityUpdator;
|
}());
|
exports.ReturningResultsEntityUpdator = ReturningResultsEntityUpdator;
|
|
//# sourceMappingURL=ReturningResultsEntityUpdator.js.map
|