ownCloud migrations#27041
Conversation
85e2980 to
ef4213d
Compare
There was a problem hiding this comment.
upgradeSchema ? (unless you remove down)
There was a problem hiding this comment.
down is off the plate - only up - I'm open regarding the naming of this method
049f648 to
7a6792e
Compare
|
@DeepDiver1975 ready for review or still developing ? |
Unit testing is to be added - but generally speaking this is ready to be reviewed |
PVince81
left a comment
There was a problem hiding this comment.
Look good so far, see my comments for some point needing discussion.
From what I see there is a lot of complexity there so it's very important to have good unit tests here.
| $this->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on'); | ||
| $this | ||
| ->setName('migrations:execute') | ||
| ->setDescription('Execute a single migration version up or down manually.') |
There was a problem hiding this comment.
should we limit this to "up" for now to avoid false hopes from admins who might try "down" out ?
There was a problem hiding this comment.
copy paste issue - we only support up
| /** | ||
| * Auto-generated migration step: Please modify to your needs! | ||
| */ | ||
| class Version<version> implements ISqlMigration { |
There was a problem hiding this comment.
Three different migration types ? Is that really needed ? ("keep it simple")
What is the best practice for an app that needs to do Schema and non-Schema migrations (ex: moving stuff inside the data folder). To make it atomic in some way I think a dev would rather write a single generic migration that does all at once: SQL changes, data folder changes, etc all within the run() function.
What do you think ? (to be documented)
There was a problem hiding this comment.
So basically I see these three because of the different scenarios
- change the schema
- in some cases changing the schema is not enough - we need to explicitly apply sql statements
- last but not least: I want to allow us to basically write repair steps as migrations as well
There was a problem hiding this comment.
In this case a single type could be enough, and receive the SQL connection and the Schema injected in the run() method. This way it is possible to do all three within a single one.
Having interfaces for each type sounds a bit over-engineered. There is also the risk of people implementing all three interfaces on a single migration. Would everything still work fine ?
But maybe you had other good reasons in mind ?
There was a problem hiding this comment.
Doing all in run by the implementor of the step requires him/her to do all on his/her own.
Schema migration:
function run($connection) {
$fromSchema = $connection->createSchema();
// now do all the schema manipultation
try {
$connection->migrateToSchema($toSchema);
} catch ($ex){
}
}I want to take away this from the implementor - all which is to be implemented: changes to the schema - done.
Furthermore - the migration interfaces are designed to execute any operations after the method returns back to core - which allows us to gain more control over the execution.
This have been the ideas while designing these interfaces.
There was a problem hiding this comment.
Ok, fine by me.
I could imagine complex situations where it is not possible:
- do a DB update
- do a FS update
- do another DB update based on the FS changes
But for such complex changes one can simply use the generic runner.
There was a problem hiding this comment.
Well - do 3 steps which are executed one after the other
| $numNewMigrations = count(array_diff(array_keys($availableMigrations), $executedMigrations)); | ||
|
|
||
| $infos = [ | ||
| 'App' => $configuration->getApp(), |
| return addcslashes($param, '\\_%'); | ||
| } | ||
|
|
||
| public function createSchema() { |
There was a problem hiding this comment.
PHPDoc, especially considering the MDB2 part
There was a problem hiding this comment.
should be on interface level - will take care
| // set default table creation options | ||
| $connectionParams['defaultTableOptions'] = [ | ||
| 'collate' => 'utf8_bin', | ||
| 'tablePrefix' => $connectionParams['tablePrefix'] |
There was a problem hiding this comment.
Have we missed this all these years ? Could this save a bit of work from the custom query builder ?
There was a problem hiding this comment.
No idea - we shall have a look ...
| // read known migrations | ||
| $toBeExecuted = $migrationConfiguration->getMigrationsToExecute($to); | ||
| foreach ($toBeExecuted as $version => $class) { | ||
| $this->executeStep($migrationConfiguration, $version, $class); |
There was a problem hiding this comment.
how / where are exceptions handled in case an exception is thrown within a step ?
does PHPDoc need an additional @throws clause to clarify this ?
when you add unit tests please also make sure to cover exception handling/forwarding.
| $migrationConfiguration->setOutputWriter(new OutputWriter(function ($message){ | ||
| \OCP\Util::writeLog('migrations', $message, \OCP\Util::INFO); | ||
| })); | ||
| public function executeStep(MigrationConfiguration $migrationConfiguration, $version, $class = null) { |
| @@ -42,14 +42,10 @@ | |||
|
|
|||
| class Migrator { | |||
There was a problem hiding this comment.
Hmmm, what's a Migrator compared to MigrationService and MigrationConfiguration ? Add PHPDoc to clarify
There was a problem hiding this comment.
Migrator: old
MigrService and MigConfig: new
There was a problem hiding this comment.
the migrators are still used for anything which is xml related - I'd keep them for now
| use OCP\ILogger; | ||
| use OCP\Migration\IOutput; | ||
|
|
||
| class SimpleOutput implements IOutput { |
There was a problem hiding this comment.
What is this and why do we need this specifically for migrations ? Add answer in PHPDoc
| * Create the schema of the connected database | ||
| * | ||
| * @return Schema | ||
| * @since 10.0.0 |
There was a problem hiding this comment.
10.0
We don't add APIs in minor/patch versions
d7fd46f to
5623297
Compare
|
|
PVince81
left a comment
There was a problem hiding this comment.
A few more minor comments.
Else it looks good.
|
|
||
| } | ||
|
|
||
| private function generateMigration(MigrationService $ms, $version, $kind) { |
There was a problem hiding this comment.
I know it's a private function, but I miss PHPDoc to explain the format of $version and $kind which are not self-explanatory.
|
|
||
| $infos = $this->getMigrationsInfos($ms); | ||
| foreach ($infos as $key => $value) { | ||
| $output->writeln(" <comment>>></comment> $key: " . str_repeat(' ', 50 - strlen($key)) . $value); |
There was a problem hiding this comment.
uh, what's this weird string <comment>>></comment> ? Purpose ? Explain in a PHP comment
| } | ||
| } | ||
|
|
||
| public function getMigrationsInfos(MigrationService $ms) { |
There was a problem hiding this comment.
PHPDoc: @return array associative array of human readable info name as key and the actual information as value
|
|
||
| public function changeSchema(Schema $schema, array $options) { | ||
| $prefix = $options['tablePrefix']; | ||
| if (!$schema->hasTable("${prefix}external_mounts")) { |
There was a problem hiding this comment.
Do we still need the prefix ? I thought it was set on the connection already ?
There was a problem hiding this comment.
This is not possible at the moment because the schema class is disconnected to the connection.
The schema as generated from the database holds the prefix already - so when comparing we need to add it.
I'm not yet that happy about this - we might need to subclass Schema or introduce ISchema.
I will do this in a follow up PR - this PR is at it's limits
| /** | ||
| * @param Schema $schema | ||
| */ | ||
| public function down(Schema $schema) { |
| @@ -42,14 +42,10 @@ | |||
|
|
|||
| class Migrator { | |||
|
Please check my comments then 👍 |
|
Shall we kill ITransactionalStep for now? Just to keep it simpler? @PVince81 |
I'd say yes, let's remove it. In general my intuitive feeling when writing migrations was that the migration itself is always within a transaction. So every migration run would have its own transaction. And maybe the top level that runs all migrations also has a parent transaction. |
6544dbf to
5d74e42
Compare
Implement occ commands migrations:status, migrations:execute, migrations:generate and migrations:migrate
5d74e42 to
6c52ff9
Compare
|
🎉 |
|
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |

Description
Own migration mechanism - doctrine/migration cannot be used due to license issues
Types of changes
Checklist: