public function __construct($tableName) { $this->tableName = $tableName; $this->schema = DB::getDoctrineSchemaManager($tableName); $platform = $this->schema->getDatabasePlatform(); $platform->registerDoctrineTypeMapping('enum', 'string'); }
public function __construct() { $this->schema = DB::getDoctrineSchemaManager(); $this->schema->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string'); $this->tables = $this->schema->listTables(); $this->relationships = []; //first create empty ruleset for each table foreach ($this->tables as $table) { $this->relationships[$table->getName()] = ['hasMany' => [], 'hasOne' => [], 'belongsTo' => [], 'belongsToMany' => []]; } // get all relationships into $this->relationships variable $this->getAllRelationships(); }
/** * Execute changes */ public function executeChanges() { $platform = $this->sm->getDatabasePlatform(); $sql = []; if (count($this->changedIndexes)) { foreach ($this->changedIndexes as $index) { $sql[] = $platform->getDropIndexSQL($index); $sql[] = $platform->getCreateIndexSQL($index, $this->table); } } if (count($this->dropIndexes)) { foreach ($this->dropIndexes as $index) { $sql[] = $platform->getDropIndexSQL($index); } } if (count($this->addedIndexes)) { foreach ($this->addedIndexes as $index) { $sql[] = $platform->getCreateIndexSQL($index, $this->table); } } if (count($sql)) { foreach ($sql as $query) { $this->db->executeUpdate($query); } $this->changedIndexes = []; $this->dropIndexes = []; $this->addedIndexes = []; } }
/** * @group DDC-887 */ public function testUpdateSchemaWithForeignKeyRenaming() { if (!$this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) { $this->markTestSkipped('This test is only supported on platforms that have foreign keys.'); } $table = new \Doctrine\DBAL\Schema\Table('test_fk_base'); $table->addColumn('id', 'integer'); $table->setPrimaryKey(array('id')); $tableFK = new \Doctrine\DBAL\Schema\Table('test_fk_rename'); $tableFK->setSchemaConfig($this->_sm->createSchemaConfig()); $tableFK->addColumn('id', 'integer'); $tableFK->addColumn('fk_id', 'integer'); $tableFK->setPrimaryKey(array('id')); $tableFK->addIndex(array('fk_id'), 'fk_idx'); $tableFK->addForeignKeyConstraint('test_fk_base', array('fk_id'), array('id')); $this->_sm->createTable($table); $this->_sm->createTable($tableFK); $tableFKNew = new \Doctrine\DBAL\Schema\Table('test_fk_rename'); $tableFKNew->setSchemaConfig($this->_sm->createSchemaConfig()); $tableFKNew->addColumn('id', 'integer'); $tableFKNew->addColumn('rename_fk_id', 'integer'); $tableFKNew->setPrimaryKey(array('id')); $tableFKNew->addIndex(array('rename_fk_id'), 'fk_idx'); $tableFKNew->addForeignKeyConstraint('test_fk_base', array('rename_fk_id'), array('id')); $c = new \Doctrine\DBAL\Schema\Comparator(); $tableDiff = $c->diffTable($tableFK, $tableFKNew); $this->_sm->alterTable($tableDiff); }
/** * @param $name * @return null */ protected function getColumnInfo($name) { if (is_null($this->columnsInfo)) { $sql = $this->schemaManager->getDatabasePlatform()->getListTableColumnsSQL($this->table); $this->columnsInfo = DB::select($sql); } foreach ($this->columnsInfo as $column) { if ($column->Field === $name) { return $column; } } return null; }
public function testAlterTableScenario() { if (!$this->_sm->getDatabasePlatform()->supportsAlterTable()) { $this->markTestSkipped('Alter Table is not supported by this platform.'); } $this->createTestTable('alter_table'); $this->createTestTable('alter_table_foreign'); $table = $this->_sm->listTableDetails('alter_table'); $this->assertTrue($table->hasColumn('id')); $this->assertTrue($table->hasColumn('test')); $this->assertTrue($table->hasColumn('foreign_key_test')); $this->assertEquals(0, count($table->getForeignKeys())); $this->assertEquals(1, count($table->getIndexes())); $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table"); $tableDiff->addedColumns['foo'] = new \Doctrine\DBAL\Schema\Column('foo', Type::getType('integer')); $tableDiff->removedColumns['test'] = $table->getColumn('test'); $this->_sm->alterTable($tableDiff); $table = $this->_sm->listTableDetails('alter_table'); $this->assertFalse($table->hasColumn('test')); $this->assertTrue($table->hasColumn('foo')); $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table"); $tableDiff->addedIndexes[] = new \Doctrine\DBAL\Schema\Index('foo_idx', array('foo')); $this->_sm->alterTable($tableDiff); $table = $this->_sm->listTableDetails('alter_table'); $this->assertEquals(2, count($table->getIndexes())); $this->assertTrue($table->hasIndex('foo_idx')); $this->assertEquals(array('foo'), array_map('strtolower', $table->getIndex('foo_idx')->getColumns())); $this->assertFalse($table->getIndex('foo_idx')->isPrimary()); $this->assertFalse($table->getIndex('foo_idx')->isUnique()); $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table"); $tableDiff->changedIndexes[] = new \Doctrine\DBAL\Schema\Index('foo_idx', array('foo', 'foreign_key_test')); $this->_sm->alterTable($tableDiff); $table = $this->_sm->listTableDetails('alter_table'); $this->assertEquals(2, count($table->getIndexes())); $this->assertTrue($table->hasIndex('foo_idx')); $this->assertEquals(array('foo', 'foreign_key_test'), array_map('strtolower', $table->getIndex('foo_idx')->getColumns())); $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table"); $tableDiff->removedIndexes[] = new \Doctrine\DBAL\Schema\Index('foo_idx', array('foo', 'foreign_key_test')); $fk = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(array('foreign_key_test'), 'alter_table_foreign', array('id')); $tableDiff->addedForeignKeys[] = $fk; $this->_sm->alterTable($tableDiff); $table = $this->_sm->listTableDetails('alter_table'); // dont check for index size here, some platforms automatically add indexes for foreign keys. $this->assertFalse($table->hasIndex('foo_idx')); $this->assertEquals(1, count($table->getForeignKeys())); $fks = $table->getForeignKeys(); $foreignKey = current($fks); $this->assertEquals('alter_table_foreign', strtolower($foreignKey->getForeignTableName())); $this->assertEquals(array('foreign_key_test'), array_map('strtolower', $foreignKey->getColumns())); $this->assertEquals(array('id'), array_map('strtolower', $foreignKey->getForeignColumns())); }
public function testAutoincrementDetection() { if (!$this->_sm->getDatabasePlatform()->supportsIdentityColumns()) { $this->markTestSkipped('This test is only supported on platforms that have autoincrement'); } $table = new \Doctrine\DBAL\Schema\Table('test_autoincrement'); $table->setSchemaConfig($this->_sm->createSchemaConfig()); $table->addColumn('id', 'integer', array('autoincrement' => true)); $table->setPrimaryKey(array('id')); $this->_sm->createTable($table); $inferredTable = $this->_sm->listTableDetails('test_autoincrement'); $this->assertTrue($inferredTable->hasColumn('id')); $this->assertTrue($inferredTable->getColumn('id')->getAutoincrement()); }
/** * @group DBAL-1095 */ public function testDoesNotListIndexesImplicitlyCreatedByForeignKeys() { if (!$this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) { $this->markTestSkipped('This test is only supported on platforms that have foreign keys.'); } $primaryTable = new Table('test_list_index_implicit_primary'); $primaryTable->addColumn('id', 'integer'); $primaryTable->setPrimaryKey(array('id')); $foreignTable = new Table('test_list_index_implicit_foreign'); $foreignTable->addColumn('fk1', 'integer'); $foreignTable->addColumn('fk2', 'integer'); $foreignTable->addIndex(array('fk1'), 'explicit_fk1_idx'); $foreignTable->addForeignKeyConstraint('test_list_index_implicit_primary', array('fk1'), array('id')); $foreignTable->addForeignKeyConstraint('test_list_index_implicit_primary', array('fk2'), array('id')); $this->_sm->dropAndCreateTable($primaryTable); $this->_sm->dropAndCreateTable($foreignTable); $indexes = $this->_sm->listTableIndexes('test_list_index_implicit_foreign'); $this->assertCount(2, $indexes); $this->assertArrayHasKey('explicit_fk1_idx', $indexes); $this->assertArrayHasKey('idx_6d88c7b4fdc58d6c', $indexes); }
/** * Retreive schema table definition foreign keys. * * @param \Doctrine\DBAL\Schema\Table $table * * @return array */ private function getTableForeignKeys(Table $table) { return $this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints() ? $table->getForeignKeys() : array(); }
/** * {@inheritdoc} */ public function loadMetadataForClass($className, ClassMetadataInfo $metadata) { $this->reverseEngineerMappingFromDatabase(); if (!isset($this->classToTableNames[$className])) { throw new \InvalidArgumentException("Unknown class " . $className); } $tableName = $this->classToTableNames[$className]; $metadata->name = $className; $metadata->table['name'] = $tableName; $columns = $this->tables[$tableName]->getColumns(); $indexes = $this->tables[$tableName]->getIndexes(); try { $primaryKeyColumns = $this->tables[$tableName]->getPrimaryKey()->getColumns(); } catch (SchemaException $e) { $primaryKeyColumns = array(); } if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) { $foreignKeys = $this->tables[$tableName]->getForeignKeys(); } else { $foreignKeys = array(); } $allForeignKeyColumns = array(); foreach ($foreignKeys as $foreignKey) { $allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns()); } $ids = array(); $fieldMappings = array(); foreach ($columns as $column) { $fieldMapping = array(); if (in_array($column->getName(), $allForeignKeyColumns)) { continue; } else { if ($primaryKeyColumns && in_array($column->getName(), $primaryKeyColumns)) { $fieldMapping['id'] = true; } } $fieldMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $column->getName(), false); $fieldMapping['columnName'] = $column->getName(); $fieldMapping['type'] = strtolower((string) $column->getType()); if ($column->getType() instanceof \Doctrine\DBAL\Types\StringType) { $fieldMapping['length'] = $column->getLength(); $fieldMapping['fixed'] = $column->getFixed(); } else { if ($column->getType() instanceof \Doctrine\DBAL\Types\IntegerType) { $fieldMapping['unsigned'] = $column->getUnsigned(); } } $fieldMapping['nullable'] = $column->getNotNull() ? false : true; if (isset($fieldMapping['id'])) { $ids[] = $fieldMapping; } else { $fieldMappings[] = $fieldMapping; } } if ($ids) { if (count($ids) == 1) { $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO); } foreach ($ids as $id) { $metadata->mapField($id); } } foreach ($fieldMappings as $fieldMapping) { $metadata->mapField($fieldMapping); } foreach ($this->manyToManyTables as $manyTable) { foreach ($manyTable->getForeignKeys() as $foreignKey) { // foreign key maps to the table of the current entity, many to many association probably exists if (strtolower($tableName) == strtolower($foreignKey->getForeignTableName())) { $myFk = $foreignKey; $otherFk = null; foreach ($manyTable->getForeignKeys() as $foreignKey) { if ($foreignKey != $myFk) { $otherFk = $foreignKey; break; } } if (!$otherFk) { // the definition of this many to many table does not contain // enough foreign key information to continue reverse engeneering. continue; } $localColumn = current($myFk->getColumns()); $associationMapping = array(); $associationMapping['fieldName'] = $this->getFieldNameForColumn($manyTable->getName(), current($otherFk->getColumns()), true); $associationMapping['targetEntity'] = $this->getClassNameForTable($otherFk->getForeignTableName()); if (current($manyTable->getColumns())->getName() == $localColumn) { $associationMapping['inversedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true); $associationMapping['joinTable'] = array('name' => strtolower($manyTable->getName()), 'joinColumns' => array(), 'inverseJoinColumns' => array()); $fkCols = $myFk->getForeignColumns(); $cols = $myFk->getColumns(); for ($i = 0; $i < count($cols); $i++) { $associationMapping['joinTable']['joinColumns'][] = array('name' => $cols[$i], 'referencedColumnName' => $fkCols[$i]); } $fkCols = $otherFk->getForeignColumns(); $cols = $otherFk->getColumns(); for ($i = 0; $i < count($cols); $i++) { $associationMapping['joinTable']['inverseJoinColumns'][] = array('name' => $cols[$i], 'referencedColumnName' => $fkCols[$i]); } } else { $associationMapping['mappedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true); } $metadata->mapManyToMany($associationMapping); break; } } } foreach ($foreignKeys as $foreignKey) { $foreignTable = $foreignKey->getForeignTableName(); $cols = $foreignKey->getColumns(); $fkCols = $foreignKey->getForeignColumns(); $localColumn = current($cols); $associationMapping = array(); $associationMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $localColumn, true); $associationMapping['targetEntity'] = $this->getClassNameForTable($foreignTable); if ($primaryKeyColumns && in_array($localColumn, $primaryKeyColumns)) { $associationMapping['id'] = true; } for ($i = 0; $i < count($cols); $i++) { $associationMapping['joinColumns'][] = array('name' => $cols[$i], 'referencedColumnName' => $fkCols[$i]); } //Here we need to check if $cols are the same as $primaryKeyColums if (!array_diff($cols, $primaryKeyColumns)) { $metadata->mapOneToOne($associationMapping); } else { $metadata->mapManyToOne($associationMapping); } } }
public function generateFieldsFromTable() { $this->schema->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string'); $columns = $this->schema->listTableColumns($this->tableName); $fields = []; foreach ($columns as $column) { switch ($column->getType()->getName()) { case 'integer': $fieldInput = $this->generateIntFieldInput($column->getName(), 'integer', $column); $type = 'number'; break; case 'smallint': $fieldInput = $this->generateIntFieldInput($column->getName(), 'smallInteger', $column); $type = 'number'; break; case 'bigint': $fieldInput = $this->generateIntFieldInput($column->getName(), 'bigInteger', $column); $type = 'number'; break; case 'boolean': $fieldInput = $this->generateSingleFieldInput($column->getName(), 'boolean'); $type = 'text'; break; case 'datetime': $fieldInput = $this->generateSingleFieldInput($column->getName(), 'dateTime'); $type = 'date'; break; case 'datetimetz': $fieldInput = $this->generateSingleFieldInput($column->getName(), 'dateTimeTz'); $type = 'date'; break; case 'date': $fieldInput = $this->generateSingleFieldInput($column->getName(), 'date'); $type = 'date'; break; case 'time': $fieldInput = $this->generateSingleFieldInput($column->getName(), 'time'); $type = 'text'; break; case 'decimal': $fieldInput = $this->generateDecimalInput($column, 'decimal'); $type = 'number'; break; case 'float': $fieldInput = $this->generateFloatInput($column); $type = 'number'; break; case 'string': $fieldInput = $this->generateStringInput($column); $type = 'text'; break; case 'text': $fieldInput = $this->generateTextInput($column); $type = 'textarea'; break; default: $fieldInput = $this->generateTextInput($column); $type = 'text'; } if (strtolower($column->getName()) == 'password') { $type = 'password'; } elseif (strtolower($column->getName()) == 'email') { $type = 'email'; } if (!empty($fieldInput)) { // $fieldInput .= $this->checkForDefault($column); // $fieldInput .= $this->checkForNullable($column); // $fieldInput .= $this->checkForUnique($column); $fields[] = GeneratorUtils::processFieldInput($fieldInput, $type, ''); } } return $fields; }
/** * Constructor. * * @param \Illuminate\Database\Connection $connection * @return void */ public function __construct(Connection $connection) { $this->connection = $connection; $this->schemaManager = $connection->getDoctrineSchemaManager(); $this->platform = $this->schemaManager->getDatabasePlatform(); }
/** * @param string $type * @param string $value */ public function registerType($type, $value) { $this->types[$type] = $value; $this->manager->getDatabasePlatform()->registerDoctrineTypeMapping($type, $value); }
/** * {@inheritdoc} */ public function loadMetadataForClass($className, ClassMetadataInfo $metadata) { $this->reverseEngineerMappingFromDatabase(); if (!isset($this->classToTableNames[$className])) { throw new \InvalidArgumentException("Unknown class " . $className); } $tableName = $this->classToTableNames[$className]; $metadata->name = $className; $metadata->table['name'] = $tableName; $columns = $this->tables[$tableName]->getColumns(); $indexes = $this->tables[$tableName]->getIndexes(); try { $primaryKeyColumns = $this->tables[$tableName]->getPrimaryKey()->getColumns(); } catch (SchemaException $e) { $primaryKeyColumns = array(); } if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) { $foreignKeys = $this->tables[$tableName]->getForeignKeys(); } else { $foreignKeys = array(); } $allForeignKeyColumns = array(); foreach ($foreignKeys as $foreignKey) { $allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns()); } $ids = array(); $fieldMappings = array(); foreach ($columns as $column) { $fieldMapping = array(); if ($primaryKeyColumns && in_array($column->getName(), $primaryKeyColumns)) { $fieldMapping['id'] = true; } else { if (in_array($column->getName(), $allForeignKeyColumns)) { continue; } } $fieldMapping['fieldName'] = Inflector::camelize(strtolower($column->getName())); $fieldMapping['columnName'] = $column->getName(); $fieldMapping['type'] = strtolower((string) $column->getType()); if ($column->getType() instanceof \Doctrine\DBAL\Types\StringType) { $fieldMapping['length'] = $column->getLength(); $fieldMapping['fixed'] = $column->getFixed(); } else { if ($column->getType() instanceof \Doctrine\DBAL\Types\IntegerType) { $fieldMapping['unsigned'] = $column->getUnsigned(); } } $fieldMapping['nullable'] = $column->getNotNull() ? false : true; if (isset($fieldMapping['id'])) { $ids[] = $fieldMapping; } else { $fieldMappings[] = $fieldMapping; } } if ($ids) { if (count($ids) == 1) { $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO); } foreach ($ids as $id) { $metadata->mapField($id); } } foreach ($fieldMappings as $fieldMapping) { $metadata->mapField($fieldMapping); } foreach ($this->manyToManyTables as $manyTable) { foreach ($manyTable->getForeignKeys() as $foreignKey) { if (strtolower($tableName) == strtolower($foreignKey->getForeignTableName())) { $myFk = $foreignKey; foreach ($manyTable->getForeignKeys() as $foreignKey) { if ($foreignKey != $myFk) { $otherFk = $foreignKey; break; } } if ($otherFk === NULL) { continue; } $localColumn = current($myFk->getColumns()); $associationMapping = array(); $associationMapping['fieldName'] = Inflector::camelize(str_replace('_id', '', strtolower(current($otherFk->getColumns())))); $associationMapping['targetEntity'] = Inflector::classify(strtolower($otherFk->getForeignTableName())); if (current($manyTable->getColumns())->getName() == $localColumn) { $associationMapping['inversedBy'] = Inflector::camelize(str_replace('_id', '', strtolower(current($myFk->getColumns())))); $associationMapping['joinTable'] = array('name' => strtolower($manyTable->getName()), 'joinColumns' => array(), 'inverseJoinColumns' => array()); $fkCols = $myFk->getForeignColumns(); $cols = $myFk->getColumns(); for ($i = 0; $i < count($cols); $i++) { $associationMapping['joinTable']['joinColumns'][] = array('name' => $cols[$i], 'referencedColumnName' => $fkCols[$i]); } $fkCols = $otherFk->getForeignColumns(); $cols = $otherFk->getColumns(); for ($i = 0; $i < count($cols); $i++) { $associationMapping['joinTable']['inverseJoinColumns'][] = array('name' => $cols[$i], 'referencedColumnName' => $fkCols[$i]); } } else { $associationMapping['mappedBy'] = Inflector::camelize(str_replace('_id', '', strtolower(current($myFk->getColumns())))); } $metadata->mapManyToMany($associationMapping); break; } } } foreach ($foreignKeys as $foreignKey) { $foreignTable = $foreignKey->getForeignTableName(); $cols = $foreignKey->getColumns(); $fkCols = $foreignKey->getForeignColumns(); $localColumn = current($cols); $associationMapping = array(); $associationMapping['fieldName'] = Inflector::camelize(str_replace('_id', '', strtolower($localColumn))); $associationMapping['targetEntity'] = Inflector::classify($foreignTable); for ($i = 0; $i < count($cols); $i++) { $associationMapping['joinColumns'][] = array('name' => $cols[$i], 'referencedColumnName' => $fkCols[$i]); } $metadata->mapManyToOne($associationMapping); } }
/** * Returns a quoted schema object. (table name, column name, etc) * * @param string $object * @return string */ public function quoteSchemaObject($object) { return $this->_sm->getDatabasePlatform()->quoteIdentifier($object); }