use of org.folio.rest.persist.SQLConnection in project mod-circulation-storage by folio-org.
the class ExpirationTool method resetPositionsForOpenRequestsByIdemIds.
private static Future<RowSet<Row>> resetPositionsForOpenRequestsByIdemIds(AsyncResult<SQLConnection> conn, Vertx vertx, String tenant, Set<String> itemIds) {
if (itemIds.isEmpty()) {
succeededFuture();
}
Set<String> quotedItemIds = itemIds.stream().map(id -> format("'%s'", id)).collect(toSet());
String fullTableName = format("%s.%s", PostgresClient.convertToPsqlStandard(tenant), REQUEST_TABLE);
String sql = format("UPDATE %1$s SET jsonb = jsonb - 'position' WHERE " + "(jsonb->>'status' = '%2$s' OR " + "jsonb->>'status' = '%3$s' OR " + "jsonb->>'status' = '%4$s' OR " + "jsonb->>'status' = '%5$s') AND " + "jsonb->>'itemId' IN (%6$s)", fullTableName, OPEN_NOT_YET_FILLED.value(), OPEN_AWAITING_PICKUP.value(), OPEN_AWAITING_DELIVERY.value(), OPEN_IN_TRANSIT.value(), String.join(",", quotedItemIds));
Promise<RowSet<Row>> promise = Promise.promise();
PostgresClient pgClient = PostgresClient.getInstance(vertx, tenant);
pgClient.execute(conn, sql, promise);
return promise.future().map(ur -> null);
}
use of org.folio.rest.persist.SQLConnection in project mod-circulation-storage by folio-org.
the class ExpirationTool method closeRequests.
private static Future<Set<String>> closeRequests(AsyncResult<SQLConnection> conn, Vertx vertx, String tenant, List<Request> requests, List<JsonObject> context) {
Future<Void> future = succeededFuture();
Set<String> closedRequestsItemIds = new HashSet<>();
for (Request request : requests) {
JsonObject pair = new JsonObject();
pair.put(ORIGINAL.value(), JsonObject.mapFrom(request));
closedRequestsItemIds.add(request.getItemId());
Request updatedRequest = changeRequestStatus(request).withPosition(null);
pair.put(UPDATED.value(), JsonObject.mapFrom(updatedRequest));
context.add(pair);
future = future.compose(v -> updateRequest(conn, vertx, tenant, updatedRequest));
}
return future.map(v -> closedRequestsItemIds);
}
use of org.folio.rest.persist.SQLConnection in project mod-circulation-storage by folio-org.
the class BatchResourceService method executeBatchUpdate.
/**
* Execute batch update in a single transaction, subsequently.
*
* @param batchFactories - Factory to create a batch update chunk.
* @param onFinishHandler - Callback.
*/
public void executeBatchUpdate(List<Function<SQLConnection, Future<RowSet<Row>>>> batchFactories, Handler<AsyncResult<Void>> onFinishHandler) {
postgresClient.startTx(connectionResult -> {
if (connectionResult.failed()) {
LOG.warn("Can not start transaction", connectionResult.cause());
onFinishHandler.handle(failedFuture(connectionResult.cause()));
return;
}
SQLConnection connection = connectionResult.result();
// Using this future for chaining updates
Future<RowSet<Row>> lastUpdate = succeededFuture();
for (Function<SQLConnection, Future<RowSet<Row>>> factory : batchFactories) {
lastUpdate = lastUpdate.compose(prev -> factory.apply(connection));
}
// Handle overall update result and decide on whether to commit or rollback transaction
lastUpdate.onComplete(updateResult -> {
if (updateResult.failed()) {
LOG.warn("Batch update rejected", updateResult.cause());
// Rollback transaction and keep original cause.
postgresClient.rollbackTx(connectionResult, rollback -> onFinishHandler.handle(failedFuture(updateResult.cause())));
} else {
LOG.debug("Update successful, committing transaction");
postgresClient.endTx(connectionResult, onFinishHandler);
}
});
});
}
use of org.folio.rest.persist.SQLConnection in project mod-source-record-manager by folio-org.
the class JobExecutionProgressDaoImpl method initializeJobExecutionProgress.
@Override
public Future<JobExecutionProgress> initializeJobExecutionProgress(String jobExecutionId, Integer totalRecords, String tenantId) {
Promise<JobExecutionProgress> promise = Promise.promise();
Promise<SQLConnection> tx = Promise.promise();
PostgresClient pgClient = pgClientFactory.createInstance(tenantId);
getSelectResult(tx, pgClient, jobExecutionId, tenantId).compose(selectResult -> {
JobExecutionProgress progress = new JobExecutionProgress().withJobExecutionId(jobExecutionId).withTotal(totalRecords);
Optional<JobExecutionProgress> optionalJobExecutionProgress = mapResultSetToOptionalJobExecutionProgress(selectResult);
return optionalJobExecutionProgress.isEmpty() ? save(progress, tenantId).map(progress) : Future.succeededFuture(optionalJobExecutionProgress.get());
}).onComplete(saveAr -> {
if (saveAr.succeeded()) {
pgClient.endTx(tx.future(), endTx -> promise.complete(saveAr.result()));
} else {
if (ValidationHelper.isDuplicate(saveAr.cause().getMessage())) {
pgClient.rollbackTx(tx.future(), r -> promise.complete());
return;
}
LOGGER.error(FAILED_INITIALIZATION_MESSAGE, jobExecutionId, saveAr.cause());
pgClient.rollbackTx(tx.future(), r -> promise.fail(saveAr.cause()));
}
});
return promise.future();
}
use of org.folio.rest.persist.SQLConnection in project mod-source-record-manager by folio-org.
the class JobExecutionDaoImpl method updateBlocking.
@Override
public Future<JobExecution> updateBlocking(String jobExecutionId, JobExecutionMutator mutator, String tenantId) {
Promise<JobExecution> promise = Promise.promise();
String rollbackMessage = "Rollback transaction. Error during jobExecution update. jobExecutionId" + jobExecutionId;
Promise<SQLConnection> connection = Promise.promise();
Promise<JobExecution> jobExecutionPromise = Promise.promise();
Future.succeededFuture().compose(v -> {
pgClientFactory.createInstance(tenantId).startTx(connection);
return connection.future();
}).compose(v -> {
String selectForUpdate = format("SELECT * FROM %s WHERE id = $1 AND is_deleted = false LIMIT 1 FOR UPDATE", formatFullTableName(tenantId, TABLE_NAME));
Promise<RowSet<Row>> selectResult = Promise.promise();
pgClientFactory.createInstance(tenantId).execute(connection.future(), selectForUpdate, Tuple.of(jobExecutionId), selectResult);
return selectResult.future();
}).compose(rowSet -> {
if (rowSet.rowCount() != 1) {
throw new NotFoundException(rollbackMessage);
}
return mutator.mutate(mapRowToJobExecution(rowSet.iterator().next())).onComplete(jobExecutionPromise);
}).compose(jobExecution -> {
Promise<RowSet<Row>> updateHandler = Promise.promise();
String preparedQuery = format(UPDATE_SQL, formatFullTableName(tenantId, TABLE_NAME));
Tuple queryParams = mapToTuple(jobExecution);
pgClientFactory.createInstance(tenantId).execute(connection.future(), preparedQuery, queryParams, updateHandler);
return updateHandler.future();
}).compose(updateHandler -> {
Promise<Void> endTxFuture = Promise.promise();
pgClientFactory.createInstance(tenantId).endTx(connection.future(), endTxFuture);
return endTxFuture.future();
}).onComplete(ar -> {
if (ar.failed()) {
pgClientFactory.createInstance(tenantId).rollbackTx(connection.future(), rollback -> promise.fail(ar.cause()));
return;
}
promise.complete(jobExecutionPromise.future().result());
});
return promise.future();
}
Aggregations