Browse Source

Move SchemaGenerator into SchemaLoader

Corey Taylor 4 years ago
parent
commit
dde4c620fe

+ 0 - 111
src/TestSuite/Fixture/SchemaGenerator.php

@@ -1,111 +0,0 @@
-<?php
-declare(strict_types=1);
-
-/**
- * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
- * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- *
- * Licensed under The MIT License
- * For full copyright and license information, please see the LICENSE.txt
- * Redistributions of files must retain the above copyright notice
- *
- * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- * @since         4.3.0
- * @license       https://opensource.org/licenses/mit-license.php MIT License
- */
-namespace Cake\TestSuite\Fixture;
-
-use Cake\Database\Connection;
-use Cake\Database\Schema\TableSchema;
-use Cake\Datasource\ConnectionManager;
-use RuntimeException;
-
-/**
- * Create database schema from the provided metadata file.
- *
- * This class is only intended for use by CakePHP's testsuite
- * as we need to test against many database platforms and can't
- * leverage migrations, or other dependencies to manage schema.
- *
- * @internal
- */
-class SchemaGenerator
-{
-    /**
-     * The metadata file to load.
-     *
-     * @var string
-     */
-    protected $file;
-
-    /**
-     * @var string
-     */
-    protected $connection;
-
-    /**
-     * Constructor
-     *
-     * @param string $file The file to load
-     * @param string $connection The connection to use.
-     * @return void
-     */
-    public function __construct(string $file, string $connection)
-    {
-        $this->file = $file;
-        $this->connection = $connection;
-
-        if (!file_exists($this->file)) {
-            throw new RuntimeException("Cannot load `{$this->file}`");
-        }
-    }
-
-    /**
-     * Reload the schema.
-     *
-     * Will drop all tables and re-create them from the metadata file.
-     *
-     * @param ?string[] $tables The list of tables to reset. Primarily for testing.
-     * @return void
-     */
-    public function reload(?array $tables = null): void
-    {
-        // Don't reload schema when we are in a separate process state.
-        if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) {
-            return;
-        }
-        $cleaner = new SchemaCleaner();
-        $cleaner->dropTables($this->connection, $tables);
-
-        $config = include $this->file;
-        $connection = ConnectionManager::get($this->connection);
-        if (!($connection instanceof Connection)) {
-            throw new RuntimeException("The `{$this->connection}` connection is not a Cake\Database\Connection");
-        }
-
-        if (!count($config)) {
-            return;
-        }
-
-        $connection->disableConstraints(function ($connection) use ($config) {
-            foreach ($config as $metadata) {
-                $table = new TableSchema($metadata['table'], $metadata['columns']);
-                if (isset($metadata['indexes'])) {
-                    foreach ($metadata['indexes'] as $key => $index) {
-                        $table->addIndex($key, $index);
-                    }
-                }
-                if (isset($metadata['constraints'])) {
-                    foreach ($metadata['constraints'] as $key => $index) {
-                        $table->addConstraint($key, $index);
-                    }
-                }
-                // Generate SQL for each table.
-                $stmts = $table->createSql($connection);
-                foreach ($stmts as $stmt) {
-                    $connection->execute($stmt);
-                }
-            }
-        });
-    }
-}

+ 56 - 7
src/TestSuite/Fixture/SchemaLoader.php

@@ -17,6 +17,7 @@ namespace Cake\TestSuite\Fixture;
 
 use Cake\Console\ConsoleIo;
 use Cake\Core\InstanceConfigTrait;
+use Cake\Database\Schema\TableSchema;
 use Cake\Datasource\ConnectionManager;
 use InvalidArgumentException;
 
@@ -41,11 +42,16 @@ class SchemaLoader
     protected $io;
 
     /**
+     * @var \Cake\TestSuite\Fixture\SchemaCleaner
+     */
+    protected $schemaCleaner;
+
+    /**
      * @var array<string, mixed>
      */
     protected $_defaultConfig = [
         'dropTables' => true,
-        'outputLevel' => ConsoleIo::NORMAL,
+        'outputLevel' => ConsoleIo::QUIET,
     ];
 
     /**
@@ -59,10 +65,12 @@ class SchemaLoader
 
         $this->io = new ConsoleIo();
         $this->io->level($this->getConfig('outputLevel'));
+
+        $this->schemaCleaner = new SchemaCleaner($this->io);
     }
 
     /**
-     * Import schema from a file, or an array of files.
+     * Load and apply schema sql file, or an array of files.
      *
      * @param array<string>|string $files Schema files to load
      * @param string $connectionName Connection name
@@ -70,7 +78,7 @@ class SchemaLoader
      * @param bool $truncateTables Truncate all tables after loading schema files
      * @return void
      */
-    public function loadFiles(
+    public function loadSqlFiles(
         $files,
         string $connectionName,
         bool $dropTables = true,
@@ -83,16 +91,15 @@ class SchemaLoader
             return;
         }
 
-        $cleaner = new SchemaCleaner($this->io);
         if ($dropTables) {
-            $cleaner->dropTables($connectionName);
+            $this->schemaCleaner->dropTables($connectionName);
         }
 
         /** @var \Cake\Database\Connection $connection */
         $connection = ConnectionManager::get($connectionName);
         foreach ($files as $file) {
             if (!file_exists($file)) {
-                throw new InvalidArgumentException("Unable to load schema file `$file`.");
+                throw new InvalidArgumentException("Unable to load SQL file `$file`.");
             }
             $sql = file_get_contents($file);
 
@@ -103,7 +110,49 @@ class SchemaLoader
         }
 
         if ($truncateTables) {
-            $cleaner->truncateTables($connectionName);
+            $this->schemaCleaner->truncateTables($connectionName);
         }
     }
+
+    /**
+     * Load and apply CakePHP-specific schema file.
+     *
+     * @param string $file Schema file
+     * @param string $connectionName Connection name
+     * @return void
+     * @internal
+     */
+    public function loadInternalFile(string $file, string $connectionName): void
+    {
+        // Don't reload schema when we are in a separate process state.
+        if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) {
+            return;
+        }
+
+        $this->schemaCleaner->dropTables($connectionName);
+
+        $tables = include $file;
+
+        $connection = ConnectionManager::get($connectionName);
+        $connection->disableConstraints(function ($connection) use ($tables) {
+            foreach ($tables as $table) {
+                $schema = new TableSchema($table['table'], $table['columns']);
+                if (isset($table['indexes'])) {
+                    foreach ($table['indexes'] as $key => $index) {
+                        $schema->addIndex($key, $index);
+                    }
+                }
+                if (isset($table['constraints'])) {
+                    foreach ($table['constraints'] as $key => $index) {
+                        $schema->addConstraint($key, $index);
+                    }
+                }
+
+                // Generate SQL for each table.
+                foreach ($schema->createSql($connection) as $sql) {
+                    $connection->execute($sql);
+                }
+            }
+        });
+    }
 }

+ 0 - 70
tests/TestCase/TestSuite/Fixture/SchemaGeneratorTest.php

@@ -1,70 +0,0 @@
-<?php
-declare(strict_types=1);
-
-/**
- * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
- * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- *
- * Licensed under The MIT License
- * For full copyright and license information, please see the LICENSE.txt
- * Redistributions of files must retain the above copyright notice
- *
- * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- * @since         4.3.0
- * @license       https://opensource.org/licenses/mit-license.php MIT License
- */
-namespace Cake\Test\TestCase\TestSuite\Fixture;
-
-use Cake\Datasource\ConnectionManager;
-use Cake\TestSuite\Fixture\SchemaGenerator;
-use Cake\TestSuite\TestCase;
-
-/**
- * SchemaGenerator Test
- */
-class SchemaGeneratorTest extends TestCase
-{
-    /**
-     * @var bool|null
-     */
-    protected $restore;
-
-    public function setUp(): void
-    {
-        parent::setUp();
-        $this->restore = $GLOBALS['__PHPUNIT_BOOTSTRAP'];
-        unset($GLOBALS['__PHPUNIT_BOOTSTRAP']);
-    }
-
-    public function tearDown(): void
-    {
-        parent::tearDown();
-        $GLOBALS['__PHPUNIT_BOOTSTRAP'] = $this->restore;
-    }
-
-    /**
-     * test reload on a table subset.
-     */
-    public function testReload(): void
-    {
-        $generator = new SchemaGenerator(__DIR__ . '/test_schema.php', 'test');
-
-        // only drop tables we'll create again.
-        $tables = ['schema_generator', 'schema_generator_comment'];
-        $generator->reload($tables);
-
-        $connection = ConnectionManager::get('test');
-        $schema = $connection->getSchemaCollection();
-
-        $result = $schema->listTables();
-        $this->assertContains('schema_generator', $result);
-        $this->assertContains('schema_generator_comment', $result);
-
-        foreach ($tables as $table) {
-            $meta = $schema->describe($table);
-            foreach ($meta->dropSql($connection) as $stmt) {
-                $connection->execute($stmt);
-            }
-        }
-    }
-}

+ 23 - 6
tests/TestCase/TestSuite/Fixture/SchemaLoaderTest.php

@@ -54,7 +54,7 @@ class SchemaLoaderTest extends TestCase
         $GLOBALS['__PHPUNIT_BOOTSTRAP'] = $this->restore;
 
         (new SchemaCleaner())->dropTables('test', ['schema_loader_test_one', 'schema_loader_test_two']);
-        ConnectionManager::drop('schema_test');
+        ConnectionManager::drop('test_schema_loader');
 
         if (file_exists($this->truncateDbFile)) {
             unlink($this->truncateDbFile);
@@ -64,14 +64,14 @@ class SchemaLoaderTest extends TestCase
     /**
      * Tests loading schema files.
      */
-    public function testLoadingFiles(): void
+    public function testLoadSqlFiles(): void
     {
         $connection = ConnectionManager::get('test');
 
         $schemaFiles[] = $this->createSchemaFile('schema_loader_test_one');
         $schemaFiles[] = $this->createSchemaFile('schema_loader_test_two');
 
-        $this->loader->loadFiles($schemaFiles, 'test', false, false);
+        $this->loader->loadSqlFiles($schemaFiles, 'test', false, false);
 
         $connection = ConnectionManager::get('test');
         $tables = $connection->getSchemaCollection()->listTables();
@@ -85,7 +85,7 @@ class SchemaLoaderTest extends TestCase
     public function testLoadMissingFile(): void
     {
         $this->expectException(InvalidArgumentException::class);
-        $this->loader->loadFiles('missing_schema_file.sql', 'test', false, false);
+        $this->loader->loadSqlFiles('missing_schema_file.sql', 'test', false, false);
     }
 
     /**
@@ -101,14 +101,14 @@ class SchemaLoaderTest extends TestCase
         ]);
 
         $schemaFile = $this->createSchemaFile('schema_loader_first');
-        $this->loader->loadFiles($schemaFile, 'test_schema_loader');
+        $this->loader->loadSqlFiles($schemaFile, 'test_schema_loader');
         $connection = ConnectionManager::get('test_schema_loader');
 
         $result = $connection->getSchemaCollection()->listTables();
         $this->assertEquals(['schema_loader_first'], $result);
 
         $schemaFile = $this->createSchemaFile('schema_loader_second');
-        $this->loader->loadFiles($schemaFile, 'test_schema_loader');
+        $this->loader->loadSqlFiles($schemaFile, 'test_schema_loader');
 
         $result = $connection->getSchemaCollection()->listTables();
         $this->assertEquals(['schema_loader_second'], $result);
@@ -118,6 +118,23 @@ class SchemaLoaderTest extends TestCase
         $this->assertCount(0, $result, 'Table should be empty.');
     }
 
+    public function testLoadInternalFiles(): void
+    {
+        $this->skipIf(!extension_loaded('pdo_sqlite'), 'Skipping as SQLite extension is missing');
+        ConnectionManager::setConfig('test_schema_loader', [
+            'className' => Connection::class,
+            'driver' => Sqlite::class,
+            'database' => $this->truncateDbFile,
+        ]);
+
+        $this->loader->loadInternalFile(__DIR__ . '/test_schema.php', 'test_schema_loader');
+
+        $connection = ConnectionManager::get('test_schema_loader');
+        $tables = $connection->getSchemaCollection()->listTables();
+        $this->assertContains('schema_generator', $tables);
+        $this->assertContains('schema_generator_comment', $tables);
+    }
+
     protected function createSchemaFile(string $tableName): string
     {
         $connection = ConnectionManager::get('test');

+ 3 - 3
tests/bootstrap.php

@@ -19,7 +19,7 @@ use Cake\Core\Configure;
 use Cake\Datasource\ConnectionManager;
 use Cake\Error\Debug\TextFormatter;
 use Cake\Log\Log;
-use Cake\TestSuite\Fixture\SchemaGenerator;
+use Cake\TestSuite\Fixture\SchemaLoader;
 use Cake\Utility\Security;
 
 if (is_file('vendor/autoload.php')) {
@@ -141,6 +141,6 @@ session_id('cli');
 
 // Create test database schema
 if (env('FIXTURE_SCHEMA_METADATA')) {
-    $schema = new SchemaGenerator(env('FIXTURE_SCHEMA_METADATA'), 'test');
-    $schema->reload();
+    $loader = new SchemaLoader();
+    $loader->loadInternalFile(env('FIXTURE_SCHEMA_METADATA'), 'test');
 }