Using DatabaseManager
The DatabaseManager class allows creation and control of one or more database instances on a PostgreSQL server.
By default, each PostgreSQL server has two databases:
- the
template1
template database from which all other databases are cloned - the
postgres
default database.
Additional databases can be created using the standard SQL CREATE DATABASE
commands.
DatabaseManager has two operation modes:
- In single database mode, only a single database exists (the
postgres
database). Every call toDatabaseManager.getDatabaseInfo()
returns a DatabaseInfo instance that can be used to connect to the single database. - In multi database mode, every call to
DatabaseManager.getDatabaseInfo()
creates a new database on the PostgreSQL server and returns a DatabaseInfo instance that decribes this new database. Each database has a unique name and is cloned from thetemplate1
database, so any operations on the template (creating tables, loading plugins etc.) are also applied to each new database instance.
Each DatabaseManager instance manages an EmbeddedPostgres instance to control the database server. Calling DatabaseManager.close()
shuts down the PostgreSQL server instance.
try (DatabaseManager manager = DatabaseManager.singleDatabase()
// same as EmbeddedPostgres.defaultInstance()
.withInstancePreparer(EmbeddedPostgres.Builder::withDefaults)
.build()
.start()) {
DatabaseInfo databaseInfo = manager.getDatabaseInfo();
try (Connection c = databaseInfo.asDataSource().getConnection();
Statement s = c.createStatement()) {
try (ResultSet rs = s.executeQuery("SELECT 1")) {
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertFalse(rs.next());
}
}
}
A DatabaseManager is created by calling either DatabaseManager.singleDatabase()
or DatabaseManager.multiDatabases()
. Each call returns a Builder which allows further customization of the PostgreSQL server and the databases. The builder creates the DatabaseManager instance by calling the Builder.build()
method.
Every DatabaseManager instance must be explicitly started by calling the start()
method.
Customizing the DatabaseManager
Customizing the EmbeddedPostgres instance
The Builder.withInstancePreparer()
and Builder.withInstancePreparers()
method allow the customization of the PostgreSQL server configuration. An instance preparer is executed once when the DatabaseManager is started and the EmbeddedPostgres.Builder that creates the EmbeddedPostgres instance is passed to it.
Either method accepts EmbeddedPostgresPreparer instances. See the EmbeddedPostgres documentation for details.
The Builder.withDefaults()
method on the EmbeddedPostgres.Builder can be used as a method reference by calling Builder.withInstancePreparer(EmbeddedPostgres.Builder::withDefaults)
to create a default configuratrion for the PostgreSQL server.
try (DatabaseManager manager = DatabaseManager.singleDatabase()
// set the default connection timeout for all DataSources
.withInstancePreparer(builder -> builder.addConnectionProperty("connectTimeout", "20"))
.build()
.start()) {
...
}
Customizing the Database instances
The Builder.withDatabasePreparer()
and Builder.withDatabasePreparers()
methods allow registration of Database customizations. A database preparer is executed once when the
DatabaseManager is started and a DataSource
instance connected to the default database will be passed to it. This DataSource
is either connected to the default database (in single database mode) or the template database from which all databases are cloned (in multi database mode).
Any DDL or data load operation will be visible in every database managed by the DatabaseManager. The most common use case is preparing the database for testing.
Either method accepts EmbeddedPostgresPreparer instances.
See Using Flyway for database customizations with the Flyway migration framework.