mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 20:29:52 +01:00
Upgrade H2 to 2.2.220.
Columns called "key" and "value" are no longer allowed. MVCC is mandatory.
This commit is contained in:
@@ -14,7 +14,9 @@ dependencies {
|
||||
api "org.briarproject:onionwrapper-core:$onionwrapper_version"
|
||||
|
||||
implementation "org.bouncycastle:bcprov-jdk15to18:$bouncy_castle_version"
|
||||
implementation 'com.h2database:h2:1.4.200' // The last version that doesn't require NIO
|
||||
// 2.2.222 includes a precompiled Java 21 class that breaks the jetifier, so it will require
|
||||
// a Gradle/AGP upgrade
|
||||
implementation 'com.h2database:h2:2.2.220'
|
||||
implementation 'org.bitlet:weupnp:0.1.4'
|
||||
implementation 'net.i2p.crypto:eddsa:0.2.0'
|
||||
implementation 'org.whispersystems:curve25519-java:0.5.0'
|
||||
|
||||
@@ -38,7 +38,7 @@ class H2Database extends JdbcDatabase {
|
||||
|
||||
private static final String HASH_TYPE = "BINARY(32)";
|
||||
private static final String SECRET_TYPE = "BINARY(32)";
|
||||
private static final String BINARY_TYPE = "BINARY";
|
||||
private static final String BINARY_TYPE = "BINARY VARYING";
|
||||
private static final String COUNTER_TYPE = "INT NOT NULL AUTO_INCREMENT";
|
||||
private static final String STRING_TYPE = "VARCHAR";
|
||||
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
||||
|
||||
@@ -117,7 +117,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
"CREATE TABLE settings"
|
||||
+ " (namespace _STRING NOT NULL,"
|
||||
+ " settingKey _STRING NOT NULL,"
|
||||
+ " value _STRING NOT NULL,"
|
||||
+ " settingValue _STRING NOT NULL,"
|
||||
+ " PRIMARY KEY (namespace, settingKey))";
|
||||
|
||||
private static final String CREATE_LOCAL_AUTHORS =
|
||||
@@ -143,7 +143,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " handshakePublicKey _BINARY," // Null if key is unknown
|
||||
+ " localAuthorId _HASH NOT NULL,"
|
||||
+ " verified BOOLEAN NOT NULL,"
|
||||
+ " syncVersions _BINARY DEFAULT '00' NOT NULL,"
|
||||
+ " syncVersions _BINARY DEFAULT X'00' NOT NULL,"
|
||||
+ " PRIMARY KEY (contactId),"
|
||||
+ " FOREIGN KEY (localAuthorId)"
|
||||
+ " REFERENCES localAuthors (authorId)"
|
||||
@@ -161,7 +161,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
"CREATE TABLE groupMetadata"
|
||||
+ " (groupId _HASH NOT NULL,"
|
||||
+ " metaKey _STRING NOT NULL,"
|
||||
+ " value _BINARY NOT NULL,"
|
||||
+ " metaValue _BINARY NOT NULL,"
|
||||
+ " PRIMARY KEY (groupId, metaKey),"
|
||||
+ " FOREIGN KEY (groupId)"
|
||||
+ " REFERENCES groups (groupId)"
|
||||
@@ -206,7 +206,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " groupId _HASH NOT NULL," // Denormalised
|
||||
+ " state INT NOT NULL," // Denormalised
|
||||
+ " metaKey _STRING NOT NULL,"
|
||||
+ " value _BINARY NOT NULL,"
|
||||
+ " metaValue _BINARY NOT NULL,"
|
||||
+ " PRIMARY KEY (messageId, metaKey),"
|
||||
+ " FOREIGN KEY (messageId)"
|
||||
+ " REFERENCES messages (messageId)"
|
||||
@@ -1926,7 +1926,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
Set<MessageId> intersection = null;
|
||||
String sql = "SELECT messageId FROM messageMetadata"
|
||||
+ " WHERE groupId = ? AND state = ?"
|
||||
+ " AND metaKey = ? AND value = ?";
|
||||
+ " AND metaKey = ? AND metaValue = ?";
|
||||
for (Entry<String, byte[]> e : query.entrySet()) {
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, g.getBytes());
|
||||
@@ -1982,7 +1982,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT messageId, metaKey, value"
|
||||
String sql = "SELECT messageId, metaKey, metaValue"
|
||||
+ " FROM messageMetadata"
|
||||
+ " WHERE groupId = ? AND state = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
@@ -2027,7 +2027,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT metaKey, value FROM groupMetadata"
|
||||
String sql = "SELECT metaKey, metaValue FROM groupMetadata"
|
||||
+ " WHERE groupId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, g.getBytes());
|
||||
@@ -2050,7 +2050,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT metaKey, value FROM messageMetadata"
|
||||
String sql = "SELECT metaKey, metaValue FROM messageMetadata"
|
||||
+ " WHERE state = ? AND messageId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, DELIVERED.getValue());
|
||||
@@ -2074,7 +2074,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT metaKey, value FROM messageMetadata"
|
||||
String sql = "SELECT metaKey, metaValue FROM messageMetadata"
|
||||
+ " WHERE (state = ? OR state = ?)"
|
||||
+ " AND messageId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
@@ -2678,7 +2678,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT settingKey, value FROM settings"
|
||||
String sql = "SELECT settingKey, settingValue FROM settings"
|
||||
+ " WHERE namespace = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setString(1, namespace);
|
||||
@@ -2914,7 +2914,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
g.getBytes(), meta, "groupMetadata", "groupId");
|
||||
if (added.isEmpty()) return;
|
||||
// Insert any keys that don't already exist
|
||||
String sql = "INSERT INTO groupMetadata (groupId, metaKey, value)"
|
||||
String sql = "INSERT INTO groupMetadata"
|
||||
+ " (groupId, metaKey, metaValue)"
|
||||
+ " VALUES (?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, g.getBytes());
|
||||
@@ -2957,7 +2958,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.close();
|
||||
// Insert any keys that don't already exist
|
||||
sql = "INSERT INTO messageMetadata"
|
||||
+ " (messageId, groupId, state, metaKey, value)"
|
||||
+ " (messageId, groupId, state, metaKey, metaValue)"
|
||||
+ " VALUES (?, ?, ?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, m.getBytes());
|
||||
@@ -3016,7 +3017,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
if (notRemoved.isEmpty()) return Collections.emptyMap();
|
||||
// Update any keys that already exist
|
||||
String sql = "UPDATE " + tableName + " SET value = ?"
|
||||
String sql = "UPDATE " + tableName + " SET metaValue = ?"
|
||||
+ " WHERE " + columnName + " = ? AND metaKey = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(2, id);
|
||||
@@ -3053,7 +3054,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
// Update any settings that already exist
|
||||
String sql = "UPDATE settings SET value = ?"
|
||||
String sql = "UPDATE settings SET settingValue = ?"
|
||||
+ " WHERE namespace = ? AND settingKey = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
for (Entry<String, String> e : s.entrySet()) {
|
||||
@@ -3069,7 +3070,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
if (rows > 1) throw new DbStateException();
|
||||
}
|
||||
// Insert any settings that don't already exist
|
||||
sql = "INSERT INTO settings (namespace, settingKey, value)"
|
||||
sql = "INSERT INTO settings (namespace, settingKey, settingValue)"
|
||||
+ " VALUES (?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
int updateIndex = 0, inserted = 0;
|
||||
|
||||
@@ -23,21 +23,18 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
||||
|
||||
private static final String DROP_TABLE = "DROP TABLE foo IF EXISTS";
|
||||
private static final String CREATE_TABLE = "CREATE TABLE foo"
|
||||
+ " (key INT NOT NULL,"
|
||||
+ " (_key INT NOT NULL,"
|
||||
+ " counter INT NOT NULL)";
|
||||
private static final String INSERT_ROW =
|
||||
"INSERT INTO foo (key, counter) VALUES (1, 123)";
|
||||
"INSERT INTO foo (_key, counter) VALUES (1, 123)";
|
||||
private static final String GET_COUNTER =
|
||||
"SELECT counter FROM foo WHERE key = 1";
|
||||
"SELECT counter FROM foo WHERE _key = 1";
|
||||
private static final String SET_COUNTER =
|
||||
"UPDATE foo SET counter = ? WHERE key = 1";
|
||||
"UPDATE foo SET counter = ? WHERE _key = 1";
|
||||
|
||||
private final File testDir = TestUtils.getTestDirectory();
|
||||
private final File db = new File(testDir, "db");
|
||||
private final String withMvcc = "jdbc:h2:split:" + db.getAbsolutePath()
|
||||
+ ";MV_STORE=TRUE";
|
||||
private final String withoutMvcc = "jdbc:h2:split:" + db.getAbsolutePath()
|
||||
+ ";MV_STORE=FALSE;LOCK_MODE=1";
|
||||
private final String url = "jdbc:h2:split:" + db.getAbsolutePath();
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@@ -52,14 +49,14 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testDoesNotReadUncommittedWritesWithMvcc() throws Exception {
|
||||
Connection connection = openConnection(true);
|
||||
Connection connection = openConnection();
|
||||
try {
|
||||
createTableAndInsertRow(connection);
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
// Start the first transaction
|
||||
Connection txn1 = openConnection(true);
|
||||
Connection txn1 = openConnection();
|
||||
try {
|
||||
txn1.setAutoCommit(false);
|
||||
// The first transaction should read the initial value
|
||||
@@ -67,7 +64,7 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
||||
// The first transaction updates the value but doesn't commit it
|
||||
assertEquals(1, setCounter(txn1, 234));
|
||||
// Start the second transaction
|
||||
Connection txn2 = openConnection(true);
|
||||
Connection txn2 = openConnection();
|
||||
try {
|
||||
txn2.setAutoCommit(false);
|
||||
// The second transaction should still read the initial value
|
||||
@@ -86,14 +83,14 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testLastWriterWinsWithMvcc() throws Exception {
|
||||
Connection connection = openConnection(true);
|
||||
Connection connection = openConnection();
|
||||
try {
|
||||
createTableAndInsertRow(connection);
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
// Start the first transaction
|
||||
Connection txn1 = openConnection(true);
|
||||
Connection txn1 = openConnection();
|
||||
try {
|
||||
txn1.setAutoCommit(false);
|
||||
// The first transaction should read the initial value
|
||||
@@ -101,7 +98,7 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
||||
// The first transaction updates the value but doesn't commit it
|
||||
assertEquals(1, setCounter(txn1, 234));
|
||||
// Start the second transaction
|
||||
Connection txn2 = openConnection(true);
|
||||
Connection txn2 = openConnection();
|
||||
try {
|
||||
txn2.setAutoCommit(false);
|
||||
// The second transaction should still read the initial value
|
||||
@@ -119,7 +116,7 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
||||
txn1.close();
|
||||
}
|
||||
// The second transaction was the last writer, so it should win
|
||||
connection = openConnection(true);
|
||||
connection = openConnection();
|
||||
try {
|
||||
assertEquals(345, getCounter(connection));
|
||||
} finally {
|
||||
@@ -129,20 +126,20 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testLockTimeoutOnRowWithMvcc() throws Exception {
|
||||
Connection connection = openConnection(true);
|
||||
Connection connection = openConnection();
|
||||
try {
|
||||
createTableAndInsertRow(connection);
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
// Start the first transaction
|
||||
Connection txn1 = openConnection(true);
|
||||
Connection txn1 = openConnection();
|
||||
try {
|
||||
txn1.setAutoCommit(false);
|
||||
// The first transaction should read the initial value
|
||||
assertEquals(123, getCounter(txn1));
|
||||
// Start the second transaction
|
||||
Connection txn2 = openConnection(true);
|
||||
Connection txn2 = openConnection();
|
||||
try {
|
||||
txn2.setAutoCommit(false);
|
||||
// The second transaction should read the initial value
|
||||
@@ -167,84 +164,8 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadLockTimeoutOnTableWithoutMvcc() throws Exception {
|
||||
Connection connection = openConnection(false);
|
||||
try {
|
||||
createTableAndInsertRow(connection);
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
// Start the first transaction
|
||||
Connection txn1 = openConnection(false);
|
||||
try {
|
||||
txn1.setAutoCommit(false);
|
||||
// The first transaction should read the initial value
|
||||
assertEquals(123, getCounter(txn1));
|
||||
// Start the second transaction
|
||||
Connection txn2 = openConnection(false);
|
||||
try {
|
||||
txn2.setAutoCommit(false);
|
||||
// The second transaction should read the initial value
|
||||
assertEquals(123, getCounter(txn2));
|
||||
// The first transaction tries to update the value
|
||||
try {
|
||||
setCounter(txn1, 345);
|
||||
fail();
|
||||
} catch (SQLException expected) {
|
||||
// Expected: the table is locked by the second transaction
|
||||
}
|
||||
// Abort the transactions
|
||||
txn1.rollback();
|
||||
txn2.rollback();
|
||||
} finally {
|
||||
txn2.close();
|
||||
}
|
||||
} finally {
|
||||
txn1.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteLockTimeoutOnTableWithoutMvcc() throws Exception {
|
||||
Connection connection = openConnection(false);
|
||||
try {
|
||||
createTableAndInsertRow(connection);
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
// Start the first transaction
|
||||
Connection txn1 = openConnection(false);
|
||||
try {
|
||||
txn1.setAutoCommit(false);
|
||||
// The first transaction should read the initial value
|
||||
assertEquals(123, getCounter(txn1));
|
||||
// The first transaction updates the value but doesn't commit yet
|
||||
assertEquals(1, setCounter(txn1, 345));
|
||||
// Start the second transaction
|
||||
Connection txn2 = openConnection(false);
|
||||
try {
|
||||
txn2.setAutoCommit(false);
|
||||
// The second transaction tries to read the value
|
||||
try {
|
||||
getCounter(txn2);
|
||||
fail();
|
||||
} catch (SQLException expected) {
|
||||
// Expected: the table is locked by the first transaction
|
||||
}
|
||||
// Abort the transactions
|
||||
txn1.rollback();
|
||||
txn2.rollback();
|
||||
} finally {
|
||||
txn2.close();
|
||||
}
|
||||
} finally {
|
||||
txn1.close();
|
||||
}
|
||||
}
|
||||
|
||||
private Connection openConnection(boolean mvcc) throws SQLException {
|
||||
return DriverManager.getConnection(mvcc ? withMvcc : withoutMvcc);
|
||||
private Connection openConnection() throws SQLException {
|
||||
return DriverManager.getConnection(url);
|
||||
}
|
||||
|
||||
private void createTableAndInsertRow(Connection c) throws SQLException {
|
||||
|
||||
@@ -18,7 +18,7 @@ dependencyVerification {
|
||||
'com.google.guava:guava:31.0.1-jre:guava-31.0.1-jre.jar:d5be94d65e87bd219fb3193ad1517baa55a3b88fc91d21cf735826ab5af087b9',
|
||||
'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99',
|
||||
'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
|
||||
'com.h2database:h2:1.4.200:h2-1.4.200.jar:3ad9ac4b6aae9cd9d3ac1c447465e1ed06019b851b893dd6a8d76ddb6d85bca6',
|
||||
'com.h2database:h2:2.2.220:h2-2.2.220.jar:978ab863018d3f965e38880571c36293ea8b10a8086194159c4d5d20b50f0a57',
|
||||
'com.squareup.okhttp3:mockwebserver:4.10.0:mockwebserver-4.10.0.jar:af29da234e63159d6e0dea43bf8288eea97d71cdf1651a5ee2d6c0d0d4adbf8f',
|
||||
'com.squareup.okhttp3:okhttp:4.10.0:okhttp-4.10.0.jar:7580f14fa1691206e37081ad3f92063b1603b328da0bb316f2fef02e0562e7ec',
|
||||
'com.squareup.okio:okio-jvm:3.0.0:okio-jvm-3.0.0.jar:be64a0cc1f28ea9cd5c970dd7e7557af72c808d738c495b397bf897c9921e907',
|
||||
|
||||
Reference in New Issue
Block a user