. */ namespace Doctrine\DBAL\Schema; /** * Schema manager for the MySql RDBMS. * * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @author Konsta Vesterinen * @author Lukas Smith (PEAR MDB2 library) * @author Roman Borschel * @author Benjamin Eberlei * @version $Revision$ * @since 2.0 */ class MySqlSchemaManager extends AbstractSchemaManager { protected function _getPortableViewDefinition($view) { return array( 'name' => $view['TABLE_NAME'], 'sql' => $view['VIEW_DEFINITION'] ); } protected function _getPortableTableDefinition($table) { return array_shift($table); } protected function _getPortableUserDefinition($user) { return array( 'user' => $user['User'], 'password' => $user['Password'], ); } protected function _getPortableTableIndexesList($tableIndexes, $tableName=null) { foreach($tableIndexes AS $k => $v) { $v = array_change_key_case($v, CASE_LOWER); if($v['key_name'] == 'PRIMARY') { $v['primary'] = true; } else { $v['primary'] = false; } $tableIndexes[$k] = $v; } return parent::_getPortableTableIndexesList($tableIndexes, $tableName); } protected function _getPortableTableConstraintDefinition($tableConstraint) { $tableConstraint = array_change_key_case($tableConstraint, CASE_LOWER); if ( ! $tableConstraint['non_unique']) { $index = $tableConstraint['key_name']; if ( ! empty($index)) { return $index; } } } protected function _getPortableSequenceDefinition($sequence) { return end($sequence); } protected function _getPortableDatabaseDefinition($database) { return $database['Database']; } /** * Gets a portable column definition. * * The database type is mapped to a corresponding Doctrine mapping type. * * @param $tableColumn * @return array */ protected function _getPortableTableColumnDefinition($tableColumn) { $dbType = strtolower($tableColumn['Type']); $dbType = strtok($dbType, '(), '); if ($dbType == 'national') { $dbType = strtok('(), '); } if (isset($tableColumn['length'])) { $length = $tableColumn['length']; $decimal = ''; } else { $length = strtok('(), '); $decimal = strtok('(), ') ? strtok('(), '):null; } $type = array(); $unsigned = $fixed = null; if ( ! isset($tableColumn['name'])) { $tableColumn['name'] = ''; } $scale = null; $precision = null; // Map db type to Doctrine mapping type switch ($dbType) { case 'tinyint': $type = 'boolean'; $length = null; break; case 'smallint': $type = 'smallint'; $length = null; break; case 'mediumint': $type = 'integer'; $length = null; break; case 'int': case 'integer': $type = 'integer'; $length = null; break; case 'bigint': $type = 'bigint'; $length = null; break; case 'tinytext': case 'mediumtext': case 'longtext': case 'text': $type = 'text'; $fixed = false; break; case 'varchar': $fixed = false; case 'string': case 'char': $type = 'string'; if ($length == '1') { $type = 'boolean'; if (preg_match('/^(is|has)/', $tableColumn['name'])) { $type = array_reverse($type); } } else if (strstr($dbType, 'text')) { $type = 'text'; if ($decimal == 'binary') { $type = 'blob'; } } if ($fixed !== false) { $fixed = true; } break; case 'set': $fixed = false; $type = 'text'; $type = 'integer'; //FIXME:??? break; case 'date': $type = 'date'; break; case 'datetime': case 'timestamp': $type = 'datetime'; break; case 'time': $type = 'time'; break; case 'float': case 'double': case 'real': case 'numeric': case 'decimal': if(preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['Type'], $match)) { $precision = $match[1]; $scale = $match[2]; $length = null; } $type = 'decimal'; break; case 'tinyblob': case 'mediumblob': case 'longblob': case 'blob': case 'binary': case 'varbinary': $type = 'blob'; $length = null; break; case 'year': $type = 'integer'; $type = 'date'; $length = null; break; case 'geometry': case 'geometrycollection': case 'point': case 'multipoint': case 'linestring': case 'multilinestring': case 'polygon': case 'multipolygon': $type = 'blob'; $length = null; break; default: $type = 'string'; $length = null; } $length = ((int) $length == 0) ? null : (int) $length; $def = array( 'type' => $type, 'length' => $length, 'unsigned' => (bool) $unsigned, 'fixed' => (bool) $fixed ); $options = array( 'length' => $length, 'unsigned' => (bool)$unsigned, 'fixed' => (bool)$fixed, 'default' => $tableColumn['Default'], 'notnull' => (bool) ($tableColumn['Null'] != 'YES'), 'scale' => null, 'precision' => null, 'platformOptions' => array( 'primary' => (strtolower($tableColumn['Key']) == 'pri') ? true : false, 'unique' => (strtolower($tableColumn['Key']) == 'uni') ? true :false, 'autoincrement' => (bool) (strpos($tableColumn['Extra'], 'auto_increment') !== false), ), ); if ($scale !== null && $precision !== null) { $options['scale'] = $scale; $options['precision'] = $precision; } $column = new Column($tableColumn['Field'], \Doctrine\DBAL\Types\Type::getType($type), $options); $column->setCaseMode($this->getCaseMode()); return $column; } public function _getPortableTableForeignKeyDefinition($tableForeignKey) { $tableForeignKey = array_change_key_case($tableForeignKey, CASE_LOWER); $fk = new ForeignKeyConstraint( (array)$tableForeignKey['column_name'], $tableForeignKey['referenced_table_name'], (array)$tableForeignKey['referenced_column_name'], $tableForeignKey['constraint_name'], array() ); $fk->setCaseMode($this->getCaseMode()); return $fk; } }