Database migrations are a way to keep database schemas in sync on all your environments/servers (local, production, stage, etc.).
Migration files can also be stored in git, so you always have a sync between your code and databases.
All migration operations are done via the migrations.php script. You can check out the available arguments using this command: php migrations.php help.
Configuring the database migration system
By default, data regarding applied migrations are stored in a plain text file, ideally you would want to store these in a database.
To implement your custom migration config, start by making a new class and implement the Dominus\System\Interfaces\MigrationsStorage interface.
<?phpuseDominus\Services\Database\Database;useDominus\System\Interfaces\MigrationsStorage;classMyCustomMigrationsConfigimplementsMigrationsStorage{privateDatabase$db;privatearray$appliedMigrations=[];/** * @throws Exception */publicfunction__construct(){$this->db=Database::getConnection('MIGRATIONS');}// In this example we will use a postgresql database/** * @throws Exception */publicfunctioninit():void{$db=$this->db;$migrationsTableExists=$db->query("SELECT EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'db_migrations' )")->fetchColumn();if(!$migrationsTableExists){$db->query(' CREATE TABLE public.db_migrations ( migration_id text PRIMARY KEY ) ');}else{$this->appliedMigrations=$db->query('SELECT migration_id FROM public.db_migrations')->fetchAllFromColumn();}}publicfunctionisApplied(string$migrationId):bool{returnin_array($migrationId,$this->appliedMigrations);}publicfunctiondatabaseUpgraded(string$migrationId):void{if(!in_array($migrationId,$this->appliedMigrations)){$this->appliedMigrations[]=$migrationId;}}publicfunctiondatabaseDowngraded(string$migrationId):void{foreach($this->appliedMigrationsas$idx=>$migration){if($migration==$migrationId){unset($this->appliedMigrations[$idx]);break;}}}publicfunctionstoreMigrations():void{$db=$this->db;$db->query('TRUNCATE TABLE public.db_migrations');$db->query('INSERT INTO public.db_migrations (migration_id) VALUES '.implode(',',array_map(staticfunction(string$migrationId){return"($migrationId)";},$this->appliedMigrations)));}}
After you have your configuration class, in your startup.php file, make a new static function public static function getMigrationsStorage(): MigrationsStorage that we will use to override the default migrations storage and return our custom storage.
<?phpclassAppConfigurationextendsDominusConfiguration{.../** * This function will return our custom migrations storage configuration * @return DefaultMigrationsConfig */publicstaticfunctiongetMigrationsStorage():MigrationsStorage{returnnewMyCustomMigrationsConfig();}}
Creating a new migration file
You can create models using the Dominus CLI using the generate migration command. It will automatically use the namespace of the current Module and create an empty migration file.
You can also use the migrations.php file in the Dominus project root(next to index.php) like so: php my_project/migrations.php add MyModuleDirName.
<?phpclassTest1700333087extendsMigration{/** * A list of Modules on which this migration depends on. Example return ['MyModule']; * An empty array should be returned if this migration has no dependencies; * @return string[] */publicfunctiongetDependencies():array{return[];}/** * Apply the migration * @return void */publicfunctionup(){}/** * Revert the migration * @return void */publicfunctiondown(){}}
Upgrading the database
You can upgrade all your modules(that have database migrations) by doing: php migrations.php up
If using containers, you can have this command placed in your start script so that your container database is always up-to-date with the code.
Downgrading the database
You can downgrade by calling the migrations.php with the down argument and pass the migration ID (The filename without its extension, e.g. Test1700333087.php -> Test1700333087).