Skip to content

Commit

Permalink
Merge tag '2.3.0' into merge-2.3.0-into-3.0.x-
Browse files Browse the repository at this point in the history
- Total issues resolved: **0**
- Total pull requests resolved: **6**
- Total contributors: **6**

 - [1032: Let composer decide the best version](#1032) thanks to @PowerKiKi

 - [1020: Add badges into README about license and packagist](#1020) thanks to @matks
 - [999: Allow using on PHP 7.1 with Composer 2](#999) thanks to @nicolas-grekas

 - [981: Add "from-empty-schema" option for "diff" command](#981) thanks to @guilliamxavier
 - [954: Make compared tables order idempotent](#954) thanks to @julienfalque

 - [888: Use executeUpdate instead of executeQuery for write operation](#888) thanks to @goetas
  • Loading branch information
goetas committed Nov 22, 2020
2 parents d23d60b + 100e85a commit 3200233
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 9 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

[![Build Status](https://travis-ci.org/doctrine/migrations.svg)](https://travis-ci.org/doctrine/migrations)
[![Code Coverage](https://codecov.io/gh/doctrine/migrations/branch/master/graph/badge.svg)](https://codecov.io/gh/doctrine/migrations/branch/master)
[![Packagist Downloads](https://img.shields.io/packagist/dm/doctrine/migrations)](https://packagist.org/packages/doctrine/migrations)
[![Packagist Version](https://img.shields.io/packagist/v/doctrine/migrations)](https://packagist.org/packages/doctrine/migrations)
[![GitHub license](https://img.shields.io/github/license/doctrine/migrations)](https://github.com/doctrine/migrations/blob/master/LICENSE)

## Documentation

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"php": "^7.2",
"doctrine/dbal": "^2.10",
"doctrine/event-manager": "^1.0",
"ocramius/package-versions": "^1.3",
"composer/package-versions-deprecated": "^1.8",
"ocramius/proxy-manager": "^2.0.2",
"psr/log": "^1.1.3",
"symfony/console": "^3.4||^4.0||^5.0",
Expand Down
10 changes: 10 additions & 0 deletions docs/en/reference/generating-migrations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -266,4 +266,14 @@ If you use the DoctrineBundle with Symfony you can set the ``schema_filter`` opt
in your configuration. You can find more information in the documentation of the
DoctrineMigrationsBundle.

Merging Historical Migrations
-----------------------------

If you have many migrations, which were generated by successive runs of the ``diff`` command over time,
and you would like to replace them with one single migration, you can
delete (or archive) all your "historical" migration files and
run the ``diff`` command with the ``--from-empty-schema`` option.
It will generate a full migration as if your database was empty.
You can then use the ``rollup`` command to synchronize the version table of your (already up-to-date) database.

:ref:`Next Chapter: Custom Configuration <custom-configuration>`
2 changes: 1 addition & 1 deletion docs/en/reference/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Now to install with Composer it is as simple as running the following command in

.. code-block:: sh
composer require "doctrine/migrations:^2.0"
composer require "doctrine/migrations"
Now you will have a file in ``vendor/bin`` available to run the migrations console application:

Expand Down
19 changes: 16 additions & 3 deletions lib/Doctrine/Migrations/Generator/DiffGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,25 @@ class DiffGenerator
/** @var SqlGenerator */
private $migrationSqlGenerator;

/** @var SchemaProviderInterface */
private $emptySchemaProvider;

public function __construct(
DBALConfiguration $dbalConfiguration,
AbstractSchemaManager $schemaManager,
SchemaProvider $schemaProvider,
AbstractPlatform $platform,
Generator $migrationGenerator,
SqlGenerator $migrationSqlGenerator
SqlGenerator $migrationSqlGenerator,
SchemaProviderInterface $emptySchemaProvider
) {
$this->dbalConfiguration = $dbalConfiguration;
$this->schemaManager = $schemaManager;
$this->schemaProvider = $schemaProvider;
$this->platform = $platform;
$this->migrationGenerator = $migrationGenerator;
$this->migrationSqlGenerator = $migrationSqlGenerator;
$this->emptySchemaProvider = $emptySchemaProvider;
}

/**
Expand All @@ -65,7 +70,8 @@ public function generate(
?string $filterExpression,
bool $formatted = false,
int $lineLength = 120,
bool $checkDbPlatform = true
bool $checkDbPlatform = true,
bool $fromEmptySchema = false
) : string {
if ($filterExpression !== null) {
$this->dbalConfiguration->setSchemaAssetsFilter(
Expand All @@ -79,7 +85,9 @@ static function ($assetName) use ($filterExpression) {
);
}

$fromSchema = $this->createFromSchema();
$fromSchema = $fromEmptySchema
? $this->createEmptySchema()
: $this->createFromSchema();

$toSchema = $this->createToSchema();

Expand Down Expand Up @@ -108,6 +116,11 @@ static function ($assetName) use ($filterExpression) {
);
}

private function createEmptySchema() : Schema
{
return $this->emptySchemaProvider->createSchema();
}

private function createFromSchema() : Schema
{
return $this->schemaManager->createSchema();
Expand Down
30 changes: 30 additions & 0 deletions lib/Doctrine/Migrations/Provider/EmptySchemaProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Doctrine\Migrations\Provider;

use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Schema\Schema;

/**
* The EmptySchemaProvider class is responsible for creating a Doctrine\DBAL\Schema\Schema instance that
* represents the empty state of your database.
*
* @internal
*/
final class EmptySchemaProvider implements SchemaProviderInterface
{
/** @var AbstractSchemaManager */
private $schemaManager;

public function __construct(AbstractSchemaManager $schemaManager)
{
$this->schemaManager = $schemaManager;
}

public function createSchema() : Schema
{
return new Schema([], [], $this->schemaManager->createSchemaConfig());
}
}
39 changes: 36 additions & 3 deletions lib/Doctrine/Migrations/Tools/Console/Command/DiffCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
namespace Doctrine\Migrations\Tools\Console\Command;

use Doctrine\Migrations\Generator\Exception\NoChangesDetected;
use Doctrine\Migrations\Metadata\AvailableMigrationsList;
use Doctrine\Migrations\Metadata\ExecutedMigrationsList;
use Doctrine\Migrations\Provider\EmptySchemaProvider;
use Doctrine\Migrations\Provider\OrmSchemaProvider;
use Doctrine\Migrations\Provider\SchemaProviderInterface;
use Doctrine\Migrations\Tools\Console\Exception\InvalidOptionUsage;
use Doctrine\SqlFormatter\SqlFormatter;
use OutOfBoundsException;
Expand All @@ -32,6 +33,19 @@ final class DiffCommand extends DoctrineCommand
/** @var string */
protected static $defaultName = 'migrations:diff';

/** @var SchemaProviderInterface|null */
protected $schemaProvider;

/** @var EmptySchemaProvider|null */
private $emptySchemaProvider;

public function __construct(?SchemaProviderInterface $schemaProvider = null)
{
$this->schemaProvider = $schemaProvider;

parent::__construct();
}

protected function configure() : void
{
parent::configure();
Expand Down Expand Up @@ -83,6 +97,12 @@ protected function configure() : void
null,
InputOption::VALUE_NONE,
'Do not throw an exception when no changes are detected.'
)
->addOption(
'from-empty-schema',
null,
InputOption::VALUE_NONE,
'Generate a full migration as if the current database was empty.'
);
}

Expand All @@ -102,6 +122,7 @@ protected function execute(
$lineLength = (int) $input->getOption('line-length');
$allowEmptyDiff = $input->getOption('allow-empty-diff');
$checkDbPlatform = filter_var($input->getOption('check-database-platform'), FILTER_VALIDATE_BOOLEAN);
$fromEmptySchema = (bool) $input->getOption('from-empty-schema');
$namespace = $input->getOption('namespace');
if ($namespace === '') {
$namespace = null;
Expand Down Expand Up @@ -146,7 +167,8 @@ protected function execute(
$filterExpression,
$formatted,
$lineLength,
$checkDbPlatform
$checkDbPlatform,
$fromEmptySchema
);
} catch (NoChangesDetected $exception) {
if ($allowEmptyDiff) {
Expand Down Expand Up @@ -202,4 +224,15 @@ private function checkNewMigrationsOrExecutedUnavailable(

return $this->canExecute('Are you sure you wish to continue?', $input);
}

private function getEmptySchemaProvider() : EmptySchemaProvider
{
if ($this->emptySchemaProvider === null) {
$this->emptySchemaProvider = new EmptySchemaProvider(
$this->connection->getSchemaManager()
);
}

return $this->emptySchemaProvider;
}
}
67 changes: 66 additions & 1 deletion tests/Doctrine/Migrations/Tests/Generator/DiffGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class DiffGeneratorTest extends TestCase
/** @var DiffGenerator */
private $migrationDiffGenerator;

/** @var SchemaProviderInterface|MockObject */
private $emptySchemaProvider;

public function testGenerate() : void
{
$fromSchema = $this->createMock(Schema::class);
Expand Down Expand Up @@ -74,6 +77,9 @@ static function ($name) : bool {
->method('getTables')
->willReturn([$table1, $table2, $table3]);

$this->emptySchemaProvider->expects(self::never())
->method('createSchema');

$this->schemaManager->expects(self::once())
->method('createSchema')
->willReturn($fromSchema);
Expand Down Expand Up @@ -118,6 +124,63 @@ static function ($name) : bool {
self::assertSame('path', $this->migrationDiffGenerator->generate('1234', '/table_name1/', true, 80));
}

public function testGenerateFromEmptySchema() : void
{
$emptySchema = $this->createMock(Schema::class);
$toSchema = $this->createMock(Schema::class);

$this->dbalConfiguration->expects(self::never())
->method('setSchemaAssetsFilter');

$this->dbalConfiguration->expects(self::once())
->method('getSchemaAssetsFilter')
->willReturn(null);

$toSchema->expects(self::never())
->method('getTables');

$this->emptySchemaProvider->expects(self::once())
->method('createSchema')
->willReturn($emptySchema);

$this->schemaManager->expects(self::never())
->method('createSchema');

$this->schemaProvider->expects(self::once())
->method('createSchema')
->willReturn($toSchema);

$toSchema->expects(self::never())
->method('dropTable');

$emptySchema->expects(self::once())
->method('getMigrateToSql')
->with($toSchema, $this->platform)
->willReturn(['CREATE TABLE table_name']);

$emptySchema->expects(self::once())
->method('getMigrateFromSql')
->with($toSchema, $this->platform)
->willReturn(['DROP TABLE table_name']);

$this->migrationSqlGenerator->expects(self::at(0))
->method('generate')
->with(['CREATE TABLE table_name'], false, 120, true)
->willReturn('test up');

$this->migrationSqlGenerator->expects(self::at(1))
->method('generate')
->with(['DROP TABLE table_name'], false, 120, true)
->willReturn('test down');

$this->migrationGenerator->expects(self::once())
->method('generateMigration')
->with('2345', 'test up', 'test down')
->willReturn('path2');

self::assertSame('path2', $this->migrationDiffGenerator->generate('2345', null, false, 120, true, true));
}

protected function setUp() : void
{
$this->dbalConfiguration = $this->createMock(DBALConfiguration::class);
Expand All @@ -126,13 +189,15 @@ protected function setUp() : void
$this->platform = $this->createMock(AbstractPlatform::class);
$this->migrationGenerator = $this->createMock(Generator::class);
$this->migrationSqlGenerator = $this->createMock(SqlGenerator::class);
$this->emptySchemaProvider = $this->createMock(SchemaProviderInterface::class);
$this->migrationDiffGenerator = new DiffGenerator(
$this->dbalConfiguration,
$this->schemaManager,
$this->schemaProvider,
$this->platform,
$this->migrationGenerator,
$this->migrationSqlGenerator
$this->migrationSqlGenerator,
$this->emptySchemaProvider
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Doctrine\Migrations\Tests\Provider;

use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Schema\SchemaConfig;
use Doctrine\Migrations\Provider\EmptySchemaProvider;
use Doctrine\Migrations\Tests\MigrationTestCase;
use PHPUnit\Framework\MockObject\MockObject;

/**
* Tests the EmptySchemaProvider.
*/
class EmptySchemaProviderTest extends MigrationTestCase
{
/** @var AbstractSchemaManager|MockObject */
private $schemaManager;

/** @var EmptySchemaProvider */
private $emptyProvider;

public function testCreateSchema() : void
{
$schemaConfig = new SchemaConfig();
$schemaConfig->setExplicitForeignKeyIndexes(true);

$this->schemaManager->expects(self::once())
->method('createSchemaConfig')
->willReturn($schemaConfig);

$schema = $this->emptyProvider->createSchema();

self::assertSame([], $schema->getTables());
self::assertSame([], $schema->getSequences());
self::assertTrue($schema->hasExplicitForeignKeyIndexes());
self::assertSame([], $schema->getNamespaces());
}

protected function setUp() : void
{
$this->schemaManager = $this->createMock(AbstractSchemaManager::class);
$this->emptyProvider = new EmptySchemaProvider($this->schemaManager);
}
}

0 comments on commit 3200233

Please sign in to comment.