Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow multiple migration directories and namespaces #856

Closed
wants to merge 1 commit into from

Conversation

goetas
Copy link
Member

@goetas goetas commented Sep 7, 2019

Q A
Type feature
BC Break yes/no
Fixed issues #853

Summary

This is a WIP pr for #853, is allows to define multiple paths (and namespaces) for migrations.

The generation and reporting are not yet implemented, I'm publishing the PR as work-in-progress to get early feedback.

@goetas
Copy link
Member Author

goetas commented Sep 11, 2019

The difficould part of this PR is that version contains only the "version" number, but when migrations will have multiple namespaces, version number might clash...

@alcaeus
Copy link
Member

alcaeus commented Sep 11, 2019

The difficould part of this PR is that version contains only the "version" number, but when migrations will have multiple namespaces, version number might clash...

That is correct. I believe that the version number no longer needs to be unique, but it must be unique within the migration namespace. Would you agree?

@goetas
Copy link
Member Author

goetas commented Sep 11, 2019

That is correct. I believe that the version number no longer needs to be unique, but it must be unique within the migration namespace. Would you agree?

I agree, but would this kind of change considered a BC break? Or the getVersion() is something "internal" not covered but BC promise?

I would like to know this because if is a BC break then I would choose a different approach and target it to a possible 3.0...

@goetas
Copy link
Member Author

goetas commented Sep 11, 2019

Another question: the "version" is used to decide with entry store in the migrations table, if we change that behavior, then the "migrations_table" will need to be migrated to a new format...

And this can be an even bigger headache even for 3.0

@alcaeus
Copy link
Member

alcaeus commented Sep 11, 2019

Yes, that is always going to be a headache. I was already thinking about this when looking at #852: technically, it's an easy change, but changing the migrations table makes it very expensive and dangerous to do so. It would be nice if we could introduce migrations for the migrations table itself, but it's not easy to build.

@jwage any idea here? Did we already have situations where we changed the migration table structure?

@goetas
Copy link
Member Author

goetas commented Sep 11, 2019

If we are going in direction to fix some of this issues in 3.0, would be nice to have some feedback on #857 (@jwage ?)

I plan to be able to allocate some time to work on this...

@alcaeus
Copy link
Member

alcaeus commented Sep 11, 2019

If we are going in direction to fix some of this issues in 3.0, would be nice to have some feedback on #857 (@jwage ?)

Absolutely.

I plan to be able to allocate some time to work on this...

That is awesome, thank you very much! ❤️
I don't have much time to take care of the migrations library, but I'll try to keep feedback coming. Feel free to ping me in Slack if I miss some GitHub notifications!

@goetas
Copy link
Member Author

goetas commented Sep 11, 2019

@alcaeus I remember that 1-3 years ago @jwage @beberlei worked on a 2.0 migrations PR #162 that was also considering getting rid of thew down() migration direction. But than that got discarded in what become the current 2.0... Is there some "written" reason on that decision? I'm a firm believer that was a good idea...

Edit: after reading a bit seems it just got lost in discussions...

@alcaeus
Copy link
Member

alcaeus commented Sep 11, 2019

Not that I know of - 2.0 was mainly the work of @jwage. I'm not very involved in this one.

Copy link
Member

@lcobucci lcobucci left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a great first step... It's quite nice that you manage to provide a BC layer but if we decide to target v3.0 maybe we can be a bit braver and simplify things even further (like using namespaces and relying on composer autoloader).

Here are some thoughts/comments (just a braindump really), thanks for pushing this further 👍

@@ -49,6 +49,9 @@ class Configuration
/** @var string */
private $migrationsExecutedAtColumnName = 'executed_at';

/** @var string[][] */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to be more explicit about the keys here (since we're relying on it), so array<string, array<string, string>>.

I'm just wondering why do we need to set the path as both key and value (especially when only using the value). Simplifying that we could represent it as array<string, string[]>.

@@ -49,6 +49,9 @@ class Configuration
/** @var string */
private $migrationsExecutedAtColumnName = 'executed_at';

/** @var string[][] */
private $migrationsDirectories = [];

/** @var string|null */
private $migrationsDirectory;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest dropping $migrationsDirectory and $migrationsNamespace entirely. That simplifies getMigrationDirectories(), getMigrationsDirectory(), and getMigrationsNamespace()

The method setMigrationsDirectory() would do the logic $this->migrationsDirectories[$this->getMigrationsNamespace() ?? ''] = [$this->migrationsDirectory => $this->migrationsDirectory]; (we could also use int keys as mentioned before to simplify things).

setMigrationsNamespace() would be slightly more complicated to potentially transferring the configuration of the directory settings for the namespace.

return;
}

$this->registerMigrationsFromDirectory($migrationsDirectory);
foreach ($migrationDirectories as $namespace => $paths) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that exposes the internals of Configuration a bit too much, maybe we can provide a method there to encapsulate things in a better way. Like:

class Configuration
{
    /**
     * @return iterable<array<string|null>>
     */
    public function iterateMigrationDirectories() : iterable
    {
        foreach ($this->migrationsDirectories as $namespace => $paths) {
            foreach ($paths as $path) {
                yield [$path, $namespace ?: null];
            }
        }
    }
}

Then we could do this here:

foreach ($this->configuration->iterateMigrationDirectories() as $directoryConfiguration) {
    $this->registerMigrations(
        $this->migrationFinder->findMigrations(...$directoryConfiguration)
    );
}

We would also be able to drop count($migrationDirectories) === 0 too since we would have an empty iterator when nothing is configured.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Configuration#getMigrationDirectories() is only used by this method we can simply no create it too 😄

@@ -103,6 +106,19 @@ public function __construct(
$this->migrationsColumnLength = strlen($this->createDateTime()->format(self::VERSION_FORMAT));
}

public function addMigrationsPath(string $path, ?string $namespace = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest always requiring the namespace.

@goetas
Copy link
Member Author

goetas commented Sep 15, 2019

Moving development to #858

@lcobucci Thanks for the review. I have addressed most of your suggestions and started a bigger set of changes in the mentioned PR

@goetas goetas closed this Sep 15, 2019
@goetas goetas added this to the 3.0.0 milestone Mar 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants