3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-14 19:25:51 +00:00

Add ability to optionally use a schema name in the Postgres block store.

Add a test to make sure things work when we set a schema name.
This commit is contained in:
Erik Tierney 2014-02-05 12:08:14 -05:00 committed by Mike Hearn
parent c95a864831
commit 59a18ab43f
2 changed files with 75 additions and 11 deletions

View File

@ -22,6 +22,7 @@ import com.google.common.collect.Lists;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -49,6 +50,7 @@ public class PostgresFullPrunedBlockStore implements FullPrunedBlockStore {
private int fullStoreDepth; private int fullStoreDepth;
private String username; private String username;
private String password; private String password;
private String schemaName;
private static final String driver = "org.postgresql.Driver"; private static final String driver = "org.postgresql.Driver";
private static final String CREATE_SETTINGS_TABLE = "CREATE TABLE settings (\n" + private static final String CREATE_SETTINGS_TABLE = "CREATE TABLE settings (\n" +
@ -107,24 +109,59 @@ public class PostgresFullPrunedBlockStore implements FullPrunedBlockStore {
*/ */
public PostgresFullPrunedBlockStore(NetworkParameters params, int fullStoreDepth, String hostname, String dbName, public PostgresFullPrunedBlockStore(NetworkParameters params, int fullStoreDepth, String hostname, String dbName,
String username, String password) throws BlockStoreException { String username, String password) throws BlockStoreException {
this(params, fullStoreDepth, "jdbc:postgresql://" + hostname + "/" + dbName, username, password); this(params, "jdbc:postgresql://" + hostname + "/" + dbName, fullStoreDepth, username, password, null);
} }
/** /**
* Creates a new PostgresFullPrunedBlockStore. * <p>Create a new PostgresFullPrunedBlockStore, storing the tables in the schema specified. You may want to
* specify a schema to avoid name collisions, or just to keep the database better organized. The schema is not
* required, and if one is not provided than the default schema for the username will be used. See
* <a href="http://www.postgres.org/docs/9.3/static/ddl-schemas.html">the postgres schema docs</a> for more on
* schemas.</p>
* *
* @param params A copy of the NetworkParameters used * @param params A copy of the NetworkParameters used.
* @param fullStoreDepth The number of blocks of history stored in full (something like 1000 is pretty safe) * @param fullStoreDepth The number of blocks of history stored in full (something like 1000 is pretty safe).
* @param connectionURL The jdbc url to connect to the database. * @param hostname The hostname of the database to connect to.
* @param username The database username * @param dbName The database to connect to.
* @param password The password to the database * @param username The database username.
* @throws BlockStoreException if the database fails to open for any reason * @param password The password to the database.
* @param schemaName The name of the schema to put the tables in. May be null if no schema is being used.
* @throws BlockStoreException If the database fails to open for any reason.
*/ */
public PostgresFullPrunedBlockStore(NetworkParameters params, int fullStoreDepth, String connectionURL, public PostgresFullPrunedBlockStore(NetworkParameters params, int fullStoreDepth, String hostname, String dbName,
String username, String password) throws BlockStoreException { String username, String password, @Nullable String schemaName) throws BlockStoreException {
this(params, "jdbc:postgresql://" + hostname + "/" + dbName, fullStoreDepth, username, password, schemaName);
}
/**
* <p>Create a new PostgresFullPrunedBlockStore, using the full connection URL instead of a hostname and password,
* and optionally allowing a schema to be specified.</p>
*
* <p>The connection URL will be passed to the database driver, and should look like
* "jdbc:postrgresql://host[:port]/databasename". You can use this to change the port, or specify additional
* parameters. See <a href="http://jdbc.postgresql.org/documentation/head/connect.html#connection-parameters">
* the PostgreSQL JDBC documentation</a> for more on the connection URL.</p>
*
* <p>This constructor also accepts a schema name to use, which can be used to avoid name collisions, or to keep the
* database organized. If no schema is provided the default schema for the username will be used. See
* <a href="http://www.postgres.org/docs/9.3/static/ddl-schemas.html">the postgres schema docs</a> for more on
* schemas.</p>
*
*
* @param params A copy of the NetworkParameters used.
* @param connectionURL The jdbc url to connect to the database.
* @param fullStoreDepth The number of blocks of history stored in full (something like 1000 is pretty safe).
* @param username The database username.
* @param password The password to the database.
* @param schemaName The name of the schema to put the tables in. May be null if no schema is being used.
* @throws BlockStoreException If the database fails to open for any reason.
*/
public PostgresFullPrunedBlockStore(NetworkParameters params, String connectionURL, int fullStoreDepth,
String username, String password, @Nullable String schemaName) throws BlockStoreException {
this.params = params; this.params = params;
this.fullStoreDepth = fullStoreDepth; this.fullStoreDepth = fullStoreDepth;
this.connectionURL = connectionURL; this.connectionURL = connectionURL;
this.schemaName = schemaName;
this.username = username; this.username = username;
this.password = password; this.password = password;
@ -165,6 +202,12 @@ public class PostgresFullPrunedBlockStore implements FullPrunedBlockStore {
conn.set(DriverManager.getConnection(connectionURL, props)); conn.set(DriverManager.getConnection(connectionURL, props));
Connection connection = conn.get(); Connection connection = conn.get();
// set the schema if one is needed
if(schemaName != null) {
Statement s = connection.createStatement();
s.execute("CREATE SCHEMA IF NOT EXISTS " + schemaName + ";");
s.execute("set search_path to '" + schemaName +"';");
}
allConnections.add(conn.get()); allConnections.add(conn.get());
log.info("Made a new connection to database " + connectionURL); log.info("Made a new connection to database " + connectionURL);
} catch (SQLException ex) { } catch (SQLException ex) {

View File

@ -4,6 +4,7 @@ import com.google.bitcoin.store.BlockStoreException;
import com.google.bitcoin.store.FullPrunedBlockStore; import com.google.bitcoin.store.FullPrunedBlockStore;
import com.google.bitcoin.store.PostgresFullPrunedBlockStore; import com.google.bitcoin.store.PostgresFullPrunedBlockStore;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test;
/** /**
* A Postgres implementation of the {@link AbstractFullPrunedBlockChainTest} * A Postgres implementation of the {@link AbstractFullPrunedBlockChainTest}
@ -16,15 +17,35 @@ public class PostgresFullPrunedBlockChainTest extends AbstractFullPrunedBlockCha
private static final String DB_NAME = "bitcoinj_test"; private static final String DB_NAME = "bitcoinj_test";
private static final String DB_USERNAME = "bitcoinj"; private static final String DB_USERNAME = "bitcoinj";
private static final String DB_PASSWORD = "password"; private static final String DB_PASSWORD = "password";
private static final String DB_SCHEMA = "blockstore_schema";
// whether to run the test with a schema name
private boolean useSchema = false;
@Override @Override
public FullPrunedBlockStore createStore(NetworkParameters params, int blockCount) public FullPrunedBlockStore createStore(NetworkParameters params, int blockCount)
throws BlockStoreException { throws BlockStoreException {
return new PostgresFullPrunedBlockStore(params, blockCount, DB_HOSTNAME, DB_NAME, DB_USERNAME, DB_PASSWORD); if(useSchema) {
return new PostgresFullPrunedBlockStore(params, blockCount, DB_HOSTNAME, DB_NAME, DB_USERNAME, DB_PASSWORD, DB_SCHEMA);
}
else {
return new PostgresFullPrunedBlockStore(params, blockCount, DB_HOSTNAME, DB_NAME, DB_USERNAME, DB_PASSWORD);
}
} }
@Override @Override
public void resetStore(FullPrunedBlockStore store) throws BlockStoreException { public void resetStore(FullPrunedBlockStore store) throws BlockStoreException {
((PostgresFullPrunedBlockStore)store).resetStore(); ((PostgresFullPrunedBlockStore)store).resetStore();
} }
@Test
public void testFirst100kBlocksWithCustomSchema() throws Exception {
boolean oldSchema = useSchema;
useSchema = true;
try {
super.testFirst100KBlocks();
} finally {
useSchema = oldSchema;
}
}
} }