se.fortnox.reactivewizard.db.transactions.TransactionExecutor Maven / Gradle / Ivy
package se.fortnox.reactivewizard.db.transactions;
import se.fortnox.reactivewizard.db.statement.Statement;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
/**
* class with helper methods used when executing stuff inside a database transaction.
*/
class TransactionExecutor {
private static final String WRONG_TYPE_ERROR =
"All parameters to createTransaction needs to be Publishers coming from a Dao-class, i.e. decorated. Statement was %s.";
/**
* Creates a Transaction based on a Collection of StatementContexts.
* @param statementContexts the collection of StatementContext to use
* @return the Transaction
*/
Transaction createTransactionWithStatements(Collection statementContexts) {
List transactionStatements = new ArrayList<>();
for (StatementContext statementContext : statementContexts) {
Statement statement = statementContext.getStatement();
TransactionStatement transactionStatement = new TransactionStatement(statement);
transactionStatements.add(transactionStatement);
}
return new Transaction(transactionStatements);
}
/**
* Execute all the statements contained in the list of StatementContext on the provided connection.
* @param statementContexts list of StatementContext to use
* @param connection the connection to use when executing statements.
*/
void executeTransaction(List statementContexts, Connection connection) throws Exception {
Transaction transaction = createTransactionWithStatements(statementContexts);
transaction.execute(connection);
statementContexts.forEach(StatementContext::transactionCompleted);
}
/**
* Extracts a list of StatementContext from the provided dao calls.
* @param daoCalls the list of dao calls to fetch StatementContext from
* @param getDecoration a function extracting the decoration from the type in the daoCalls iterable.
* @param Flux or Mono
*
* @return a list of statement contexts.
*/
List getStatementContexts(Iterable daoCalls, Function> getDecoration) {
List daoStatementContexts = new ArrayList<>();
for (T statement : daoCalls) {
Optional> decoration = getDecoration.apply(statement);
if (decoration.isEmpty() || !(decoration.get() instanceof StatementContext statementContext)) {
String statementString = statement == null ? "null" : statement.getClass().toString();
throw new TransactionExecutionException(String.format(WRONG_TYPE_ERROR, statementString));
}
daoStatementContexts.add(statementContext);
}
return daoStatementContexts;
}
/**
* Get the connection scheduler to use when executing the statements.
* Will get the first connection scheduler from the first StatementContext.
*
* @param statementContexts list of StatementContext
* @return the ConnectionScheduler to use
*
* @throws RuntimeException if a ConnectionScheduler could not be found.
*/
ConnectionScheduler getConnectionScheduler(List statementContexts) {
return statementContexts.stream()
.map(StatementContext::getConnectionScheduler)
.filter(ConnectionScheduler::hasConnectionProvider)
.findFirst()
.orElseThrow(() -> new TransactionExecutionException("No Publisher with a valid connection provider was found"));
}
static class TransactionExecutionException extends RuntimeException {
public TransactionExecutionException(String message) {
super(message);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy