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

Squash core migrations #2842

Merged
merged 4 commits into from
May 10, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
367 changes: 367 additions & 0 deletions migrations/install.dump

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/Console/ConsoleServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public function register()
ResetCommand::class,
ScheduleListCommand::class,
ScheduleRunCommand::class
// Used internally to create DB dumps before major releases.
// \Flarum\Database\Console\GenerateDumpCommand::class
Copy link
Member

Choose a reason for hiding this comment

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

Do we really need to put this command inside of the source code?

We likely won't need it before a while, and it might end up broken without us even realizing it in the meantime.

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

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

Which is why I commented it out. I wanted to keep it so that we could debug how the dump was created if we run into issues with it.

Copy link
Member

Choose a reason for hiding this comment

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

I just don't really like the idea of having that code lying around unused for 1,2,5 years? in the repo. I feel like it would be best inside of an issue, or a dedicated branch so we can find it again later but don't ship it / maintain it as part of the whole 1.x release cycle.

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

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

I wanted to put it in the Flarum CLI, but didn't have time to rewrite it so that it worked for this.

];
});

Expand Down
87 changes: 87 additions & 0 deletions src/Database/Console/GenerateDumpCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/

namespace Flarum\Database\Console;

use Flarum\Console\AbstractCommand;
use Flarum\Foundation\Paths;
use Illuminate\Database\Connection;

class GenerateDumpCommand extends AbstractCommand
{
/**
* @var Connection
*/
protected $connection;

/**
* @var Paths
*/
protected $paths;

/**
* @param Connection $connection
* @param Paths $paths
*/
public function __construct(Connection $connection, Paths $paths)
{
$this->connection = $connection;
$this->paths = $paths;

parent::__construct();
}

/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('schema:dump')
->setDescription('Dump DB schema');
}

/**
* {@inheritdoc}
*/
protected function fire()
{
$dumpPath = __DIR__.'/../../../migrations/install.dump';
/** @var Connection */
askvortsov1 marked this conversation as resolved.
Show resolved Hide resolved
$connection = resolve('db.connection');

$connection
->getSchemaState()
->withMigrationTable($connection->getTablePrefix().'migrations')
->handleOutputUsing(function ($type, $buffer) {
$this->output->write($buffer);
})
->dump($connection, $dumpPath);

// We need to remove any data migrations, as those won't be captured
// in the schema dump, and must be run separately.
$coreDataMigrations = [
'2018_07_21_000000_seed_default_groups',
'2018_07_21_000100_seed_default_group_permissions',
];

$newDump = [];
$dump = file($dumpPath);
foreach ($dump as $line) {
foreach ($coreDataMigrations as $excludeMigrationId) {
if (strpos($line, $excludeMigrationId) !== false) {
continue 2;
}
}
$newDump[] = $line;
}

file_put_contents($dumpPath, implode($newDump));
}
}
16 changes: 0 additions & 16 deletions src/Database/DatabaseMigrationRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,6 @@ public function delete($file, $extension = null)
$query->delete();
}

/**
* Create the migration repository data store.
*
* @return void
*/
public function createRepository()
{
$schema = $this->connection->getSchemaBuilder();

$schema->create($this->table, function ($table) {
$table->increments('id');
$table->string('migration');
$table->string('extension')->nullable();
});
}

/**
* Determine if the migration repository exists.
*
Expand Down
7 changes: 0 additions & 7 deletions src/Database/MigrationRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@ public function log($file, $extension = null);
*/
public function delete($file, $extension = null);

/**
* Create the migration repository data store.
*
* @return void
*/
public function createRepository();

/**
* Determine if the migration repository exists.
*
Expand Down
68 changes: 48 additions & 20 deletions src/Database/Migrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
use Exception;
use Flarum\Extension\Extension;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Database\MySqlConnection;
use Illuminate\Database\Schema\Builder;
use Illuminate\Database\Schema\SchemaState;
use Illuminate\Filesystem\Filesystem;
use InvalidArgumentException;
use Symfony\Component\Console\Output\OutputInterface;

class Migrator
Expand All @@ -39,6 +42,18 @@ class Migrator
*/
protected $schemaBuilder;

/**
* The DB table prefix.
*/
protected $tablePrefix;

/**
* The database schema builder instance.
*
* @var SchemaState
*/
protected $schemaState;

/**
* The output interface implementation.
*
Expand All @@ -61,7 +76,13 @@ public function __construct(
$this->files = $files;
$this->repository = $repository;

if (! ($connection instanceof MySqlConnection)) {
throw new InvalidArgumentException('Only MySQL connections are supported');
}

$this->tablePrefix = $connection->getTablePrefix();
$this->schemaBuilder = $connection->getSchemaBuilder();
$this->schemaState = $connection->getSchemaState();

// Workaround for https://github.com/laravel/framework/issues/1186
$connection->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
Expand Down Expand Up @@ -242,6 +263,33 @@ public function resolve($path, $file)
}
}

/**
* Initialize the Flarum database from a schema dump.
*
* @param string $path to the directory containing the dump.
*/
public function installFromSchema(string $path)
{
$schemaPath = "$path/install.dump";
$prefixedSchemaPath = "$path/install_prefixed.dump.tmp";
askvortsov1 marked this conversation as resolved.
Show resolved Hide resolved

$currDumpFile = file_get_contents($schemaPath);

file_put_contents($prefixedSchemaPath, str_replace('db_prefix_', $this->tablePrefix, $currDumpFile));

$this->note('<info>Loading stored database schema:</info>');
$startTime = microtime(true);

$this->schemaState->handleOutputUsing(function ($type, $buffer) {
$this->output->write($buffer);
})->load($prefixedSchemaPath);

$runTime = number_format((microtime(true) - $startTime) * 1000, 2);
$this->note('<info>Loaded stored database schema.</info> ('.$runTime.'ms)');

unlink($prefixedSchemaPath);
}

/**
* Set the output implementation that should be used by the console.
*
Expand All @@ -268,16 +316,6 @@ protected function note($message)
}
}

/**
* Get the migration repository instance.
*
* @return MigrationRepositoryInterface
*/
public function getRepository()
{
return $this->repository;
}

/**
* Determine if the migration repository exists.
*
Expand All @@ -287,14 +325,4 @@ public function repositoryExists()
{
return $this->repository->repositoryExists();
}

/**
* Get the file system instance.
*
* @return \Illuminate\Filesystem\Filesystem
*/
public function getFilesystem()
{
return $this->files;
}
}
2 changes: 1 addition & 1 deletion src/Install/Steps/RunMigrations.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function run()
{
$migrator = $this->getMigrator();

$migrator->getRepository()->createRepository();
$migrator->installFromSchema($this->path);
$migrator->run($this->path);
}

Expand Down