LazyRecord\Migration\MigrationGenerator::generateWithDiff PHP Метод

generateWithDiff() публичный Метод

public generateWithDiff ( $taskName, $dataSourceId, array $schemas, $time = null )
$schemas array
    public function generateWithDiff($taskName, $dataSourceId, array $schemas, $time = null)
    {
        $connectionManager = \LazyRecord\ConnectionManager::getInstance();
        $connection = $connectionManager->getConnection($dataSourceId);
        $driver = $connectionManager->getQueryDriver($dataSourceId);
        $parser = TableParser::create($connection, $driver);
        $tableSchemas = $schemas;
        $existingTables = $parser->getTables();
        $this->logger->info('Found ' . count($schemas) . ' schemas to compare.');
        $template = $this->createClassTemplate($taskName, $time);
        $upgradeMethod = $template->addMethod('public', 'upgrade', array(), '');
        $downgradeMethod = $template->addMethod('public', 'downgrade', array(), '');
        $comparator = new Comparator($driver);
        // schema from runtime
        foreach ($tableSchemas as $key => $a) {
            $table = is_numeric($key) ? $a->getTable() : $key;
            if (!in_array($table, $existingTables)) {
                $this->logger->info(sprintf("Found schema '%s' to be imported to '%s'", $a, $table), 1);
                // generate create table statement.
                // use sqlbuilder to build schema sql
                $upcall = new MethodCallExpr('$this', 'importSchema', [new Raw('new ' . get_class($a))]);
                $upgradeMethod->getBlock()->appendLine(new Statement($upcall));
                $downcall = new MethodCallExpr('$this', 'dropTable', [$table]);
                $downgradeMethod->getBlock()->appendLine(new Statement($downcall));
                continue;
            }
            // revsersed schema
            $b = $parser->reverseTableSchema($table, $a);
            $diffs = $comparator->compare($b, $a);
            if (empty($diffs)) {
                continue;
            }
            // generate alter table statement.
            foreach ($diffs as $diff) {
                switch ($diff->flag) {
                    case 'A':
                        $alterTable = new AlterTableQuery($table);
                        $alterTable->addColumn($diff->getAfterColumn());
                        $this->appendQueryStatement($upgradeMethod, $driver, $alterTable, new ArgumentArray());
                        $alterTable = new AlterTableQuery($table);
                        $alterTable->dropColumn($diff->getAfterColumn());
                        $this->appendQueryStatement($downgradeMethod, $driver, $alterTable, new ArgumentArray());
                        break;
                    case 'M':
                        $alterTable = new AlterTableQuery($table);
                        $after = $diff->getAfterColumn();
                        $before = $diff->getBeforeColumn();
                        if (!$after || !$before) {
                            throw new LogicException('afterColumn or beforeColumn is undefined.');
                        }
                        // Check primary key
                        if ($before->primary != $after->primary) {
                            // primary key requires another sub-statement "ADD PRIMARY KEY .."
                            $alterTable->add()->primaryKey([$after->name]);
                        }
                        $alterTable->modifyColumn($after);
                        $this->appendQueryStatement($upgradeMethod, $driver, $alterTable, new ArgumentArray());
                        $alterTable = new AlterTableQuery($table);
                        $alterTable->modifyColumn($before);
                        $this->appendQueryStatement($downgradeMethod, $driver, $alterTable, new ArgumentArray());
                        break;
                    case 'D':
                        $alterTable = new AlterTableQuery($table);
                        $alterTable->dropColumnByName($diff->name);
                        $this->appendQueryStatement($upgradeMethod, $driver, $alterTable, new ArgumentArray());
                        $alterTable = new AlterTableQuery($table);
                        $alterTable->addColumn($diff->getBeforeColumn());
                        $this->appendQueryStatement($downgradeMethod, $driver, $alterTable, new ArgumentArray());
                        break;
                    default:
                        $this->logger->warn('** unsupported flag.');
                        continue;
                }
            }
        }
        $filename = $this->generateFilename($taskName, $time);
        $path = $this->migrationDir . DIRECTORY_SEPARATOR . $filename;
        if (false === file_put_contents($path, $template->render())) {
            throw new RuntimeException("Can't write migration script to {$path}.");
        }
        return array($template->class->name, $path);
    }

Usage Example

 public function testMigrationByDiff()
 {
     $this->conn->query('DROP TABLE IF EXISTS users');
     $this->conn->query('DROP TABLE IF EXISTS test');
     $this->conn->query('CREATE TABLE users (account VARCHAR(128) UNIQUE)');
     if (!file_exists('tests/migrations_testing')) {
         mkdir('tests/migrations_testing');
     }
     $generator = new MigrationGenerator(Console::getInstance()->getLogger(), 'tests/migrations_testing');
     ok(class_exists('TestApp\\Model\\UserSchema', true));
     $finder = new SchemaFinder();
     $finder->find();
     list($class, $path) = $generator->generateWithDiff('DiffMigration', $this->getDriverType(), ["users" => new TestApp\Model\UserSchema()], '20120101');
     require_once $path;
     ok($class::getId());
     /*
     $userSchema = new TestApp\Model\UserSchema;
     $column = $userSchema->getColumn('account');
     */
     // run migration
     $runner = new MigrationRunner($this->logger, $this->getDriverType());
     $runner->resetMigrationId($this->conn, $this->queryDriver);
     $runner->load('tests/migrations_testing');
     // XXX: PHPUnit can't run this test in separated unit test since
     // there is a bug of serializing the global array, this assertion will get 5 instead of the expected 1.
     $scripts = $runner->loadMigrationScripts();
     $this->assertNotEmpty($scripts);
     // $this->assertCount(1, $scripts);
     // $this->expectOutputRegex('#DiffMigration_1325347200#');
     $runner->runUpgrade($this->conn, $this->queryDriver, [$class]);
     # echo file_get_contents($path);
     unlink($path);
     $this->conn->query('DROP TABLE IF EXISTS users');
 }
All Usage Examples Of LazyRecord\Migration\MigrationGenerator::generateWithDiff