Because Flarum supports optional extension dependencies, there is a use case for optional database migrations that should only be applied if another extension is installed/enabled.
In particular, this allows achieving:
- Add column to a table created by the optional dependency extension
- Create pivot tables and foreign keys for tables created by optional dependencies
This cannot be achieved with regular migrations because there's a need for the migration to be attempted again every time an extension is enabled. And an extension cannot delete itself from the MigrationRepository (migrations table) from within the migration since that record is only updated after the migration returns successfully.
My proposal is to add a when callback key to migration arrays. When running up migrations, the when key would run first. If it exists and returns a falsy value, up is skipped and no migration is written to the MigrationRepository. On down migrations, everything would always run and the down migration can simply become a no-op if it cannot find the columns/tables that it needs to delete.
I have implemented this proposal as part of flamarkt/backoffice. The migrator changes can be found in https://github.com/flamarkt/backoffice/blob/main/src/Database/AugmentedMigrator.php while an example usage can be found in flamarkt/taxonomies https://github.com/flamarkt/taxonomies/blob/main/migrations/20210401_000400_create_product_term_table.php
A different implementation could be to use a special exception that the up migration could throw to cause the migration to be skipped without stopping the migrator.
Supporting down migration so that they run when the dependency is uninstalled without running all of the extension's down migrations is probably way too complex and I see a lot less use case for that (would only be useful when changing existing columns that must be reverted)
Are there other use cases of implementation concerns I might not have thought of?