Beispiel #1
0
 /**
  * Dumps a single Schema model into an XML formatted version.
  *
  * @param  Schema  $schema                The schema object
  * @param  boolean $doFinalInitialization Whether or not to validate the schema
  * @return string
  */
 public function dumpSchema(Schema $schema, $doFinalInitialization = true)
 {
     $rootNode = $this->document->createElement('app-data');
     $this->document->appendChild($rootNode);
     foreach ($schema->getDatabases($doFinalInitialization) as $database) {
         $this->appendDatabaseNode($database, $rootNode);
     }
     return trim($this->document->saveXML());
 }
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $configOptions = [];
     if ($this->hasInputOption('connection', $input)) {
         foreach ($input->getOption('connection') as $conn) {
             $configOptions += $this->connectionToProperties($conn);
         }
     }
     if ($this->hasInputOption('migration-table', $input)) {
         $configOptions['propel']['migrations']['tableName'] = $input->getOption('migration-table');
     }
     if ($this->hasInputOption('schema-dir', $input)) {
         $configOptions['propel']['paths']['schemaDir'] = $input->getOption('schema-dir');
     }
     if ($this->hasInputOption('output-dir', $input)) {
         $configOptions['propel']['paths']['migrationDir'] = $input->getOption('output-dir');
     }
     $generatorConfig = $this->getGeneratorConfig($configOptions, $input);
     $this->createDirectory($generatorConfig->getSection('paths')['migrationDir']);
     $manager = new MigrationManager();
     $manager->setGeneratorConfig($generatorConfig);
     $manager->setSchemas($this->getSchemas($generatorConfig->getSection('paths')['schemaDir'], $input->getOption('recursive')));
     $connections = [];
     $optionConnections = $input->getOption('connection');
     if (!$optionConnections) {
         $connections = $generatorConfig->getBuildConnections();
     } else {
         foreach ($optionConnections as $connection) {
             list($name, $dsn, $infos) = $this->parseConnection($connection);
             $connections[$name] = array_merge(['dsn' => $dsn], $infos);
         }
     }
     $manager->setConnections($connections);
     $manager->setMigrationTable($generatorConfig->getConfigProperty('migrations.tableName'));
     $manager->setWorkingDirectory($generatorConfig->getSection('paths')['migrationDir']);
     if ($manager->hasPendingMigrations()) {
         throw new RuntimeException('Uncommitted migrations have been found ; you should either execute or delete them before rerunning the \'diff\' task');
     }
     $totalNbTables = 0;
     $reversedSchema = new Schema();
     foreach ($manager->getDatabases() as $appDatabase) {
         $name = $appDatabase->getName();
         if (!($params = @$connections[$name])) {
             $output->writeln(sprintf('<info>No connection configured for database "%s"</info>', $name));
         }
         if ($input->getOption('verbose')) {
             $output->writeln(sprintf('Connecting to database "%s" using DSN "%s"', $name, $params['dsn']));
         }
         $conn = $manager->getAdapterConnection($name);
         $platform = $generatorConfig->getConfiguredPlatform($conn, $name);
         if (!$platform->supportsMigrations()) {
             $output->writeln(sprintf('Skipping database "%s" since vendor "%s" does not support migrations', $name, $platform->getDatabaseType()));
             continue;
         }
         $additionalTables = [];
         foreach ($appDatabase->getTables() as $table) {
             if ($table->getSchema() && $table->getSchema() != $appDatabase->getSchema()) {
                 $additionalTables[] = $table;
             }
         }
         if ($input->getOption('disable-identifier-quoting')) {
             $platform->setIdentifierQuoting(false);
         }
         $database = new Database($name);
         $database->setPlatform($platform);
         $database->setSchema($appDatabase->getSchema());
         $database->setDefaultIdMethod(IdMethod::NATIVE);
         $parser = $generatorConfig->getConfiguredSchemaParser($conn, $name);
         $nbTables = $parser->parse($database, $additionalTables);
         $reversedSchema->addDatabase($database);
         $totalNbTables += $nbTables;
         if ($input->getOption('verbose')) {
             $output->writeln(sprintf('%d tables found in database "%s"', $nbTables, $name), Output::VERBOSITY_VERBOSE);
         }
     }
     if ($totalNbTables) {
         $output->writeln(sprintf('%d tables found in all databases.', $totalNbTables));
     } else {
         $output->writeln('No table found in all databases');
     }
     // comparing models
     $output->writeln('Comparing models...');
     $tableRenaming = $input->getOption('table-renaming');
     $migrationsUp = [];
     $migrationsDown = [];
     $removeTable = !$input->getOption('skip-removed-table');
     $excludedTables = $input->getOption('skip-tables');
     foreach ($reversedSchema->getDatabases() as $database) {
         $name = $database->getName();
         if ($input->getOption('verbose')) {
             $output->writeln(sprintf('Comparing database "%s"', $name));
         }
         if (!($appDataDatabase = $manager->getDatabase($name))) {
             $output->writeln(sprintf('<error>Database "%s" does not exist in schema.xml. Skipped.</error>', $name));
             continue;
         }
         $configManager = new ConfigurationManager();
         $excludedTables = array_merge((array) $excludedTables, (array) $configManager->getSection('exclude_tables'));
         $databaseDiff = DatabaseComparator::computeDiff($database, $appDataDatabase, false, $tableRenaming, $removeTable, $excludedTables);
         if (!$databaseDiff) {
             if ($input->getOption('verbose')) {
                 $output->writeln(sprintf('Same XML and database structures for datasource "%s" - no diff to generate', $name));
             }
             continue;
         }
         $output->writeln(sprintf('Structure of database was modified in datasource "%s": %s', $name, $databaseDiff->getDescription()));
         foreach ($databaseDiff->getPossibleRenamedTables() as $fromTableName => $toTableName) {
             $output->writeln(sprintf('<info>Possible table renaming detected: "%s" to "%s". It will be deleted and recreated. Use --table-renaming to only rename it.</info>', $fromTableName, $toTableName));
         }
         $conn = $manager->getAdapterConnection($name);
         $platform = $generatorConfig->getConfiguredPlatform($conn, $name);
         if ($input->getOption('disable-identifier-quoting')) {
             $platform->setIdentifierQuoting(false);
         }
         $migrationsUp[$name] = $platform->getModifyDatabaseDDL($databaseDiff);
         $migrationsDown[$name] = $platform->getModifyDatabaseDDL($databaseDiff->getReverseDiff());
     }
     if (!$migrationsUp) {
         $output->writeln('Same XML and database structures for all datasource - no diff to generate');
         return;
     }
     $timestamp = time();
     $migrationFileName = $manager->getMigrationFileName($timestamp);
     $migrationClassBody = $manager->getMigrationClassBody($migrationsUp, $migrationsDown, $timestamp, $input->getOption('comment'));
     $file = $generatorConfig->getSection('paths')['migrationDir'] . DIRECTORY_SEPARATOR . $migrationFileName;
     file_put_contents($file, $migrationClassBody);
     $output->writeln(sprintf('"%s" file successfully created.', $file));
     if (null !== ($editorCmd = $input->getOption('editor'))) {
         $output->writeln(sprintf('Using "%s" as text editor', $editorCmd));
         shell_exec($editorCmd . ' ' . escapeshellarg($file));
     } else {
         $output->writeln('Please review the generated SQL statements, and add data migration code if necessary.');
         $output->writeln('Once the migration class is valid, call the "migrate" task to execute it.');
     }
 }
Beispiel #3
0
 /** Sets up the Propel model. */
 public function setUp()
 {
     $schema = new Schema(new MysqlPlatform());
     $this->database = new Database();
     $schema->addDatabase($this->database);
 }
Beispiel #4
0
 /**
  * Returns the GeneratorConfigInterface object.
  *
  * @return GeneratorConfigInterface
  */
 public function getGeneratorConfig()
 {
     if ($this->parentSchema) {
         return $this->parentSchema->getGeneratorConfig();
     }
 }
 public function testSetGeneratorConfig()
 {
     $config = $this->getMock('Propel\\Generator\\Config\\GeneratorConfig');
     $schema = new Schema();
     $schema->setGeneratorConfig($config);
     $this->assertSame($config, $schema->getGeneratorConfig());
 }
Beispiel #6
0
 public function startElement($parser, $name, $attributes)
 {
     $parentTag = $this->peekCurrentSchemaTag();
     if (false === $parentTag) {
         switch ($name) {
             case 'database':
                 if ($this->isExternalSchema()) {
                     $this->currentPackage = isset($attributes['package']) ? $attributes['package'] : null;
                     if (null === $this->currentPackage) {
                         $this->currentPackage = $this->defaultPackage;
                     }
                 } else {
                     $this->currDB = $this->schema->addDatabase($attributes);
                 }
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('database' === $parentTag) {
         switch ($name) {
             case 'external-schema':
                 $xmlFile = isset($attributes['filename']) ? $attributes['filename'] : null;
                 // 'referenceOnly' attribute is valid in the main schema XML file only,
                 // and it's ignored in the nested external-schemas
                 if (!$this->isExternalSchema()) {
                     $isForRefOnly = isset($attributes['referenceOnly']) ? $attributes['referenceOnly'] : null;
                     $this->isForReferenceOnly = null !== $isForRefOnly ? 'true' === strtolower($isForRefOnly) : true;
                     // defaults to TRUE
                 }
                 if ('/' !== $xmlFile[0]) {
                     $xmlFile = realpath(dirname($this->currentXmlFile) . DIRECTORY_SEPARATOR . $xmlFile);
                     if (!file_exists($xmlFile)) {
                         throw new SchemaException(sprintf('Unknown include external "%s"', $xmlFile));
                     }
                 }
                 $this->parseFile($xmlFile);
                 break;
             case 'domain':
                 $this->currDB->addDomain($attributes);
                 break;
             case 'table':
                 if (!isset($attributes['schema']) && $this->currDB->getSchema() && $this->currDB->getPlatform()->supportsSchemas() && false === strpos($attributes['name'], $this->currDB->getPlatform()->getSchemaDelimiter())) {
                     $attributes['schema'] = $this->currDB->getSchema();
                 }
                 $this->currTable = $this->currDB->addTable($attributes);
                 if ($this->isExternalSchema()) {
                     $this->currTable->setForReferenceOnly($this->isForReferenceOnly);
                     $this->currTable->setPackage($this->currentPackage);
                 }
                 break;
             case 'vendor':
                 $this->currVendorObject = $this->currDB->addVendorInfo($attributes);
                 break;
             case 'behavior':
                 $this->currBehavior = $this->currDB->addBehavior($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('table' === $parentTag) {
         switch ($name) {
             case 'column':
                 $this->currColumn = $this->currTable->addColumn($attributes);
                 break;
             case 'foreign-key':
                 $this->currFK = $this->currTable->addForeignKey($attributes);
                 break;
             case 'index':
                 $this->currIndex = new Index();
                 $this->currIndex->setTable($this->currTable);
                 $this->currIndex->loadMapping($attributes);
                 break;
             case 'unique':
                 $this->currUnique = new Unique();
                 $this->currUnique->setTable($this->currTable);
                 $this->currUnique->loadMapping($attributes);
                 break;
             case 'vendor':
                 $this->currVendorObject = $this->currTable->addVendorInfo($attributes);
                 break;
             case 'id-method-parameter':
                 $this->currTable->addIdMethodParameter($attributes);
                 break;
             case 'behavior':
                 $this->currBehavior = $this->currTable->addBehavior($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('column' === $parentTag) {
         switch ($name) {
             case 'inheritance':
                 $this->currColumn->addInheritance($attributes);
                 break;
             case 'vendor':
                 $this->currVendorObject = $this->currColumn->addVendorInfo($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('foreign-key' === $parentTag) {
         switch ($name) {
             case 'reference':
                 $this->currFK->addReference($attributes);
                 break;
             case 'vendor':
                 $this->currVendorObject = $this->currUnique->addVendorInfo($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('index' === $parentTag) {
         switch ($name) {
             case 'index-column':
                 $this->currIndex->addColumn($attributes);
                 break;
             case 'vendor':
                 $this->currVendorObject = $this->currIndex->addVendorInfo($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('unique' === $parentTag) {
         switch ($name) {
             case 'unique-column':
                 $this->currUnique->addColumn($attributes);
                 break;
             case 'vendor':
                 $this->currVendorObject = $this->currUnique->addVendorInfo($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ($parentTag == 'behavior') {
         switch ($name) {
             case 'parameter':
                 $this->currBehavior->addParameter($attributes);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } elseif ('vendor' === $parentTag) {
         switch ($name) {
             case 'parameter':
                 $this->currVendorObject->setParameter($attributes['name'], $attributes['value']);
                 break;
             default:
                 $this->_throwInvalidTagException($parser, $name);
         }
     } else {
         // it must be an invalid tag
         $this->_throwInvalidTagException($parser, $name);
     }
     $this->pushCurrentSchemaTag($name);
 }
 public function testSetGeneratorConfig()
 {
     $config = $this->getMockBuilder('Propel\\Generator\\Config\\GeneratorConfig')->disableOriginalConstructor()->getMock();
     $schema = new Schema();
     $schema->setGeneratorConfig($config);
     $this->assertSame($config, $schema->getGeneratorConfig());
 }
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $generatorConfig = $this->getGeneratorConfig(array('propel.platform.class' => $input->getOption('platform'), 'propel.reverse.parser.class' => $this->getReverseClass($input), 'propel.migration.table' => $input->getOption('migration-table')), $input);
     $this->createDirectory($input->getOption('output-dir'));
     $manager = new MigrationManager();
     $manager->setGeneratorConfig($generatorConfig);
     $manager->setSchemas($this->getSchemas($input->getOption('input-dir')));
     $connections = array();
     $optionConnections = $input->getOption('connection');
     if (!$optionConnections) {
         $connections = $generatorConfig->getBuildConnections($input->getOption('input-dir'));
     } else {
         foreach ($optionConnections as $connection) {
             list($name, $dsn, $infos) = $this->parseConnection($connection);
             $connections[$name] = array_merge(array('dsn' => $dsn), $infos);
         }
     }
     $manager->setConnections($connections);
     $manager->setMigrationTable($input->getOption('migration-table'));
     $manager->setWorkingDirectory($input->getOption('output-dir'));
     if ($manager->hasPendingMigrations()) {
         throw new RuntimeException('Uncommitted migrations have been found ; you should either execute or delete them before rerunning the \'diff\' task');
     }
     $totalNbTables = 0;
     $schema = new Schema();
     foreach ($connections as $name => $params) {
         if ($input->getOption('verbose')) {
             $output->writeln(sprintf('Connecting to database "%s" using DSN "%s"', $name, $params['dsn']));
         }
         $conn = $manager->getAdapterConnection($name);
         $platform = $generatorConfig->getConfiguredPlatform($conn, $name);
         if (!$platform->supportsMigrations()) {
             $output->writeln(sprintf('Skipping database "%s" since vendor "%s" does not support migrations', $name, $platform->getDatabaseType()));
             continue;
         }
         $database = new Database($name);
         $database->setPlatform($platform);
         $database->setDefaultIdMethod(IdMethod::NATIVE);
         $parser = $generatorConfig->getConfiguredSchemaParser($conn);
         $nbTables = $parser->parse($database, $this);
         $schema->addDatabase($database);
         $totalNbTables += $nbTables;
         if ($input->getOption('verbose')) {
             $output->writeln(sprintf('%d tables found in database "%s"', $nbTables, $name), Output::VERBOSITY_VERBOSE);
         }
     }
     if ($totalNbTables) {
         $output->writeln(sprintf('%d tables found in all databases.', $totalNbTables));
     } else {
         $output->writeln('No table found in all databases');
     }
     $appDatasFromXml = $manager->getDataModels();
     $appDataFromXml = array_pop($appDatasFromXml);
     // comparing models
     $output->writeln('Comparing models...');
     $migrationsUp = array();
     $migrationsDown = array();
     foreach ($schema->getDatabases() as $database) {
         $name = $database->getName();
         if ($input->getOption('verbose')) {
             $output->writeln(sprintf('Comparing database "%s"', $name));
         }
         if (!$appDataFromXml->hasDatabase($name)) {
             // FIXME: tables present in database but not in XML
             continue;
         }
         $databaseDiff = DatabaseComparator::computeDiff($database, $appDataFromXml->getDatabase($name));
         if (!$databaseDiff) {
             if ($input->getOption('verbose')) {
                 $output->writeln(sprintf('Same XML and database structures for datasource "%s" - no diff to generate', $name));
             }
             continue;
         }
         $output->writeln(sprintf('Structure of database was modified in datasource "%s": %s', $name, $databaseDiff->getDescription()));
         $platform = $generatorConfig->getConfiguredPlatform(null, $name);
         $migrationsUp[$name] = $platform->getModifyDatabaseDDL($databaseDiff);
         $migrationsDown[$name] = $platform->getModifyDatabaseDDL($databaseDiff->getReverseDiff());
     }
     if (!$migrationsUp) {
         $output->writeln('Same XML and database structures for all datasource - no diff to generate');
         return;
     }
     $timestamp = time();
     $migrationFileName = $manager->getMigrationFileName($timestamp);
     $migrationClassBody = $manager->getMigrationClassBody($migrationsUp, $migrationsDown, $timestamp);
     $file = $input->getOption('output-dir') . DIRECTORY_SEPARATOR . $migrationFileName;
     file_put_contents($file, $migrationClassBody);
     $output->writeln(sprintf('"%s" file successfully created.', $file));
     if (null !== ($editorCmd = $input->getOption('editor'))) {
         $output->writeln(sprintf('Using "%s" as text editor', $editorCmd));
         shell_exec($editorCmd . ' ' . escapeshellarg($file));
     } else {
         $output->writeln('Please review the generated SQL statements, and add data migration code if necessary.');
         $output->writeln('Once the migration class is valid, call the "migrate" task to execute it.');
     }
 }
<?php

use Propel\Generator\Model\Schema;
use Propel\Generator\Platform\MysqlPlatform;
$database = (include __DIR__ . DIRECTORY_SEPARATOR . 'blog-database.php');
$schema = new Schema(new MysqlPlatform());
$schema->setName('acme');
$schema->addDatabase($database);
return $schema;
Beispiel #10
0
    public function testAutoNamespaceToDatabaseSchemaName()
    {
        $yamlConf = <<<EOF
propel:
  database:
      connections:
          mysource:
              adapter: mysql
              classname: Propel\\Runtime\\Connection\\DebugPDO
              dsn: mysql:host=localhost;dbname=mydb
              user: root
              password:
  generator:
      schema:
          autoNamespace: true
EOF;
        $configFilename = sys_get_temp_dir() . '/propel.yml';
        $filesystem = new Filesystem();
        $filesystem->dumpFile($configFilename, $yamlConf);
        $schema = 'TestSchema';
        $config = new GeneratorConfig($configFilename);
        $platform = new MysqlPlatform();
        $parentSchema = new Schema($platform);
        $parentSchema->setGeneratorConfig($config);
        $db = new Database();
        $db->setPlatform($platform);
        $db->setParentSchema($parentSchema);
        $db->setSchema($schema);
        $this->assertEquals($schema, $db->getNamespace());
    }
 public function testValidateReturnsTrueWhenTwoTablesHaveSamePhpNameInDifferentNamespaces()
 {
     $column1 = new Column('id');
     $column1->setPrimaryKey(true);
     $table1 = new Table('foo');
     $table1->addColumn($column1);
     $table1->setNamespace('Foo');
     $column2 = new Column('id');
     $column2->setPrimaryKey(true);
     $table2 = new Table('bar');
     $table2->addColumn($column2);
     $table2->setPhpName('Foo');
     $table2->setNamespace('Bar');
     $database = new Database();
     $database->addTable($table1);
     $database->addTable($table2);
     $schema = new Schema();
     $schema->addDatabase($database);
     $validator = new SchemaValidator($schema);
     $this->assertTrue($validator->validate());
 }