mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 20:29:52 +01:00
WIP: Create indexes on foreign key columns if needed.
This commit is contained in:
@@ -413,6 +413,9 @@ interface Database<T> {
|
|||||||
*/
|
*/
|
||||||
Collection<MessageId> getMessageIds(T txn, GroupId g) throws DbException;
|
Collection<MessageId> getMessageIds(T txn, GroupId g) throws DbException;
|
||||||
|
|
||||||
|
Collection<String> explainGetMessageIds(T txn, GroupId g)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the IDs of any delivered messages in the given group with
|
* Returns the IDs of any delivered messages in the given group with
|
||||||
* metadata that matches all entries in the given query. If the query is
|
* metadata that matches all entries in the given query. If the query is
|
||||||
|
|||||||
@@ -4,14 +4,16 @@ class DatabaseTypes {
|
|||||||
|
|
||||||
private final String hashType, secretType, binaryType;
|
private final String hashType, secretType, binaryType;
|
||||||
private final String counterType, stringType;
|
private final String counterType, stringType;
|
||||||
|
private final String explainCommand; // FIXME: Remove
|
||||||
|
|
||||||
public DatabaseTypes(String hashType, String secretType, String binaryType,
|
public DatabaseTypes(String hashType, String secretType, String binaryType,
|
||||||
String counterType, String stringType) {
|
String counterType, String stringType, String explainCommand) {
|
||||||
this.hashType = hashType;
|
this.hashType = hashType;
|
||||||
this.secretType = secretType;
|
this.secretType = secretType;
|
||||||
this.binaryType = binaryType;
|
this.binaryType = binaryType;
|
||||||
this.counterType = counterType;
|
this.counterType = counterType;
|
||||||
this.stringType = stringType;
|
this.stringType = stringType;
|
||||||
|
this.explainCommand = explainCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,6 +24,7 @@ class DatabaseTypes {
|
|||||||
* <li> _BINARY
|
* <li> _BINARY
|
||||||
* <li> _COUNTER
|
* <li> _COUNTER
|
||||||
* <li> _STRING
|
* <li> _STRING
|
||||||
|
* <li> _EXPLAIN
|
||||||
*/
|
*/
|
||||||
String replaceTypes(String s) {
|
String replaceTypes(String s) {
|
||||||
s = s.replaceAll("_HASH", hashType);
|
s = s.replaceAll("_HASH", hashType);
|
||||||
@@ -29,6 +32,7 @@ class DatabaseTypes {
|
|||||||
s = s.replaceAll("_BINARY", binaryType);
|
s = s.replaceAll("_BINARY", binaryType);
|
||||||
s = s.replaceAll("_COUNTER", counterType);
|
s = s.replaceAll("_COUNTER", counterType);
|
||||||
s = s.replaceAll("_STRING", stringType);
|
s = s.replaceAll("_STRING", stringType);
|
||||||
|
s = s.replaceAll("_EXPLAIN", explainCommand);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,8 +42,10 @@ class H2Database extends JdbcDatabase {
|
|||||||
private static final String COUNTER_TYPE =
|
private static final String COUNTER_TYPE =
|
||||||
"INT NOT NULL AUTO_INCREMENT PRIMARY KEY";
|
"INT NOT NULL AUTO_INCREMENT PRIMARY KEY";
|
||||||
private static final String STRING_TYPE = "VARCHAR";
|
private static final String STRING_TYPE = "VARCHAR";
|
||||||
|
private static final String EXPLAIN_COMMAND = "EXPLAIN";
|
||||||
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
||||||
SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE);
|
SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE,
|
||||||
|
EXPLAIN_COMMAND);
|
||||||
|
|
||||||
private final DatabaseConfig config;
|
private final DatabaseConfig config;
|
||||||
private final String url;
|
private final String url;
|
||||||
@@ -74,7 +76,7 @@ class H2Database extends JdbcDatabase {
|
|||||||
boolean reopen = isNonEmptyDirectory(dir);
|
boolean reopen = isNonEmptyDirectory(dir);
|
||||||
if (LOG.isLoggable(INFO)) LOG.info("Reopening DB: " + reopen);
|
if (LOG.isLoggable(INFO)) LOG.info("Reopening DB: " + reopen);
|
||||||
if (!reopen && dir.mkdirs()) LOG.info("Created database directory");
|
if (!reopen && dir.mkdirs()) LOG.info("Created database directory");
|
||||||
super.open("org.h2.Driver", reopen, key, listener);
|
super.open("org.h2.Driver", reopen, false, key, listener);
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Contents of account directory after opening DB:");
|
LOG.info("Contents of account directory after opening DB:");
|
||||||
logFileOrDir(LOG, INFO, dir.getParentFile());
|
logFileOrDir(LOG, INFO, dir.getParentFile());
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ class HyperSqlDatabase extends JdbcDatabase {
|
|||||||
private static final String COUNTER_TYPE = "INTEGER NOT NULL"
|
private static final String COUNTER_TYPE = "INTEGER NOT NULL"
|
||||||
+ " PRIMARY KEY GENERATED ALWAYS AS IDENTITY(START WITH 1)";
|
+ " PRIMARY KEY GENERATED ALWAYS AS IDENTITY(START WITH 1)";
|
||||||
private static final String STRING_TYPE = "VARCHAR";
|
private static final String STRING_TYPE = "VARCHAR";
|
||||||
|
private static final String EXPLAIN_COMMAND = "EXPLAIN PLAN FOR";
|
||||||
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
||||||
SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE);
|
SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE,
|
||||||
|
EXPLAIN_COMMAND);
|
||||||
|
|
||||||
private final DatabaseConfig config;
|
private final DatabaseConfig config;
|
||||||
private final String url;
|
private final String url;
|
||||||
@@ -70,7 +72,7 @@ class HyperSqlDatabase extends JdbcDatabase {
|
|||||||
boolean reopen = isNonEmptyDirectory(dir);
|
boolean reopen = isNonEmptyDirectory(dir);
|
||||||
if (LOG.isLoggable(INFO)) LOG.info("Reopening DB: " + reopen);
|
if (LOG.isLoggable(INFO)) LOG.info("Reopening DB: " + reopen);
|
||||||
if (!reopen && dir.mkdirs()) LOG.info("Created database directory");
|
if (!reopen && dir.mkdirs()) LOG.info("Created database directory");
|
||||||
super.open("org.hsqldb.jdbc.JDBCDriver", reopen, key, listener);
|
super.open("org.hsqldb.jdbc.JDBCDriver", reopen, true, key, listener);
|
||||||
return reopen;
|
return reopen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -359,10 +359,84 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
+ " ON messages (cleanupDeadline)";
|
+ " ON messages (cleanupDeadline)";
|
||||||
|
|
||||||
// FIXME: Migration needs to add new index
|
// FIXME: Migration needs to add new index
|
||||||
private static final String INDEX_OUTGOING_KEYS_BY_TRANSPORT_ID_KEYSET_ID =
|
private static final String INDEX_OUTGOING_KEYS_BY_TRANSPORT_ID_KEY_SET_ID =
|
||||||
"CREATE INDEX IF NOT EXISTS outgoingKeysByTransportIdKeysetId"
|
"CREATE INDEX IF NOT EXISTS outgoingKeysByTransportIdKeySetId"
|
||||||
+ " ON outgoingKeys (transportId, keySetId)";
|
+ " ON outgoingKeys (transportId, keySetId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_CONTACTS_BY_LOCAL_AUTHOR_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS contactsByLocalAuthorId"
|
||||||
|
+ " ON contacts (localAuthorId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_GROUP_METADATA_BY_GROUP_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS groupMetadataByGroupId"
|
||||||
|
+ " ON groupMetadata (groupId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_GROUP_VISIBILITIES_BY_CONTACT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS groupVisibilitiesByContactId"
|
||||||
|
+ " ON groupVisibilities (contactId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_GROUP_VISIBILITIES_BY_GROUP_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS groupVisibilitiesByGroupId"
|
||||||
|
+ " ON groupVisibilities (groupId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_MESSAGES_BY_GROUP_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS messagesByGroupId"
|
||||||
|
+ " ON messages (groupId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_MESSAGE_METADATA_BY_MESSAGE_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS messageMetadataByMessageId"
|
||||||
|
+ " ON messageMetadata (messageId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_MESSAGE_METADATA_BY_GROUP_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS messageMetadataByGroupId"
|
||||||
|
+ " ON messageMetadata (groupId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_MESSAGE_DEPENDENCIES_BY_GROUP_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS messageDependenciesByGroupId"
|
||||||
|
+ " ON messageDependencies (groupId)";
|
||||||
|
|
||||||
|
private static final String
|
||||||
|
FOREIGN_INDEX_MESSAGE_DEPENDENCIES_BY_MESSAGE_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS messageDependenciesByMessageId"
|
||||||
|
+ " ON messageDependencies (messageId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_OFFERS_BY_CONTACT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS offersByContactId"
|
||||||
|
+ " ON offers (contactId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_STATUSES_BY_MESSAGE_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS statusesByMessageId"
|
||||||
|
+ " ON statuses (messageId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_STATUSES_BY_CONTACT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS statusesByContactId"
|
||||||
|
+ " ON statuses (contactId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_STATUSES_BY_GROUP_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS statusesByGroupId"
|
||||||
|
+ " ON statuses (groupId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_OUTGOING_KEYS_BY_TRANSPORT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS outgoingKeysByTransportId"
|
||||||
|
+ " ON outgoingKeys (transportId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_OUTGOING_KEYS_BY_CONTACT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS outgoingKeysByContactId"
|
||||||
|
+ " ON outgoingKeys (contactId)";
|
||||||
|
|
||||||
|
private static final String
|
||||||
|
FOREIGN_INDEX_OUTGOING_KEYS_BY_PENDING_CONTACT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS outgoingKeysByPendingContactId"
|
||||||
|
+ " ON outgoingKeys (pendingContactId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_INCOMING_KEYS_BY_TRANSPORT_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS incomingKeysByTransportId"
|
||||||
|
+ " ON incomingKeys (transportId)";
|
||||||
|
|
||||||
|
private static final String FOREIGN_INDEX_INCOMING_KEYS_BY_KEY_SET_ID =
|
||||||
|
"CREATE INDEX IF NOT EXISTS incomingKeysByKeySetId"
|
||||||
|
+ " ON incomingKeys (keySetId)";
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(JdbcDatabase.class.getName());
|
getLogger(JdbcDatabase.class.getName());
|
||||||
|
|
||||||
@@ -398,6 +472,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void open(String driverClass, boolean reopen,
|
protected void open(String driverClass, boolean reopen,
|
||||||
|
boolean createForeignKeyIndexes,
|
||||||
@SuppressWarnings("unused") SecretKey key,
|
@SuppressWarnings("unused") SecretKey key,
|
||||||
@Nullable MigrationListener listener) throws DbException {
|
@Nullable MigrationListener listener) throws DbException {
|
||||||
// Load the JDBC driver
|
// Load the JDBC driver
|
||||||
@@ -424,7 +499,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("db dirty? " + wasDirtyOnInitialisation);
|
LOG.info("db dirty? " + wasDirtyOnInitialisation);
|
||||||
}
|
}
|
||||||
createIndexes(txn);
|
createIndexes(txn, createForeignKeyIndexes);
|
||||||
setDirty(txn, true);
|
setDirty(txn, true);
|
||||||
commitTransaction(txn);
|
commitTransaction(txn);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
@@ -557,7 +632,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createIndexes(Connection txn) throws DbException {
|
private void createIndexes(Connection txn, boolean createForeignKeyIndexes)
|
||||||
|
throws DbException {
|
||||||
Statement s = null;
|
Statement s = null;
|
||||||
try {
|
try {
|
||||||
s = txn.createStatement();
|
s = txn.createStatement();
|
||||||
@@ -569,7 +645,31 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
s.executeUpdate(INDEX_STATUSES_BY_CONTACT_ID_TIMESTAMP);
|
s.executeUpdate(INDEX_STATUSES_BY_CONTACT_ID_TIMESTAMP);
|
||||||
s.executeUpdate(INDEX_STATUSES_BY_CONTACT_ID_TX_COUNT_TIMESTAMP);
|
s.executeUpdate(INDEX_STATUSES_BY_CONTACT_ID_TX_COUNT_TIMESTAMP);
|
||||||
s.executeUpdate(INDEX_MESSAGES_BY_CLEANUP_DEADLINE);
|
s.executeUpdate(INDEX_MESSAGES_BY_CLEANUP_DEADLINE);
|
||||||
s.executeUpdate(INDEX_OUTGOING_KEYS_BY_TRANSPORT_ID_KEYSET_ID);
|
s.executeUpdate(INDEX_OUTGOING_KEYS_BY_TRANSPORT_ID_KEY_SET_ID);
|
||||||
|
// Some DB implementations automatically create indexes on columns
|
||||||
|
// that are foreign keys, others don't
|
||||||
|
if (createForeignKeyIndexes) {
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_CONTACTS_BY_LOCAL_AUTHOR_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_GROUP_METADATA_BY_GROUP_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_GROUP_VISIBILITIES_BY_CONTACT_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_GROUP_VISIBILITIES_BY_GROUP_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_MESSAGES_BY_GROUP_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_MESSAGE_METADATA_BY_MESSAGE_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_MESSAGE_METADATA_BY_GROUP_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_MESSAGE_DEPENDENCIES_BY_GROUP_ID);
|
||||||
|
s.executeUpdate(
|
||||||
|
FOREIGN_INDEX_MESSAGE_DEPENDENCIES_BY_MESSAGE_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_OFFERS_BY_CONTACT_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_STATUSES_BY_MESSAGE_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_STATUSES_BY_CONTACT_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_STATUSES_BY_GROUP_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_OUTGOING_KEYS_BY_TRANSPORT_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_OUTGOING_KEYS_BY_CONTACT_ID);
|
||||||
|
s.executeUpdate(
|
||||||
|
FOREIGN_INDEX_OUTGOING_KEYS_BY_PENDING_CONTACT_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_INCOMING_KEYS_BY_TRANSPORT_ID);
|
||||||
|
s.executeUpdate(FOREIGN_INDEX_INCOMING_KEYS_BY_KEY_SET_ID);
|
||||||
|
}
|
||||||
s.close();
|
s.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s, LOG, WARNING);
|
tryToClose(s, LOG, WARNING);
|
||||||
@@ -1920,6 +2020,38 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> explainGetMessageIds(Connection txn, GroupId g)
|
||||||
|
throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = dbTypes.replaceTypes("_EXPLAIN SELECT messageId"
|
||||||
|
+ " FROM messages"
|
||||||
|
+ " WHERE groupId = ? AND state = ?");
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setBytes(1, g.getBytes());
|
||||||
|
ps.setInt(2, DELIVERED.getValue());
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
int cols = rs.getMetaData().getColumnCount();
|
||||||
|
List<String> explanation = new ArrayList<>();
|
||||||
|
while (rs.next()) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 1; i <= cols; i++) {
|
||||||
|
sb.append(rs.getString(i)).append(' ');
|
||||||
|
}
|
||||||
|
explanation.add(sb.toString());
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
return explanation;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(rs, LOG, WARNING);
|
||||||
|
tryToClose(ps, LOG, WARNING);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<MessageId> getMessageIds(Connection txn, GroupId g,
|
public Collection<MessageId> getMessageIds(Connection txn, GroupId g,
|
||||||
Metadata query) throws DbException {
|
Metadata query) throws DbException {
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ class SqliteDatabase extends JdbcDatabase {
|
|||||||
private static final String COUNTER_TYPE =
|
private static final String COUNTER_TYPE =
|
||||||
"INTEGER PRIMARY KEY AUTOINCREMENT";
|
"INTEGER PRIMARY KEY AUTOINCREMENT";
|
||||||
private static final String STRING_TYPE = "VARCHAR";
|
private static final String STRING_TYPE = "VARCHAR";
|
||||||
|
private static final String EXPLAIN_COMMAND = "EXPLAIN QUERY PLAN";
|
||||||
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
||||||
SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE);
|
SECRET_TYPE, BINARY_TYPE, COUNTER_TYPE, STRING_TYPE,
|
||||||
|
EXPLAIN_COMMAND);
|
||||||
|
|
||||||
private final DatabaseConfig config;
|
private final DatabaseConfig config;
|
||||||
private final String url;
|
private final String url;
|
||||||
@@ -71,7 +73,7 @@ class SqliteDatabase extends JdbcDatabase {
|
|||||||
boolean reopen = isNonEmptyDirectory(dir);
|
boolean reopen = isNonEmptyDirectory(dir);
|
||||||
if (LOG.isLoggable(INFO)) LOG.info("Reopening DB: " + reopen);
|
if (LOG.isLoggable(INFO)) LOG.info("Reopening DB: " + reopen);
|
||||||
if (!reopen && dir.mkdirs()) LOG.info("Created database directory");
|
if (!reopen && dir.mkdirs()) LOG.info("Created database directory");
|
||||||
super.open("org.sqlite.JDBC", reopen, key, listener);
|
super.open("org.sqlite.JDBC", reopen, true, key, listener);
|
||||||
return reopen;
|
return reopen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ public class HyperSqlDatabaseTest extends JdbcDatabaseTest {
|
|||||||
@Override
|
@Override
|
||||||
protected JdbcDatabase createDatabase(DatabaseConfig config,
|
protected JdbcDatabase createDatabase(DatabaseConfig config,
|
||||||
MessageFactory messageFactory, Clock clock) {
|
MessageFactory messageFactory, Clock clock) {
|
||||||
return new HyperSqlDatabase(config, messageFactory ,clock);
|
return new HyperSqlDatabase(config, messageFactory, clock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testExplainGetMessageIds() {
|
||||||
|
// Ugh, HSQLDB can't handle EXPLAIN PLAN FOR in prepared statements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2500,6 +2500,21 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
assertEquals(NO_CLEANUP_DEADLINE, db.getNextCleanupDeadline(txn));
|
assertEquals(NO_CLEANUP_DEADLINE, db.getNextCleanupDeadline(txn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Remove
|
||||||
|
@Test
|
||||||
|
public void testExplainGetMessageIds() throws Exception {
|
||||||
|
Database<Connection> db = open(false);
|
||||||
|
Connection txn = db.startTransaction();
|
||||||
|
db.addGroup(txn, group);
|
||||||
|
Collection<String> explanation = db.explainGetMessageIds(txn, groupId);
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
db.close();
|
||||||
|
|
||||||
|
System.out.println("getMessageIds(T, GroupId)");
|
||||||
|
for (String line : explanation) System.out.println(line);
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
private Database<Connection> open(boolean resume) throws Exception {
|
private Database<Connection> open(boolean resume) throws Exception {
|
||||||
return open(resume, new TestMessageFactory(), new SystemClock());
|
return open(resume, new TestMessageFactory(), new SystemClock());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user