/** * Look for table structure modifications and apply to them * * @param string $tableName * @param array $tableColumns */ public function morphTable($tableName, $definition) { $defaultSchema = self::$_connection->getDefaultSchema(); $tableExists = self::$_connection->tableExists($tableName, $defaultSchema); if (isset($definition['columns'])) { if (count($definition['columns']) == 0) { throw new ActiveRecordMigrationException('La tabla debe tener al menos una columna'); } $fields = array(); foreach ($definition['columns'] as $tableColumn) { if (!is_object($tableColumn)) { throw new ActiveRecordMigrationException('La tabla debe tener al menos una columna'); } $fields[$tableColumn->getName()] = $tableColumn; } if ($tableExists == true) { $localFields = array(); $description = self::$_connection->describeTable($tableName, $defaultSchema); foreach ($description as $field) { $localFields[$field['Field']] = $field; } foreach ($fields as $fieldName => $tableColumn) { if (!isset($localFields[$fieldName])) { self::$_connection->addColumn($tableName, $tableColumn->getSchemaName(), $tableColumn); } else { $changed = false; $columnDefinition = strtolower(self::$_connection->getColumnDefinition($tableColumn)); if ($localFields[$fieldName]['Type'] != $columnDefinition) { $changed = true; } if ($tableColumn->isNotNull() != true && $localFields[$fieldName]['Null'] == 'NO') { $changed = true; } else { if ($tableColumn->isNotNull() == true && $localFields[$fieldName]['Null'] == 'YES') { $changed = true; } } if ($changed == true) { self::$_connection->modifyColumn($tableName, $tableColumn->getSchemaName(), $tableColumn); } } } foreach ($localFields as $fieldName => $localField) { if (!isset($fields[$fieldName])) { self::$_connection->dropColumn($tableName, null, $fieldName); } } } else { self::$_connection->createTable($tableName, $defaultSchema, $definition); if (method_exists($this, 'afterCreateTable')) { $this->afterCreateTable(); } } } if (isset($definition['references'])) { if ($tableExists == true) { $references = array(); foreach ($definition['references'] as $tableReference) { $references[$tableReference->getName()] = $tableReference; } $localReferences = self::$_connection->describeReferences($tableName, $defaultSchema); foreach ($definition['references'] as $tableReference) { if (!isset($localReferences[$tableReference->getName()])) { self::$_connection->addForeignKey($tableName, $tableReference->getSchemaName(), $tableReference); } else { $changed = false; if ($tableReference->getReferencedTable() != $localReferences[$tableReference->getName()]['referencedTable']) { $changed = true; } if ($changed == false) { if (count($tableReference->getColumns()) != count($localReferences[$tableReference->getName()]['columns'])) { $changed = true; } } if ($changed == false) { if (count($tableReference->getReferencedColumns()) != count($localReferences[$tableReference->getName()]['referencedColumns'])) { $changed = true; } } if ($changed == false) { foreach ($tableReference->getColumns() as $columnName) { if (!in_array($columnName, $localReferences[$tableReference->getName()]['columns'])) { $changed = true; break; } } } if ($changed == false) { foreach ($tableReference->getReferencedColumns() as $columnName) { if (!in_array($columnName, $localReferences[$tableReference->getName()]['referencedColumns'])) { $changed = true; break; } } } if ($changed == true) { self::$_connection->dropForeignKey($tableName, $tableReference->getSchemaName(), $tableReference->getName()); self::$_connection->addForeignKey($tableName, $tableReference->getSchemaName(), $tableReference); } } } foreach ($localReferences as $referenceName => $reference) { if (!isset($references[$referenceName])) { self::$_connection->dropForeignKey($tableName, null, $referenceName); } } } } if (isset($definition['indexes'])) { if ($tableExists == true) { $indexes = array(); foreach ($definition['indexes'] as $tableIndex) { $indexes[$tableIndex->getName()] = $tableIndex; } $localIndexes = self::$_connection->describeIndexes($tableName, $defaultSchema); foreach ($definition['indexes'] as $tableIndex) { if (!isset($localIndexes[$tableIndex->getName()])) { if ($tableIndex->getName() == 'PRIMARY') { self::$_connection->addPrimaryKey($tableName, $tableColumn->getSchemaName(), $tableIndex); } else { self::$_connection->addIndex($tableName, $tableColumn->getSchemaName(), $tableIndex); } } else { $changed = false; if (count($tableIndex->getColumns()) != count($localIndexes[$tableIndex->getName()])) { $changed = true; } else { foreach ($tableIndex->getColumns() as $columnName) { if (!in_array($columnName, $localIndexes[$tableIndex->getName()])) { $changed = true; break; } } } if ($changed == true) { if ($tableIndex->getName() == 'PRIMARY') { self::$_connection->dropPrimaryKey($tableName, $tableColumn->getSchemaName()); self::$_connection->addPrimaryKey($tableName, $tableColumn->getSchemaName(), $tableIndex); } else { self::$_connection->dropIndex($tableName, $tableColumn->getSchemaName(), $tableIndex->getName()); self::$_connection->addIndex($tableName, $tableColumn->getSchemaName(), $tableIndex); } } } } foreach ($localIndexes as $indexName => $indexColumns) { if (!isset($indexes[$indexName])) { self::$_connection->dropIndex($tableName, null, $indexName); } } } } }