Skip to content

Commit

Permalink
Merge pull request #1150 from doctrine/less-metadata-queries
Browse files Browse the repository at this point in the history
cache some metadata state to avoid querying all the time the database…
  • Loading branch information
goetas committed Apr 24, 2021
2 parents 96c64fa + af63b46 commit 1c2780d
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
20 changes: 20 additions & 0 deletions lib/Doctrine/Migrations/Metadata/Storage/TableMetadataStorage.php
Expand Up @@ -37,6 +37,12 @@

final class TableMetadataStorage implements MetadataStorage
{
/** @var bool */
private $isInitialized;

/** @var bool */
private $schemaUpToDate = false;

/** @var Connection */
private $connection;

Expand Down Expand Up @@ -152,22 +158,32 @@ public function ensureInitialized(): void
if (! $this->isInitialized()) {
$expectedSchemaChangelog = $this->getExpectedTable();
$this->schemaManager->createTable($expectedSchemaChangelog);
$this->schemaUpToDate = true;
$this->isInitialized = true;

return;
}

$this->isInitialized = true;
$expectedSchemaChangelog = $this->getExpectedTable();
$diff = $this->needsUpdate($expectedSchemaChangelog);
if ($diff === null) {
$this->schemaUpToDate = true;

return;
}

$this->schemaUpToDate = true;
$this->schemaManager->alterTable($diff);
$this->updateMigratedVersionsFromV1orV2toV3();
}

private function needsUpdate(Table $expectedTable): ?TableDiff
{
if ($this->schemaUpToDate) {
return null;
}

$comparator = new Comparator();
$currentTable = $this->schemaManager->listTableDetails($this->configuration->getTableName());
$diff = $comparator->diffTable($currentTable, $expectedTable);
Expand All @@ -177,6 +193,10 @@ private function needsUpdate(Table $expectedTable): ?TableDiff

private function isInitialized(): bool
{
if ($this->isInitialized) {
return $this->isInitialized;
}

if ($this->connection instanceof PrimaryReadReplicaConnection) {
$this->connection->connect('master');
}
Expand Down
Expand Up @@ -6,9 +6,11 @@

use DateTime;
use DateTimeImmutable;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\PDO\SQLite\Driver as SQLiteDriver;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Logging\DebugStack;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\DateTimeType;
Expand All @@ -31,6 +33,9 @@ class TableMetadataStorageTest extends TestCase
/** @var Connection */
private $connection;

/** @var Configuration */
private $connectionConfig;

/** @var TableMetadataStorage */
private $storage;

Expand All @@ -40,22 +45,38 @@ class TableMetadataStorageTest extends TestCase
/** @var AbstractSchemaManager */
private $schemaManager;

private function getSqliteConnection(): Connection
private function getSqliteConnection(?Configuration $configuration = null): Connection
{
$params = ['driver' => 'pdo_sqlite', 'memory' => true];

return DriverManager::getConnection($params);
return DriverManager::getConnection($params, $configuration);
}

public function setUp(): void
{
$this->connection = $this->getSqliteConnection();
$this->schemaManager = $this->connection->getSchemaManager();
$this->connectionConfig = new Configuration();
$this->connection = $this->getSqliteConnection($this->connectionConfig);
$this->schemaManager = $this->connection->getSchemaManager();

$this->config = new TableMetadataStorageConfiguration();
$this->storage = new TableMetadataStorage($this->connection, new AlphabeticalComparator(), $this->config);
}

public function testSchemaIntrospectionExecutedOnlyOnce(): void
{
$stack = new DebugStack();
$this->connectionConfig->setSQLLogger($stack);
$this->storage->ensureInitialized();

$oldQueryCount = $stack->currentQuery;
$this->storage->ensureInitialized();
self::assertSame(0, $stack->currentQuery - $oldQueryCount);

$oldQueryCount = $stack->currentQuery;
$this->storage->getExecutedMigrations();
self::assertSame(1, $stack->currentQuery - $oldQueryCount);
}

public function testDifferentTableNotUpdatedOnRead(): void
{
$this->expectException(MetadataStorageError::class);
Expand Down
Expand Up @@ -309,6 +309,14 @@ public function testExecuteMigrate(): void
public function testExecuteMigrateUpdatesMigrationsTableWhenNeeded(): void
{
$this->alterMetadataTable();
// replace the old storage instance since it has cached the metadata state and we have altered it with alterMetadataTable() above
$this->storage = new TableMetadataStorage(
$this->connection,
new AlphabeticalComparator(),
$this->metadataConfiguration,
$this->migrationRepository
);
$this->dependencyFactory->setService(MetadataStorage::class, $this->storage);

$this->migrateCommandTester->execute([], ['interactive' => false]);

Expand Down

0 comments on commit 1c2780d

Please sign in to comment.