kitloong / laravel-migrations-generator

Laravel Migrations Generator: Automatically generate your migrations from an existing database schema.
MIT License
2.44k stars 270 forks source link

Bug: Connection option doesn't work as expected #163

Closed calebdw closed 1 year ago

calebdw commented 1 year ago

Hello!

Describe the bug I have 3 different connections/databases in my application. When I try to use this package to create a squashed migration file for each of them using the --connection, I get 3 migration files all with the same tables from the default connection, but applied to the different connections with Schema::connection().

To Reproduce Steps to reproduce the behavior:

  1. Create two different database connections with different tables
  2. Run `php artisan migrate:generate --connection --path database/ --table-filename create__tables.php --skip-log --skip-views --skip-proc --squash --quiet',
  3. Run `php artisan migrate:generate --connection --path database/ --table-filename create__tables.php --skip-log --skip-views --skip-proc --squash --quiet',
  4. Connection 2 does not contain the tables in connection 2, but rather those in connection 1 that are applied to connection 2.

Expected behavior I expect --connection <connection_2> to create a migration file for the tables in connection 2.

Screenshots N/A

Details (please complete the following information):

Additional context Add any other context about the problem here.

calebdw commented 1 year ago

Update

I found that the --connection options does work as expected when running the command manually through Artisan. However, I'm trying to loop over the connections in code, and every migration file has the same content as the first connection....maybe it has something to do with the --squash option and the temporary files?

calebdw commented 1 year ago

I think I found the reason---all of the schema managers are being registered as singletons:

        foreach (
            [
                Setting::class           => Setting::class,
                MySQLRepository::class   => MySQLRepository::class,
                MySQLSchema::class       => DBALMySQLSchema::class,
                PgSQLRepository::class   => PgSQLRepository::class,
                PgSQLSchema::class       => DBALPgSQLSchema::class,
                SQLiteRepository::class  => SQLiteRepository::class,
                SQLiteSchema::class      => DBALSQLiteSchema::class,
                SQLSrvRepository::class  => SQLSrvRepository::class,
                SQLSrvSchema::class      => DBALSQLSrvSchema::class,
                MariaDBRepository::class => MariaDBRepository::class,
            ] as $abstract => $concrete
        ) {
            $this->app->singleton($abstract, $concrete);
        }
kitloong commented 1 year ago

Hi @CalebDW Thank you for reporting.

Instead, the --connection works fine for me, with --squash.

I'm trying to loop over the connections in code

I am not fully clear with your usage here, perhaps you could provide some code examples? And how is the singleton broke your code?

Thanks for you providing more info.

calebdw commented 1 year ago

I'm trying to use this package to create table migrations for Larastan to read (because it doesn't do great at reading Postgres dumps). The code is as follows:

        collect(config('database.connections'))
            ->mapWithKeys(fn ($item, $key) => [$key => $item['database']])
            ->sortBy(fn ($database) => $database === config('database.default'))
            ->each(function ($database, $connection) {
                $task = "Creating Larastan migration for database [{$database}] on connection [{$connection}]";

                $this->components->info($task);

                $this->call('migrate:generate', [
                    '--connection'     => $connection,
                    '--path'           => 'larastan/migrations',
                    '--table-filename' => "create_{$connection}_tables.php",
                    '--skip-log'       => true,
                    '--skip-proc'      => true,
                    '--skip-views'     => true,
                    '--squash'         => true,
                ]);

                App::forgetInstance(PgSQLSchema::class);
            });

I was able to solve the issue on my end by forgetting the singleton, but I think it would be good to update it on your end to not be a singleton.

kitloong commented 1 year ago

Thank you @CalebDW

calebdw commented 1 year ago

Awesome, no thank you!