. */ namespace Doctrine\DBAL\Schema; /** * xxx * * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @author Konsta Vesterinen * @author Lukas Smith (PEAR MDB2 library) * @version $Revision$ * @since 2.0 */ class MySqlSchemaManager extends AbstractSchemaManager { protected function _getPortableViewDefinition($view) { return $view['TABLE_NAME']; } protected function _getPortableTableDefinition($table) { return end($table); } protected function _getPortableUserDefinition($user) { return array( 'user' => $user['User'], 'password' => $user['Password'], ); } protected function _getPortableTableIndexDefinition($tableIndex) { $tableIndex = array_change_key_case($tableIndex, CASE_LOWER); $result = array(); if ($tableIndex['key_name'] != 'PRIMARY' && ($index = $tableIndex['key_name'])) { $result['name'] = $index; $result['column'] = $tableIndex['column_name']; $result['unique'] = $tableIndex['non_unique'] ? false : true; } return $result; } 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']; } 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'] = ''; } $values = null; $scale = null; switch ($dbType) { case 'tinyint': $type = 'integer'; $type = 'boolean'; if (preg_match('/^(is|has)/', $tableColumn['name'])) { $type = array_reverse($type); } $unsigned = preg_match('/ unsigned/i', $tableColumn['Type']); $length = 1; break; case 'smallint': $type = 'integer'; $unsigned = preg_match('/ unsigned/i', $tableColumn['Type']); $length = 2; break; case 'mediumint': $type = 'integer'; $unsigned = preg_match('/ unsigned/i', $tableColumn['Type']); $length = 3; break; case 'int': case 'integer': $type = 'integer'; $unsigned = preg_match('/ unsigned/i', $tableColumn['Type']); $length = 4; break; case 'bigint': $type = 'integer'; $unsigned = preg_match('/ unsigned/i', $tableColumn['Type']); $length = 8; break; case 'tinytext': case 'mediumtext': case 'longtext': case 'text': case 'text': 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); } } elseif (strstr($dbType, 'text')) { $type = 'clob'; if ($decimal == 'binary') { $type = 'blob'; } } if ($fixed !== false) { $fixed = true; } break; case 'set': $fixed = false; $type = 'text'; $type = 'integer'; break; case 'date': $type = 'date'; $length = null; break; case 'datetime': case 'timestamp': $type = 'timestamp'; $length = null; break; case 'time': $type = 'time'; $length = null; break; case 'float': case 'double': case 'real': $type = 'float'; $unsigned = preg_match('/ unsigned/i', $tableColumn['type']); break; case 'unknown': case 'decimal': if ($decimal !== null) { $scale = $decimal; } case 'numeric': $type = 'decimal'; $unsigned = preg_match('/ unsigned/i', $tableColumn['type']); 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 'bit': $type = 'bit'; 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 ); if ($values !== null) { $def['values'] = $values; } if ($scale !== null) { $def['scale'] = $scale; } $values = isset($def['values']) ? $def['values'] : array(); $column = array( 'name' => $tableColumn['Field'], 'values' => $values, 'primary' => (bool) (strtolower($tableColumn['Key']) == 'pri'), 'default' => $tableColumn['Default'], 'notnull' => (bool) ($tableColumn['Null'] != 'YES'), 'autoincrement' => (bool) (strpos($tableColumn['Extra'], 'auto_increment') !== false), ); $column = array_merge($column, $def); return $column; } public function _getPortableTableForeignKeyDefinition($tableForeignKey) { $tableForeignKey = array_change_key_case($tableForeignKey, CASE_LOWER); $foreignKey = array( 'table' => $tableForeignKey['referenced_table_name'], 'local' => $tableForeignKey['column_name'], 'foreign' => $tableForeignKey['referenced_column_name'] ); return $foreignKey; } /** * {@inheritdoc} */ public function createSequence($sequenceName, $start = 1, $allocationSize = 1) { $seqColumnName = 'mysql_sequence'; /* No support for options yet. Might add 4th options parameter later $optionsStrings = array(); if (isset($options['comment']) && ! empty($options['comment'])) { $optionsStrings['comment'] = 'COMMENT = ' . $this->_conn->quote($options['comment'], 'string'); } if (isset($options['charset']) && ! empty($options['charset'])) { $optionsStrings['charset'] = 'DEFAULT CHARACTER SET ' . $options['charset']; if (isset($options['collate'])) { $optionsStrings['collate'] .= ' COLLATE ' . $options['collate']; } } $type = false; if (isset($options['type'])) { $type = $options['type']; } else { $type = $this->_conn->default_table_type; } if ($type) { $optionsStrings[] = 'ENGINE = ' . $type; }*/ try { $query = 'CREATE TABLE ' . $sequenceName . ' (' . $seqcolName . ' INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (' . $seqcolName . '))'; /*if (!empty($options_strings)) { $query .= ' '.implode(' ', $options_strings); }*/ $query .= ' ENGINE = INNODB'; $res = $this->_conn->exec($query); } catch(Doctrine\DBAL\ConnectionException $e) { throw \Doctrine\Common\DoctrineException::createSequenceFailed($query); } if ($start == 1) { return; } $query = 'INSERT INTO ' . $sequenceName . ' (' . $seqcolName . ') VALUES (' . ($start - 1) . ')'; $res = $this->_conn->exec($query); // Handle error try { $res = $this->_conn->exec('DROP TABLE ' . $sequenceName); } catch (\Exception $e) { throw \Doctrine\Common\DoctrineException::couldNotDropSequenceTable($sequenceName); } return $res; } }