fj.control.db.DbState Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of functionaljava Show documentation
Show all versions of functionaljava Show documentation
Functional Java is an open source library that supports closures for the Java programming language
package fj.control.db;
import fj.Unit;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* Performs database I/O, in order to read or write the database state.
*/
public final class DbState {
private final Connector pc;
private final DB terminal;
private DbState(final Connector pc, final DB terminal) {
this.pc = pc;
this.terminal = terminal;
}
/**
* A simple connector (the default) that gets connections to the given database URL from the driver manager.
*
* @param url The database URL to connect to.
* @return A connector that generates connections to the given database.
*/
public static Connector driverManager(final String url) {
return new Connector() {
public Connection connect() throws SQLException {
return DriverManager.getConnection(url);
}
};
}
/**
* Creates a database state reader given a connection URL.
*
* @param url The connection URL to the database.
* @return A database state reader that reads the given database.
*/
public static DbState reader(final String url) {
return new DbState(driverManager(url), rollback);
}
/**
* Creates a database state writer given a connection URL.
*
* @param url The connection URL to the database.
* @return A database state writer that writes the given database.
*/
public static DbState writer(final String url) {
return new DbState(driverManager(url), commit);
}
/**
* Returns a new reader that reads the database via the given Connector.
*
* @param pc A connector with which to generate database connections.
* @return A new reader that reads the database via the given Connector.
*/
public static DbState reader(final Connector pc) {
return new DbState(pc, rollback);
}
/**
* Returns a new writer that writes the database via the given Connector.
*
* @param pc A connector with which to generate database connections.
* @return A new writer that writes the database via the given Connector.
*/
public static DbState writer(final Connector pc) {
return new DbState(pc, commit);
}
private static final DB rollback = new DB() {
public Unit run(final Connection c) throws SQLException {
c.rollback();
return Unit.unit();
}
};
private static final DB commit = new DB() {
public Unit run(final Connection c) throws SQLException {
c.commit();
return Unit.unit();
}
};
/**
* Runs the given database action as a single transaction.
*
* @param dba A database action to run.
* @return The result of running the action against the database.
* @throws SQLException in case of a database error.
*/
public A run(final DB dba) throws SQLException {
try (Connection c = pc.connect()) {
c.setAutoCommit(false);
final A a;
try {
a = dba.run(c);
} catch (RuntimeException | SQLException e) {
try {
c.rollback();
} catch (Exception re) {
e.addSuppressed(re);
}
throw e;
}
terminal.run(c);
return a;
}
}
}