Interface DatabaseMigrator
- All Known Implementing Classes:
BaseDatabaseMigrator
This method of migration means that not all schemas are represented by a database on disk. For example, if the only database on disk is schema 0 and the current schema is 3, then the database will be copied, tagged as schema 3 and upgraded. There will not be a copy of schema 1 or 2 on disk.
This interface allows for purging old schemas. Since every migration makes another copy of the database, this interface uses the retention schema to determine what versions of the database are safe to delete.
Database Migration
The database migration process ensures that the database schema matches what the code expects. This is executed every time the application starts. During this phase, the migrator does one of the following:- The database file does not exist, so the migrator creates it from scratch.
- The code's schema version is newer than the database's, so the migrator updates the database.
- The code's schema version is older than the database's, so the migrator rolls back to a previous version.
- The code's schema version matches the database's schema version, so all is good: no action is taken.
Downgrading the database to an older version is also called "rolling back" or "rollback".
Example
In the following example, the schema #0 code creates a table named "options", while the schema #1 code renames an existing field and adds a new field.
public class OurDatabaseMigrator implements DatabaseMigrator {
private Jdbi jdbi;
@Override
public int getCurrentSchema() {
return 1;
}
@Override
public void setJdbi(Jdbi jdbi) {
this.jdbi = jdbi;
}
@Override
public void migrateToSchema(Jdbi jdbi, int schema) {
switch (schema) {
// Initial schema version #0:
case 0 -> jdbi.useHandle(handle -> {
// Create the "options" table:
handle.execute("""
CREATE TABLE options(
[name] TEXT NOT NULL,
[value] TEXT,
PRIMARY KEY([name]))""");
});
// Current schema version #1:
case 1 -> jdbi.useHandle(handle -> {
// Change column name from [value] to [currentValue]:
handle.execute("""
ALTER TABLE options
RENAME COLUMN [value] TO [currentValue]""");
// Add column [defaultValue]:
handle.execute("""
ALTER TABLE options
ADD COLUMN [defaultValue] TEXT""");
});
default -> throw new ConfigException(
String.format("Invalid schema version [%s] encountered", schema));
}
}
}
- Since:
- 1.0
- Version:
- 2022-08-30
-
Method Summary
Modifier and TypeMethodDescriptionint
Returns the current schema version.default int
Returns the minimum schema version to use for migration.default int
Returns the minimum schema version to keep on disk after migration.default void
migrateToSchema
(DataSource datasource, int schema) Applies any changes to the database for the specified schema number.void
migrateToSchema
(Jdbi jdbi, int schema) Applies any changes to the database for the specified schema number.default boolean
Returnstrue
if any schema versions newer than the current version should be deleted from disk.default void
setDataSource
(DataSource datasource) Sets the finalDataSource
to use after migration is complete.default void
Sets the finalJdbi
instance to use after migration is complete.
-
Method Details
-
getCurrentSchema
int getCurrentSchema()Returns the current schema version. The migration process migrates to this version during startup. Must be a non-negative integer that starts with zero, then increments by one each time the schema is updated.Example
- Database schema versions 4, 6, and 7 exist on the disk.
- You set the desired schema by having this method return the number 9.
- After migration, the database with schema #9 exists on the disk, however a database with schema #8 does not exist.
- Returns:
- the current schema version
-
getMinimumMigrationSchema
default int getMinimumMigrationSchema()Returns the minimum schema version to use for migration. Any existing database with this version or higher can be used for migration. Anything below this version will be ignored, causing migration to create a clean schema with no data.Example
- Database schema versions 0, 1, and 2 exist on the disk.
- You set the minimum migration schema by having this method return the number 4.
- No database migration takes place because all existing schemas are less than 4.
- After migration, the database with schema 4 exists, but it contains no data.
- Returns:
- the minimum schema to migrate
-
getMinimumRetentionSchema
default int getMinimumRetentionSchema()Returns the minimum schema version to keep on disk after migration. Any database with a schema older than this will be deleted from disk.Example
- Database schema versions 0, 1, 2, 4, 6, and 7 exist on the disk.
- You migrate to the newest schema, version #8.
- This method in your custom data source migrator returns the number 4.
- After migration, databases with schemas 0, 1, and 2 have been deleted, leaving databases 4, 6, 7, and 8 on the disk.
- Returns:
- minimum retention schema
-
purgeNewerSchema
default boolean purgeNewerSchema()Returnstrue
if any schema versions newer than the current version should be deleted from disk. In the event of a rollback, this will cause the newer data to be deleted, so when rolling forward the data will be migrated again.Example 1 (purge newer)
- Database schema versions 0, 1, 2, 4, 6, and 7 exist on the disk.
- You want newer schemas deleted, so you have this method return
true
. - You migrate/rollback to an older schema, version #6.
- After migration, the database with schema #7 has been deleted, and the active database schema is #6.
Example 2 (keep newer)
- Database schema versions 0, 1, 2, 4, 6, and 7 exist on the disk.
- You do not want newer schemas deleted, so you have this method return
false
. - You migrate/rollback to an older schema, version #6.
- After migration, the database with schema #7 still exists, even though the active database schema is #6.
- Returns:
true
to purge newer schemas on rollback, orfalse
to keep
-
migrateToSchema
Applies any changes to the database for the specified schema number. This is called for every schema version from the current database schema plus 1 to the current schema. For example, if the current database is at schema 2 and the current schema is 4, then this will be called with a schema of 3 and then 4. TheDataSource
provided may be temporary and should only be used for migration. When migration is complete, a call tosetDataSource()
will be made with the finalDataSource
.By default this simply calls the
JDBI
version of this call. Override this to use theDataSource
directly instead ofJDBI
.- Parameters:
datasource
- the datasource to the database to migrateschema
- the schema version to apply
-
migrateToSchema
Applies any changes to the database for the specified schema number. This is called for every schema version from the current database schema plus 1 to the current schema. For example, if the current database is at schema 2 and the current schema is 4, then this will be called with a schema of 3 and then 4. TheJdbi
provided may be temporary and should only be used for migration. When migration is complete, a call tosetJdbi()
will be made with the finalJdbi
instance.- Parameters:
jdbi
-Jdbi
wrapper for the datasource to use for migrationschema
- the schema version to apply
-
setDataSource
Sets the finalDataSource
to use after migration is complete. Override to gain access to the underlyingDataSource
instead of theJdbi
instance. -
setJdbi
Sets the finalJdbi
instance to use after migration is complete. Override to gain access to the final Jdbi instance if the migrator is also the DAO object.
-