1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var tslib_1 = require("tslib");
|
4 | var CockroachDriver_1 = require("../driver/cockroachdb/CockroachDriver");
|
5 | var QueryBuilder_1 = require("./QueryBuilder");
|
6 | var SqlServerDriver_1 = require("../driver/sqlserver/SqlServerDriver");
|
7 | var PostgresDriver_1 = require("../driver/postgres/PostgresDriver");
|
8 | var EntityMetadata_1 = require("../metadata/EntityMetadata");
|
9 | var UpdateResult_1 = require("./result/UpdateResult");
|
10 | var ReturningStatementNotSupportedError_1 = require("../error/ReturningStatementNotSupportedError");
|
11 | var ReturningResultsEntityUpdator_1 = require("./ReturningResultsEntityUpdator");
|
12 | var SqljsDriver_1 = require("../driver/sqljs/SqljsDriver");
|
13 | var MysqlDriver_1 = require("../driver/mysql/MysqlDriver");
|
14 | var BroadcasterResult_1 = require("../subscriber/BroadcasterResult");
|
15 | var AbstractSqliteDriver_1 = require("../driver/sqlite-abstract/AbstractSqliteDriver");
|
16 | var LimitOnUpdateNotSupportedError_1 = require("../error/LimitOnUpdateNotSupportedError");
|
17 | var OracleDriver_1 = require("../driver/oracle/OracleDriver");
|
18 | var UpdateValuesMissingError_1 = require("../error/UpdateValuesMissingError");
|
19 | var EntityColumnNotFound_1 = require("../error/EntityColumnNotFound");
|
20 |
|
21 |
|
22 |
|
23 | var UpdateQueryBuilder = (function (_super) {
|
24 | tslib_1.__extends(UpdateQueryBuilder, _super);
|
25 |
|
26 |
|
27 |
|
28 | function UpdateQueryBuilder(connectionOrQueryBuilder, queryRunner) {
|
29 | var _this = _super.call(this, connectionOrQueryBuilder, queryRunner) || this;
|
30 | _this.expressionMap.aliasNamePrefixingEnabled = false;
|
31 | return _this;
|
32 | }
|
33 |
|
34 |
|
35 |
|
36 | |
37 |
|
38 |
|
39 | UpdateQueryBuilder.prototype.getQuery = function () {
|
40 | var sql = this.createUpdateExpression();
|
41 | sql += this.createOrderByExpression();
|
42 | sql += this.createLimitExpression();
|
43 | return sql.trim();
|
44 | };
|
45 | |
46 |
|
47 |
|
48 | UpdateQueryBuilder.prototype.execute = function () {
|
49 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
50 | var queryRunner, transactionStartedByUs, broadcastResult, returningResultsEntityUpdator, _a, sql, parameters, updateResult, _b, broadcastResult, error_1, rollbackError_1;
|
51 | return tslib_1.__generator(this, function (_c) {
|
52 | switch (_c.label) {
|
53 | case 0:
|
54 | queryRunner = this.obtainQueryRunner();
|
55 | transactionStartedByUs = false;
|
56 | _c.label = 1;
|
57 | case 1:
|
58 | _c.trys.push([1, 13, 18, 23]);
|
59 | if (!(this.expressionMap.useTransaction === true && queryRunner.isTransactionActive === false)) return [3 , 3];
|
60 | return [4 , queryRunner.startTransaction()];
|
61 | case 2:
|
62 | _c.sent();
|
63 | transactionStartedByUs = true;
|
64 | _c.label = 3;
|
65 | case 3:
|
66 | if (!(this.expressionMap.callListeners === true && this.expressionMap.mainAlias.hasMetadata)) return [3 , 5];
|
67 | broadcastResult = new BroadcasterResult_1.BroadcasterResult();
|
68 | queryRunner.broadcaster.broadcastBeforeUpdateEvent(broadcastResult, this.expressionMap.mainAlias.metadata);
|
69 | if (!(broadcastResult.promises.length > 0)) return [3 , 5];
|
70 | return [4 , Promise.all(broadcastResult.promises)];
|
71 | case 4:
|
72 | _c.sent();
|
73 | _c.label = 5;
|
74 | case 5:
|
75 | returningResultsEntityUpdator = new ReturningResultsEntityUpdator_1.ReturningResultsEntityUpdator(queryRunner, this.expressionMap);
|
76 | if (this.expressionMap.updateEntity === true &&
|
77 | this.expressionMap.mainAlias.hasMetadata &&
|
78 | this.expressionMap.whereEntities.length > 0) {
|
79 | this.expressionMap.extraReturningColumns = returningResultsEntityUpdator.getUpdationReturningColumns();
|
80 | }
|
81 | _a = tslib_1.__read(this.getQueryAndParameters(), 2), sql = _a[0], parameters = _a[1];
|
82 | updateResult = new UpdateResult_1.UpdateResult();
|
83 | _b = updateResult;
|
84 | return [4 , queryRunner.query(sql, parameters)];
|
85 | case 6:
|
86 | _b.raw = _c.sent();
|
87 | if (!(this.expressionMap.updateEntity === true &&
|
88 | this.expressionMap.mainAlias.hasMetadata &&
|
89 | this.expressionMap.whereEntities.length > 0)) return [3 , 8];
|
90 | return [4 , returningResultsEntityUpdator.update(updateResult, this.expressionMap.whereEntities)];
|
91 | case 7:
|
92 | _c.sent();
|
93 | _c.label = 8;
|
94 | case 8:
|
95 | if (!(this.expressionMap.callListeners === true && this.expressionMap.mainAlias.hasMetadata)) return [3 , 10];
|
96 | broadcastResult = new BroadcasterResult_1.BroadcasterResult();
|
97 | queryRunner.broadcaster.broadcastAfterUpdateEvent(broadcastResult, this.expressionMap.mainAlias.metadata);
|
98 | if (!(broadcastResult.promises.length > 0)) return [3 , 10];
|
99 | return [4 , Promise.all(broadcastResult.promises)];
|
100 | case 9:
|
101 | _c.sent();
|
102 | _c.label = 10;
|
103 | case 10:
|
104 | if (!transactionStartedByUs) return [3 , 12];
|
105 | return [4 , queryRunner.commitTransaction()];
|
106 | case 11:
|
107 | _c.sent();
|
108 | _c.label = 12;
|
109 | case 12: return [2 , updateResult];
|
110 | case 13:
|
111 | error_1 = _c.sent();
|
112 | if (!transactionStartedByUs) return [3 , 17];
|
113 | _c.label = 14;
|
114 | case 14:
|
115 | _c.trys.push([14, 16, , 17]);
|
116 | return [4 , queryRunner.rollbackTransaction()];
|
117 | case 15:
|
118 | _c.sent();
|
119 | return [3 , 17];
|
120 | case 16:
|
121 | rollbackError_1 = _c.sent();
|
122 | return [3 , 17];
|
123 | case 17: throw error_1;
|
124 | case 18:
|
125 | if (!(queryRunner !== this.queryRunner)) return [3 , 20];
|
126 | return [4 , queryRunner.release()];
|
127 | case 19:
|
128 | _c.sent();
|
129 | _c.label = 20;
|
130 | case 20:
|
131 | if (!(this.connection.driver instanceof SqljsDriver_1.SqljsDriver && !queryRunner.isTransactionActive)) return [3 , 22];
|
132 | return [4 , this.connection.driver.autoSave()];
|
133 | case 21:
|
134 | _c.sent();
|
135 | _c.label = 22;
|
136 | case 22: return [7 ];
|
137 | case 23: return [2 ];
|
138 | }
|
139 | });
|
140 | });
|
141 | };
|
142 |
|
143 |
|
144 |
|
145 | |
146 |
|
147 |
|
148 | UpdateQueryBuilder.prototype.set = function (values) {
|
149 | this.expressionMap.valuesSet = values;
|
150 | return this;
|
151 | };
|
152 | |
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 | UpdateQueryBuilder.prototype.where = function (where, parameters) {
|
159 | this.expressionMap.wheres = [];
|
160 | var condition = this.computeWhereParameter(where);
|
161 | if (condition)
|
162 | this.expressionMap.wheres = [{ type: "simple", condition: condition }];
|
163 | if (parameters)
|
164 | this.setParameters(parameters);
|
165 | return this;
|
166 | };
|
167 | |
168 |
|
169 |
|
170 |
|
171 | UpdateQueryBuilder.prototype.andWhere = function (where, parameters) {
|
172 | this.expressionMap.wheres.push({ type: "and", condition: this.computeWhereParameter(where) });
|
173 | if (parameters)
|
174 | this.setParameters(parameters);
|
175 | return this;
|
176 | };
|
177 | |
178 |
|
179 |
|
180 |
|
181 | UpdateQueryBuilder.prototype.orWhere = function (where, parameters) {
|
182 | this.expressionMap.wheres.push({ type: "or", condition: this.computeWhereParameter(where) });
|
183 | if (parameters)
|
184 | this.setParameters(parameters);
|
185 | return this;
|
186 | };
|
187 | |
188 |
|
189 |
|
190 | UpdateQueryBuilder.prototype.whereInIds = function (ids) {
|
191 | return this.where(this.createWhereIdsExpression(ids));
|
192 | };
|
193 | |
194 |
|
195 |
|
196 | UpdateQueryBuilder.prototype.andWhereInIds = function (ids) {
|
197 | return this.andWhere(this.createWhereIdsExpression(ids));
|
198 | };
|
199 | |
200 |
|
201 |
|
202 | UpdateQueryBuilder.prototype.orWhereInIds = function (ids) {
|
203 | return this.orWhere(this.createWhereIdsExpression(ids));
|
204 | };
|
205 | |
206 |
|
207 |
|
208 | UpdateQueryBuilder.prototype.output = function (output) {
|
209 | return this.returning(output);
|
210 | };
|
211 | |
212 |
|
213 |
|
214 | UpdateQueryBuilder.prototype.returning = function (returning) {
|
215 |
|
216 | if (!this.connection.driver.isReturningSqlSupported())
|
217 | throw new ReturningStatementNotSupportedError_1.ReturningStatementNotSupportedError();
|
218 | this.expressionMap.returning = returning;
|
219 | return this;
|
220 | };
|
221 | |
222 |
|
223 |
|
224 |
|
225 |
|
226 | UpdateQueryBuilder.prototype.orderBy = function (sort, order, nulls) {
|
227 | if (order === void 0) { order = "ASC"; }
|
228 | var _a, _b;
|
229 | if (sort) {
|
230 | if (sort instanceof Object) {
|
231 | this.expressionMap.orderBys = sort;
|
232 | }
|
233 | else {
|
234 | if (nulls) {
|
235 | this.expressionMap.orderBys = (_a = {}, _a[sort] = { order: order, nulls: nulls }, _a);
|
236 | }
|
237 | else {
|
238 | this.expressionMap.orderBys = (_b = {}, _b[sort] = order, _b);
|
239 | }
|
240 | }
|
241 | }
|
242 | else {
|
243 | this.expressionMap.orderBys = {};
|
244 | }
|
245 | return this;
|
246 | };
|
247 | |
248 |
|
249 |
|
250 | UpdateQueryBuilder.prototype.addOrderBy = function (sort, order, nulls) {
|
251 | if (order === void 0) { order = "ASC"; }
|
252 | if (nulls) {
|
253 | this.expressionMap.orderBys[sort] = { order: order, nulls: nulls };
|
254 | }
|
255 | else {
|
256 | this.expressionMap.orderBys[sort] = order;
|
257 | }
|
258 | return this;
|
259 | };
|
260 | |
261 |
|
262 |
|
263 | UpdateQueryBuilder.prototype.limit = function (limit) {
|
264 | this.expressionMap.limit = limit;
|
265 | return this;
|
266 | };
|
267 | |
268 |
|
269 |
|
270 |
|
271 |
|
272 | UpdateQueryBuilder.prototype.whereEntity = function (entity) {
|
273 | var _this = this;
|
274 | if (!this.expressionMap.mainAlias.hasMetadata)
|
275 | throw new Error(".whereEntity method can only be used on queries which update real entity table.");
|
276 | this.expressionMap.wheres = [];
|
277 | var entities = entity instanceof Array ? entity : [entity];
|
278 | entities.forEach(function (entity) {
|
279 | var entityIdMap = _this.expressionMap.mainAlias.metadata.getEntityIdMap(entity);
|
280 | if (!entityIdMap)
|
281 | throw new Error("Provided entity does not have ids set, cannot perform operation.");
|
282 | _this.orWhereInIds(entityIdMap);
|
283 | });
|
284 | this.expressionMap.whereEntities = entities;
|
285 | return this;
|
286 | };
|
287 | |
288 |
|
289 |
|
290 |
|
291 |
|
292 | UpdateQueryBuilder.prototype.updateEntity = function (enabled) {
|
293 | this.expressionMap.updateEntity = enabled;
|
294 | return this;
|
295 | };
|
296 |
|
297 |
|
298 |
|
299 | |
300 |
|
301 |
|
302 | UpdateQueryBuilder.prototype.createUpdateExpression = function () {
|
303 | var _this = this;
|
304 | var valuesSet = this.getValueSet();
|
305 | var metadata = this.expressionMap.mainAlias.hasMetadata ? this.expressionMap.mainAlias.metadata : undefined;
|
306 |
|
307 | var updateColumnAndValues = [];
|
308 | var newParameters = {};
|
309 | var parametersCount = this.connection.driver instanceof MysqlDriver_1.MysqlDriver ||
|
310 | this.connection.driver instanceof OracleDriver_1.OracleDriver ||
|
311 | this.connection.driver instanceof AbstractSqliteDriver_1.AbstractSqliteDriver
|
312 | ? 0 : Object.keys(this.expressionMap.nativeParameters).length;
|
313 | if (metadata) {
|
314 | EntityMetadata_1.EntityMetadata.createPropertyPath(metadata, valuesSet).forEach(function (propertyPath) {
|
315 |
|
316 | var columns = metadata.findColumnsWithPropertyPath(propertyPath);
|
317 | if (columns.length <= 0) {
|
318 | throw new EntityColumnNotFound_1.EntityColumnNotFound(propertyPath);
|
319 | }
|
320 | columns.forEach(function (column) {
|
321 | if (!column.isUpdate) {
|
322 | return;
|
323 | }
|
324 | var paramName = "upd_" + column.databaseName;
|
325 |
|
326 | var value = column.getEntityValue(valuesSet);
|
327 | if (column.referencedColumn && value instanceof Object) {
|
328 | value = column.referencedColumn.getEntityValue(value);
|
329 | }
|
330 | else if (!(value instanceof Function)) {
|
331 | value = _this.connection.driver.preparePersistentValue(value, column);
|
332 | }
|
333 |
|
334 | if (value instanceof Function) {
|
335 | updateColumnAndValues.push(_this.escape(column.databaseName) + " = " + value());
|
336 | }
|
337 | else {
|
338 | if (_this.connection.driver instanceof SqlServerDriver_1.SqlServerDriver) {
|
339 | value = _this.connection.driver.parametrizeValue(column, value);
|
340 |
|
341 |
|
342 | }
|
343 | if (_this.connection.driver instanceof MysqlDriver_1.MysqlDriver ||
|
344 | _this.connection.driver instanceof OracleDriver_1.OracleDriver ||
|
345 | _this.connection.driver instanceof AbstractSqliteDriver_1.AbstractSqliteDriver) {
|
346 | newParameters[paramName] = value;
|
347 | }
|
348 | else {
|
349 | _this.expressionMap.nativeParameters[paramName] = value;
|
350 | }
|
351 | var expression = null;
|
352 | if (_this.connection.driver instanceof MysqlDriver_1.MysqlDriver && _this.connection.driver.spatialTypes.indexOf(column.type) !== -1) {
|
353 | expression = "GeomFromText(" + _this.connection.driver.createParameter(paramName, parametersCount) + ")";
|
354 | }
|
355 | else if (_this.connection.driver instanceof PostgresDriver_1.PostgresDriver && _this.connection.driver.spatialTypes.indexOf(column.type) !== -1) {
|
356 | if (column.srid != null) {
|
357 | expression = "ST_SetSRID(ST_GeomFromGeoJSON(" + _this.connection.driver.createParameter(paramName, parametersCount) + "), " + column.srid + ")::" + column.type;
|
358 | }
|
359 | else {
|
360 | expression = "ST_GeomFromGeoJSON(" + _this.connection.driver.createParameter(paramName, parametersCount) + ")::" + column.type;
|
361 | }
|
362 | }
|
363 | else {
|
364 | expression = _this.connection.driver.createParameter(paramName, parametersCount);
|
365 | }
|
366 | updateColumnAndValues.push(_this.escape(column.databaseName) + " = " + expression);
|
367 | parametersCount++;
|
368 | }
|
369 | });
|
370 | });
|
371 | if (metadata.versionColumn)
|
372 | updateColumnAndValues.push(this.escape(metadata.versionColumn.databaseName) + " = " + this.escape(metadata.versionColumn.databaseName) + " + 1");
|
373 | if (metadata.updateDateColumn)
|
374 | updateColumnAndValues.push(this.escape(metadata.updateDateColumn.databaseName) + " = CURRENT_TIMESTAMP");
|
375 | }
|
376 | else {
|
377 | Object.keys(valuesSet).map(function (key) {
|
378 | var value = valuesSet[key];
|
379 |
|
380 | if (value instanceof Function) {
|
381 | updateColumnAndValues.push(_this.escape(key) + " = " + value());
|
382 | }
|
383 | else {
|
384 |
|
385 |
|
386 |
|
387 | if (_this.connection.driver instanceof MysqlDriver_1.MysqlDriver ||
|
388 | _this.connection.driver instanceof OracleDriver_1.OracleDriver ||
|
389 | _this.connection.driver instanceof AbstractSqliteDriver_1.AbstractSqliteDriver) {
|
390 | newParameters[key] = value;
|
391 | }
|
392 | else {
|
393 | _this.expressionMap.nativeParameters[key] = value;
|
394 | }
|
395 | updateColumnAndValues.push(_this.escape(key) + " = " + _this.connection.driver.createParameter(key, parametersCount));
|
396 | parametersCount++;
|
397 | }
|
398 | });
|
399 | }
|
400 | if (updateColumnAndValues.length <= 0) {
|
401 | throw new UpdateValuesMissingError_1.UpdateValuesMissingError();
|
402 | }
|
403 |
|
404 |
|
405 | if (this.connection.driver instanceof MysqlDriver_1.MysqlDriver ||
|
406 | this.connection.driver instanceof OracleDriver_1.OracleDriver ||
|
407 | this.connection.driver instanceof AbstractSqliteDriver_1.AbstractSqliteDriver) {
|
408 | this.expressionMap.nativeParameters = Object.assign(newParameters, this.expressionMap.nativeParameters);
|
409 | }
|
410 |
|
411 | var whereExpression = this.createWhereExpression();
|
412 | var returningExpression = this.createReturningExpression();
|
413 |
|
414 | if (returningExpression && (this.connection.driver instanceof PostgresDriver_1.PostgresDriver || this.connection.driver instanceof OracleDriver_1.OracleDriver || this.connection.driver instanceof CockroachDriver_1.CockroachDriver)) {
|
415 | return "UPDATE " + this.getTableName(this.getMainTableName()) + " SET " + updateColumnAndValues.join(", ") + whereExpression + " RETURNING " + returningExpression;
|
416 | }
|
417 | else if (returningExpression && this.connection.driver instanceof SqlServerDriver_1.SqlServerDriver) {
|
418 | return "UPDATE " + this.getTableName(this.getMainTableName()) + " SET " + updateColumnAndValues.join(", ") + " OUTPUT " + returningExpression + whereExpression;
|
419 | }
|
420 | else {
|
421 | return "UPDATE " + this.getTableName(this.getMainTableName()) + " SET " + updateColumnAndValues.join(", ") + whereExpression;
|
422 | }
|
423 | };
|
424 | |
425 |
|
426 |
|
427 | UpdateQueryBuilder.prototype.createOrderByExpression = function () {
|
428 | var _this = this;
|
429 | var orderBys = this.expressionMap.orderBys;
|
430 | if (Object.keys(orderBys).length > 0)
|
431 | return " ORDER BY " + Object.keys(orderBys)
|
432 | .map(function (columnName) {
|
433 | if (typeof orderBys[columnName] === "string") {
|
434 | return _this.replacePropertyNames(columnName) + " " + orderBys[columnName];
|
435 | }
|
436 | else {
|
437 | return _this.replacePropertyNames(columnName) + " " + orderBys[columnName].order + " " + orderBys[columnName].nulls;
|
438 | }
|
439 | })
|
440 | .join(", ");
|
441 | return "";
|
442 | };
|
443 | |
444 |
|
445 |
|
446 | UpdateQueryBuilder.prototype.createLimitExpression = function () {
|
447 | var limit = this.expressionMap.limit;
|
448 | if (limit) {
|
449 | if (this.connection.driver instanceof MysqlDriver_1.MysqlDriver) {
|
450 | return " LIMIT " + limit;
|
451 | }
|
452 | else {
|
453 | throw new LimitOnUpdateNotSupportedError_1.LimitOnUpdateNotSupportedError();
|
454 | }
|
455 | }
|
456 | return "";
|
457 | };
|
458 | |
459 |
|
460 |
|
461 | UpdateQueryBuilder.prototype.getValueSet = function () {
|
462 | if (this.expressionMap.valuesSet instanceof Object)
|
463 | return this.expressionMap.valuesSet;
|
464 | throw new UpdateValuesMissingError_1.UpdateValuesMissingError();
|
465 | };
|
466 | return UpdateQueryBuilder;
|
467 | }(QueryBuilder_1.QueryBuilder));
|
468 | exports.UpdateQueryBuilder = UpdateQueryBuilder;
|
469 |
|
470 |
|