Search code examples
phpcodeigniter-4

Codeigniter 4 - How to run one specific migration file?


I have a project with multiple migration files, according to different modules of the project. I want to pass a key (associative array) and run all the files on that index.

//EXAMPLE

$files = [
    'blog' => [
        //array of file names
    ],
    'storage' => [
        //array of file names
    ],
    'sales' => [
        //array of file names
    ],
]

runAll($files['sales'])

I've read the docs but it just allow specified class name in terminal.

Edit: Just checked again and it either allow class name but namespace on migrate command.


Solution

  • You can migrate a single file regardless of order or batches using the method force(string $path, string $namespace, ?string $group = null) available within the MigrationRunner class.

    force($path, $namespace, $group)

    This forces a single file to migrate regardless of order or batches. Method “up” or “down” is detected based on whether it has already been migrated.

    Note:

    This method is recommended only for testing and could cause data consistency issues.

    So in your case, you would just run a for loop through the files as you pass the expected parameters in the force(...) method. I.e:

    Assuming the array keys of your $files array represent the various 'modules' of the project:

    $migrate = \Config\Services::migrations();
    $psr4 = config(\Config\Autoload::class)->psr4;
    
    foreach ($files as $module => $filenames) {
    
        $namespace = "Modules\\" . ucwords($module);
    
        foreach ($filenames as $filename) {
            try {
                $migrate->force($psr4[$namespace] . "\\" . $filename, $namespace);
            } catch (\Throwable $e) {
                // Do something with the error here...
            }
        }
    }
    

    NOTES:

    The above solution assumes that you already mapped your $psr4 namespaces in your application modules to their respective locations on the file system: I.e:

    File: app/Config/Autoload.php

    // ...
    
        public $psr4 = [
            APP_NAMESPACE => APPPATH, // For custom app namespace
            'Config' => APPPATH . 'Config',
            'Modules\Blog' => ROOTPATH . 'module/blog',
            'Modules\Storage' => ROOTPATH . 'module/storage',
            'Modules\Sales' => ROOTPATH . 'module/sales',
        ];
    
    // ...