forked from functionaljava/functionaljava
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDbState.java
More file actions
114 lines (102 loc) · 3.23 KB
/
DbState.java
File metadata and controls
114 lines (102 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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<Unit> terminal;
private DbState(final Connector pc, final DB<Unit> 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<Unit> rollback = new DB<Unit>() {
public Unit run(final Connection c) throws SQLException {
c.rollback();
return Unit.unit();
}
};
private static final DB<Unit> commit = new DB<Unit>() {
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> A run(final DB<A> 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;
}
}
}