Skip to main content

Database migrations

Storage backends

The plugin supports two database backends — SQLite (default, file-based) and MySQL. Both are accessed through the same Database / SQLDatabase classes in common/database/.

Every repository query must work on both backends. Differences in syntax (e.g. quoting, AUTO_INCREMENT vs AUTOINCREMENT, NOW() vs CURRENT_TIMESTAMP) must be handled in the repository.

Schema versioning

The schema version is tracked in the database_configuration table, in a row keyed on the configuration key schema_version.

SQLDatabase reads that value at startup, then sequentially applies every migration method whose source version matches the current schema version, until the schema matches the latest known version.

Adding a migration

A migration is a versioned method on common/database/SQLDatabase.java, named:

update_X_Y_Z_to_A_B_C()

Where:

  • X_Y_Z is the current schema version.
  • A_B_C is the target schema version (always one step ahead).

Steps:

  1. Pick A_B_C as the version your change ships in.
  2. Add the method on SQLDatabase. Inside, run the DDL statements that bring the schema from X_Y_Z to A_B_C. Make sure each statement works on both SQLite and MySQL.
  3. Register the call in SQLDatabase's migration chain so it runs after update_<previous>_to_X_Y_Z.
  4. At the end of the method, bump the row in database_configuration to A_B_C.

Backwards compatibility

Migrations only go forward — there is no automatic downgrade. A server admin who downgrades the plugin without restoring a database backup keeps a future-schema database, which the older plugin will probably reject at startup.

When introducing a destructive migration (drop column, change column type with data loss), call it out explicitly in CHANGELOG.md so admins back up first.