diff --git a/src/Phinx/Db/Adapter/MysqlAdapter.php b/src/Phinx/Db/Adapter/MysqlAdapter.php index 122e134d3..9a21c4c7f 100644 --- a/src/Phinx/Db/Adapter/MysqlAdapter.php +++ b/src/Phinx/Db/Adapter/MysqlAdapter.php @@ -22,7 +22,7 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. - * + * * @package Phinx * @subpackage Phinx\Db\Adapter */ @@ -51,11 +51,11 @@ public function connect() throw new \RuntimeException('You need to enable the PDO_Mysql extension for Phinx to run properly.'); // @codeCoverageIgnoreEnd } - + $dsn = ''; $db = null; $options = $this->getOptions(); - + // if port is specified use it, otherwise use the MySQL default if (isset($options['port'])) { $dsn = 'mysql:host=' . $options['host'] . ';port=' . $options['port'] . ';dbname=' . $options['name']; @@ -83,14 +83,14 @@ public function connect() } $this->setConnection($db); - + // Create the schema table if it doesn't already exist if (!$this->hasSchemaTable()) { $this->createSchemaTable(); } } } - + /** * {@inheritdoc} */ @@ -98,7 +98,7 @@ public function disconnect() { $this->connection = null; } - + /** * {@inheritdoc} */ @@ -106,7 +106,7 @@ public function hasTransactions() { return true; } - + /** * {@inheritdoc} */ @@ -114,7 +114,7 @@ public function beginTransaction() { $this->execute('START TRANSACTION'); } - + /** * {@inheritdoc} */ @@ -122,7 +122,7 @@ public function commitTransaction() { $this->execute('COMMIT'); } - + /** * {@inheritdoc} */ @@ -130,7 +130,7 @@ public function rollbackTransaction() { $this->execute('ROLLBACK'); } - + /** * {@inheritdoc} */ @@ -138,7 +138,7 @@ public function quoteTableName($tableName) { return str_replace('.', '`.`', $this->quoteColumnName($tableName)); } - + /** * {@inheritdoc} */ @@ -146,23 +146,23 @@ public function quoteColumnName($columnName) { return '`' . str_replace('`', '``', $columnName) . '`'; } - + /** * {@inheritdoc} */ public function hasTable($tableName) { $options = $this->getOptions(); - + $tables = array(); $rows = $this->fetchAll(sprintf('SHOW TABLES IN `%s`', $options['name'])); foreach ($rows as $row) { $tables[] = strtolower($row[0]); } - + return in_array(strtolower($tableName), $tables); } - + /** * {@inheritdoc} */ @@ -176,7 +176,7 @@ public function createTable(Table $table) 'collation' => 'utf8_general_ci' ); $options = array_merge($defaultOptions, $table->getOptions()); - + // Add the default primary key $columns = $table->getPendingColumns(); if (!isset($options['id']) || (isset($options['id']) && $options['id'] === true)) { @@ -184,7 +184,7 @@ public function createTable(Table $table) $column->setName('id') ->setType('integer') ->setIdentity(true); - + array_unshift($columns, $column); $options['primary_key'] = 'id'; @@ -198,28 +198,28 @@ public function createTable(Table $table) array_unshift($columns, $column); $options['primary_key'] = $options['id']; } - + // TODO - process table options like collation etc - + // process table engine (default to InnoDB) $optionsStr = 'ENGINE = InnoDB'; if (isset($options['engine'])) { $optionsStr = sprintf('ENGINE = %s', $options['engine']); } - + // process table collation if (isset($options['collation'])) { $charset = explode('_', $options['collation']); $optionsStr .= sprintf(' CHARACTER SET %s', $charset[0]); $optionsStr .= sprintf(' COLLATE %s', $options['collation']); } - + $sql = 'CREATE TABLE '; $sql .= $this->quoteTableName($table->getName()) . ' ('; foreach ($columns as $column) { $sql .= $this->quoteColumnName($column->getName()) . ' ' . $this->getColumnSqlDefinition($column) . ', '; } - + // set the primary key(s) if (isset($options['primary_key'])) { $sql = rtrim($sql); @@ -235,7 +235,7 @@ public function createTable(Table $table) } else { $sql = substr(rtrim($sql), 0, -1); // no primary keys } - + // set the indexes $indexes = $table->getIndexes(); if (!empty($indexes)) { @@ -260,7 +260,7 @@ public function createTable(Table $table) $this->execute($sql); $this->endCommandTimer(); } - + /** * {@inheritdoc} */ @@ -271,7 +271,7 @@ public function renameTable($tableName, $newTableName) $this->execute(sprintf('RENAME TABLE %s TO %s', $this->quoteTableName($tableName), $this->quoteTableName($newTableName))); $this->endCommandTimer(); } - + /** * {@inheritdoc} */ @@ -310,7 +310,7 @@ public function getColumns($tableName) return $columns; } - + /** * {@inheritdoc} */ @@ -322,10 +322,10 @@ public function hasColumn($tableName, $columnName) return true; } } - + return false; } - + /** * {@inheritdoc} */ @@ -337,16 +337,16 @@ public function addColumn(Table $table, Column $column) $this->quoteColumnName($column->getName()), $this->getColumnSqlDefinition($column) ); - + if ($column->getAfter()) { $sql .= ' AFTER ' . $this->quoteColumnName($column->getAfter()); } - + $this->writeCommand('addColumn', array($table->getName(), $column->getName(), $column->getType())); $this->execute($sql); $this->endCommandTimer(); } - + /** * {@inheritdoc} */ @@ -359,7 +359,7 @@ public function renameColumn($tableName, $columnName, $newColumnName) $null = ($row['Null'] == 'NO') ? 'NOT NULL' : 'NULL'; $extra = ' ' . strtoupper($row['Extra']); $definition = $row['Type'] . ' ' . $null . $extra; - + $this->writeCommand('renameColumn', array($tableName, $columnName, $newColumnName)); $this->execute( sprintf('ALTER TABLE %s CHANGE COLUMN %s %s %s', @@ -372,13 +372,13 @@ public function renameColumn($tableName, $columnName, $newColumnName) return $this->endCommandTimer(); } } - + throw new \InvalidArgumentException(sprintf( 'The specified column doesn\'t exist: ' . $columnName )); } - + /** * {@inheritdoc} */ @@ -396,7 +396,7 @@ public function changeColumn($tableName, $columnName, Column $newColumn) ); return $this->endCommandTimer(); } - + /** * {@inheritdoc} */ @@ -413,7 +413,7 @@ public function dropColumn($tableName, $columnName) ); return $this->endCommandTimer(); } - + /** * Get an array of indexes from a particular table. * @@ -432,7 +432,7 @@ protected function getIndexes($tableName) } return $indexes; } - + /** * {@inheritdoc} */ @@ -441,20 +441,21 @@ public function hasIndex($tableName, $columns) if (is_string($columns)) { $columns = array($columns); // str to array } - + $columns = array_map('strtolower', $columns); $indexes = $this->getIndexes($tableName); - + var_dump($indexes); + die; foreach ($indexes as $index) { $a = array_diff($columns, $index['columns']); if (empty($a)) { return true; } } - + return false; } - + /** * {@inheritdoc} */ @@ -470,31 +471,48 @@ public function addIndex(Table $table, Index $index) ); return $this->endCommandTimer(); } - + /** * {@inheritdoc} */ - public function dropIndex($tableName, $columns) + public function dropIndex($tableName, $columns, $indexName = null) { $this->startCommandTimer(); if (is_string($columns)) { $columns = array($columns); // str to array } - + $this->writeCommand('dropIndex', array($tableName, $columns)); $indexes = $this->getIndexes($tableName); $columns = array_map('strtolower', $columns); - - foreach ($indexes as $indexName => $index) { - $a = array_diff($columns, $index['columns']); - if (empty($a)) { + + foreach ($indexes as $name => $index) { + if ($indexName && $name == $indexName) { $this->execute( - sprintf('ALTER TABLE %s DROP INDEX %s', + sprintf( + 'ALTER TABLE %s DROP INDEX %s', $this->quoteTableName($tableName), $this->quoteColumnName($indexName) ) ); - return $this->endCommandTimer(); + $this->endCommandTimer(); + + return; + } + else { + $a = array_diff($columns, $index['columns']); + if (empty($a)) { + $this->execute( + sprintf( + 'ALTER TABLE %s DROP INDEX %s', + $this->quoteTableName($tableName), + $this->quoteColumnName($name) + ) + ); + $this->endCommandTimer(); + + return; + } } } } @@ -533,6 +551,16 @@ public function hasForeignKey($tableName, $columns, $constraint = null) protected function getForeignKeys($tableName) { $foreignKeys = array(); + + $parts = explode('.', $tableName); + if (count($parts) > 0) { + $tableName = end($parts); + $database = $parts[0]; + } + else { + $database = $this->getOptions()["name"]; + } + $rows = $this->fetchAll(sprintf( 'SELECT CONSTRAINT_NAME, @@ -541,11 +569,11 @@ protected function getForeignKeys($tableName) REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE - WHERE REFERENCED_TABLE_SCHEMA = DATABASE() + WHERE REFERENCED_TABLE_SCHEMA = "%s" AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = "%s" ORDER BY POSITION_IN_UNIQUE_CONSTRAINT', - $tableName + $database, $tableName )); foreach ($rows as $row) { $foreignKeys[$row['CONSTRAINT_NAME']]['table'] = $row['TABLE_NAME']; @@ -581,9 +609,9 @@ public function dropForeignKey($tableName, $columns, $constraint = null) if (is_string($columns)) { $columns = array($columns); // str to array } - + $this->writeCommand('dropForeignKey', array($tableName, $columns)); - + if ($constraint) { $this->execute( sprintf('ALTER TABLE %s DROP FOREIGN KEY %s', @@ -593,16 +621,25 @@ public function dropForeignKey($tableName, $columns, $constraint = null) ); return $this->endCommandTimer(); } else { + $parts = explode('.', $tableName); + if (count($parts) > 0) { + $tableName = end($parts); + $database = $parts[0]; + } else { + $database = $this->getOptions()["name"]; + } + foreach ($columns as $column) { $rows = $this->fetchAll(sprintf( 'SELECT CONSTRAINT_NAME FROM information_schema.KEY_COLUMN_USAGE - WHERE REFERENCED_TABLE_SCHEMA = DATABASE() + WHERE REFERENCED_TABLE_SCHEMA = "%s" AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = "%s" AND COLUMN_NAME = "%s" ORDER BY POSITION_IN_UNIQUE_CONSTRAINT', + $database, $tableName, $column )); @@ -613,7 +650,7 @@ public function dropForeignKey($tableName, $columns, $constraint = null) } return $this->endCommandTimer(); } - + /** * {@inheritdoc} */ @@ -731,7 +768,7 @@ public function createDatabase($name, $options = array()) $this->startCommandTimer(); $this->writeCommand('createDatabase', array($name)); $charset = isset($options['charset']) ? $options['charset'] : 'utf8'; - + if (isset($options['collation'])) { $this->execute(sprintf( 'CREATE DATABASE `%s` DEFAULT CHARACTER SET `%s` COLLATE `%s`', $name, $charset, $options['collation'] @@ -741,7 +778,7 @@ public function createDatabase($name, $options = array()) } return $this->endCommandTimer(); } - + /** * {@inheritdoc} */ @@ -753,16 +790,16 @@ public function hasDatabase($name) $name ) ); - + foreach ($rows as $row) { if (!empty($row)) { return true; } } - + return false; } - + /** * {@inheritdoc} */ @@ -773,7 +810,7 @@ public function dropDatabase($name) $this->execute(sprintf('DROP DATABASE IF EXISTS `%s`', $name)); return $this->endCommandTimer(); } - + /** * Gets the MySQL Column Definition for a Column object. * @@ -809,7 +846,7 @@ protected function getColumnSqlDefinition(Column $column) return $def; } - + /** * Gets the MySQL Index Definition for an Index object. *