mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 19:59:05 +01:00
Throw meaningful exceptions for schema errors.
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
package org.briarproject.bramble.api.db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when the database uses a newer schema than the current code.
|
||||||
|
*/
|
||||||
|
public class DataTooNewException extends DbException {
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package org.briarproject.bramble.api.db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when the database uses an older schema than the current code and
|
||||||
|
* cannot be migrated.
|
||||||
|
*/
|
||||||
|
public class DataTooOldException extends DbException {
|
||||||
|
}
|
||||||
@@ -37,6 +37,11 @@ public interface DatabaseComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the database and returns true if the database already existed.
|
* Opens the database and returns true if the database already existed.
|
||||||
|
*
|
||||||
|
* @throws DataTooNewException if the data uses a newer schema than the
|
||||||
|
* current code
|
||||||
|
* @throws DataTooOldException if the data uses an older schema than the
|
||||||
|
* current code and cannot be migrated
|
||||||
*/
|
*/
|
||||||
boolean open() throws DbException;
|
boolean open() throws DbException;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package org.briarproject.bramble.db;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
|
import org.briarproject.bramble.api.db.DataTooNewException;
|
||||||
|
import org.briarproject.bramble.api.db.DataTooOldException;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Metadata;
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
@@ -37,6 +39,11 @@ interface Database<T> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the database and returns true if the database already existed.
|
* Opens the database and returns true if the database already existed.
|
||||||
|
*
|
||||||
|
* @throws DataTooNewException if the data uses a newer schema than the
|
||||||
|
* current code
|
||||||
|
* @throws DataTooOldException if the data uses an older schema than the
|
||||||
|
* current code and cannot be migrated
|
||||||
*/
|
*/
|
||||||
boolean open() throws DbException;
|
boolean open() throws DbException;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package org.briarproject.bramble.db;
|
|||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
|
import org.briarproject.bramble.api.db.DataTooNewException;
|
||||||
|
import org.briarproject.bramble.api.db.DataTooOldException;
|
||||||
import org.briarproject.bramble.api.db.DbClosedException;
|
import org.briarproject.bramble.api.db.DbClosedException;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Metadata;
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
@@ -295,7 +297,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
Connection txn = startTransaction();
|
Connection txn = startTransaction();
|
||||||
try {
|
try {
|
||||||
if (reopen) {
|
if (reopen) {
|
||||||
if (!checkSchemaVersion(txn)) throw new DbException();
|
checkSchemaVersion(txn);
|
||||||
} else {
|
} else {
|
||||||
createTables(txn);
|
createTables(txn);
|
||||||
storeSchemaVersion(txn, CODE_SCHEMA_VERSION);
|
storeSchemaVersion(txn, CODE_SCHEMA_VERSION);
|
||||||
@@ -310,16 +312,21 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares the schema version stored in the database with the schema
|
* Compares the schema version stored in the database with the schema
|
||||||
* version used by the current code, applies any suitable migrations to the
|
* version used by the current code and applies any suitable migrations to
|
||||||
* data if necessary, and returns true if the schema now matches the
|
* the data if necessary.
|
||||||
* current code.
|
*
|
||||||
|
* @throws DataTooNewException if the data uses a newer schema than the
|
||||||
|
* current code
|
||||||
|
* @throws DataTooOldException if the data uses an older schema than the
|
||||||
|
* current code and cannot be migrated
|
||||||
*/
|
*/
|
||||||
private boolean checkSchemaVersion(Connection txn) throws DbException {
|
private void checkSchemaVersion(Connection txn) throws DbException {
|
||||||
Settings s = getSettings(txn, DB_SETTINGS_NAMESPACE);
|
Settings s = getSettings(txn, DB_SETTINGS_NAMESPACE);
|
||||||
int dataSchemaVersion = s.getInt(SCHEMA_VERSION_KEY, -1);
|
int dataSchemaVersion = s.getInt(SCHEMA_VERSION_KEY, -1);
|
||||||
if (dataSchemaVersion == -1) return false;
|
if (dataSchemaVersion == -1) throw new DbException();
|
||||||
if (dataSchemaVersion == CODE_SCHEMA_VERSION) return true;
|
if (dataSchemaVersion == CODE_SCHEMA_VERSION) return;
|
||||||
if (CODE_SCHEMA_VERSION < dataSchemaVersion) return false;
|
if (CODE_SCHEMA_VERSION < dataSchemaVersion)
|
||||||
|
throw new DataTooNewException();
|
||||||
// Apply any suitable migrations in order
|
// Apply any suitable migrations in order
|
||||||
for (Migration<Connection> m : getMigrations()) {
|
for (Migration<Connection> m : getMigrations()) {
|
||||||
int start = m.getStartVersion(), end = m.getEndVersion();
|
int start = m.getStartVersion(), end = m.getEndVersion();
|
||||||
@@ -333,7 +340,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
dataSchemaVersion = end;
|
dataSchemaVersion = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dataSchemaVersion == CODE_SCHEMA_VERSION;
|
if (dataSchemaVersion != CODE_SCHEMA_VERSION)
|
||||||
|
throw new DataTooOldException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Package access for testing
|
// Package access for testing
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.briarproject.bramble.db;
|
package org.briarproject.bramble.db;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.db.DataTooNewException;
|
||||||
|
import org.briarproject.bramble.api.db.DataTooOldException;
|
||||||
import org.briarproject.bramble.api.db.DatabaseConfig;
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
@@ -95,7 +97,7 @@ public abstract class DatabaseMigrationTest extends BrambleMockTestCase {
|
|||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DbException.class)
|
@Test(expected = DataTooNewException.class)
|
||||||
public void testThrowsExceptionIfDataIsNewerThanCode() throws Exception {
|
public void testThrowsExceptionIfDataIsNewerThanCode() throws Exception {
|
||||||
// Open the DB for the first time
|
// Open the DB for the first time
|
||||||
Database<Connection> db = createDatabase(asList(migration, migration1));
|
Database<Connection> db = createDatabase(asList(migration, migration1));
|
||||||
@@ -109,7 +111,7 @@ public abstract class DatabaseMigrationTest extends BrambleMockTestCase {
|
|||||||
db.open();
|
db.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DbException.class)
|
@Test(expected = DataTooOldException.class)
|
||||||
public void testThrowsExceptionIfCodeIsNewerThanDataAndNoMigrations()
|
public void testThrowsExceptionIfCodeIsNewerThanDataAndNoMigrations()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
// Open the DB for the first time
|
// Open the DB for the first time
|
||||||
@@ -123,7 +125,7 @@ public abstract class DatabaseMigrationTest extends BrambleMockTestCase {
|
|||||||
db.open();
|
db.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DbException.class)
|
@Test(expected = DataTooOldException.class)
|
||||||
public void testThrowsExceptionIfCodeIsNewerThanDataAndNoSuitableMigration()
|
public void testThrowsExceptionIfCodeIsNewerThanDataAndNoSuitableMigration()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
|
|||||||
Reference in New Issue
Block a user