Skip to content

Commit

Permalink
Add support for indexes with multiple fields. Fixed #1
Browse files Browse the repository at this point in the history
  • Loading branch information
odan committed Sep 20, 2016
1 parent 1cc6bfe commit 883a187
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 29 deletions.
7 changes: 6 additions & 1 deletion src/Migration/Adapter/Database/MySqlAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,12 @@ public function getIndexes($tableName)
$rows = $this->pdo->query($sql)->fetchAll();
$result = [];
foreach ($rows as $row) {
if (isset($row['cardinality'])) {
unset($row['cardinality']);
}
$name = $row['key_name'];
$result[$name] = $row;
$seq = $row['seq_in_index'];
$result[$name][$seq] = $row;
}
return $result;
}
Expand Down Expand Up @@ -278,4 +282,5 @@ public function quote($value)
}
return $this->pdo->quote($value);
}

}
131 changes: 104 additions & 27 deletions src/Migration/Adapter/Generator/PhinxMySqlGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public function __construct(MySqlAdapter $dba, OutputInterface $output, $options
* @param array $diffs
* @return string PHP code
*/
public function createMigration($name, $diffs)
public function createMigration($name, $newSchema, $oldSchema)
{
$output = array();
$output[] = '<?php';
Expand All @@ -93,7 +93,7 @@ public function createMigration($name, $diffs)
$output[] = '';
$output[] = sprintf('class %s extends AbstractMigration', $name);
$output[] = '{';
$output = $this->addChangeMethod($output, $diffs[0], $diffs[1]);
$output = $this->addChangeMethod($output, $newSchema, $oldSchema);
$output[] = '}';
$output[] = '';
$result = implode($this->nl, $output);
Expand Down Expand Up @@ -133,10 +133,10 @@ public function getTableMigration($output, $new, $old)
}

if (!empty($new['database'])) {
if (isset($new['database']['default_character_set_name'])) {
if ($this->neq($new, $old, ['database', 'default_character_set_name'])) {
$output[] = $this->getAlterDatabaseCharset($new['database']['default_character_set_name']);
}
if (isset($new['database']['default_collation_name'])) {
if ($this->neq($new, $old, ['database', 'default_collation_name'])) {
$output[] = $this->getAlterDatabaseCollate($new['database']['default_collation_name']);
}
}
Expand All @@ -150,41 +150,47 @@ public function getTableMigration($output, $new, $old)
// create the table
$output[] = $this->getCreateTable($tableName);
}
if (isset($table['table']['engine'])) {
if ($this->neq($new, $old, ['tables', $tableName, 'table', 'engine'])) {
$output[] = $this->getAlterTableEngine($tableName, $table['table']['engine']);
}
if (isset($table['table']['table_comment'])) {
if ($this->neq($new, $old, ['tables', $tableName, 'table', 'table_comment'])) {
$output[] = $this->getAlterTableComment($tableName, $table['table']['table_comment']);
}
if (isset($table['table']['character_set_name'])) {
if ($this->neq($new, $old, ['tables', $tableName, 'table', 'character_set_name'])) {
$output[] = $this->getAlterTableCharset($tableName, $table['table']['character_set_name']);
}
if (isset($table['table']['table_collation'])) {
if ($this->neq($new, $old, ['tables', $tableName, 'table', 'table_collation'])) {
$output[] = $this->getAlterTableCollate($tableName, $table['table']['table_collation']);
}

if (!empty($table['columns'])) {
foreach ($table['columns'] as $columnName => $columnData) {
if (!isset($old['tables'][$tableName]['columns'][$columnName])) {
$output[] = $this->getColumnCreate($tableName, $columnName, $columnData);
$output[] = $this->getColumnCreate($new, $tableName, $columnName, $columnData);
} else {
$output[] = $this->getColumnUpdate($tableName, $columnName, $columnData);
if ($this->neq($new, $old, ['tables', $tableName, 'columns', $columnName])) {
$output[] = $this->getColumnUpdate($new, $tableName, $columnName, $columnData);
}
}
}
}

if (!empty($old['tables'][$tableName]['columns'])) {
foreach ($old['tables'][$tableName]['columns'] as $oldColumnName => $oldColumnData) {
$output[] = $this->getColumnRemove($tableName, $oldColumnName);
if (!isset($new['tables'][$tableName]['columns'][$oldColumnName])) {
$output[] = $this->getColumnRemove($tableName, $oldColumnName);
}
}
}

if (!empty($table['indexes'])) {
foreach ($table['indexes'] as $indexName => $indexData) {
foreach ($table['indexes'] as $indexName => $indexSequences) {
if (!isset($old['tables'][$tableName]['indexes'][$indexName])) {
$output[] = $this->getIndexCreate($tableName, $indexName, $indexData);
$output[] = $this->getIndexCreate($new, $tableName, $indexName);
} else {
$output[] = $this->getIndexRemove($tableName, $indexName, $indexData);
if ($this->neq($new, $old, ['tables', $tableName, 'indexes', $indexName])) {
$output[] = $this->getIndexCreate($new, $tableName, $indexName);
}
}
}
}
Expand All @@ -201,6 +207,14 @@ public function getTableMigration($output, $new, $old)
if ($tableName == 'phinxlog') {
continue;
}

if (!empty($old['tables'][$tableName]['indexes'])) {
foreach ($old['tables'][$tableName]['indexes'] as $indexName => $indexSequences) {
if (!isset($new['tables'][$tableName]['indexes'][$indexName])) {
$output[] = $this->getIndexRemove($tableName, $indexName);
}
}
}
if (!isset($new['tables'][$tableName])) {
$output[] = $this->getDropTable($tableName);
}
Expand Down Expand Up @@ -375,14 +389,14 @@ protected function getAlterTableComment($table, $comment)
/**
* Generate column create.
*
* @param array $schema
* @param string $table
* @param string $columnName
* @param string $columnData
* @return string
*/
protected function getColumnCreate($table, $columnName, $columnData)
protected function getColumnCreate($schema, $table, $columnName)
{
$columns = $this->dba->getColumns($table);
$columns = $schema['tables'][$table]['columns'];
$columnData = $columns[$columnName];
$phinxType = $this->getPhinxColumnType($columnData);
$columnAttributes = $this->getPhinxColumnOptions($phinxType, $columnData, $columns);
Expand All @@ -405,14 +419,14 @@ protected function getColumnCreate($table, $columnName, $columnData)
/**
* Generate column update.
*
* @param array $schema
* @param string $table
* @param string $columnName
* @param string $columnData
* @return string
*/
protected function getColumnUpdate($table, $columnName, $columnData)
protected function getColumnUpdate($schema, $table, $columnName)
{
$columns = $this->dba->getColumns($table);
$columns = $schema['tables'][$table]['columns'];
$columnData = $columns[$columnName];

$phinxType = $this->getPhinxColumnType($columnData);
Expand Down Expand Up @@ -699,31 +713,48 @@ public function getColumnLimit($columnData)
/**
* Generate index create.
*
* @param array $schema
* @param string $table
* @param string $indexName
* @param array $indexData
* @return string
*/
protected function getIndexCreate($table, $indexName, $indexData)
protected function getIndexCreate($schema, $table, $indexName)
{
if ($indexName == 'PRIMARY') {
return '';
}
if (isset($indexData['column_name'])) {
$indexName = $indexData['column_name'];
}
$indexOptions = $this->getIndexOptions($indexData);
$indexes = $schema['tables'][$table]['indexes'];
$indexSequences = $indexes[$indexName];

$indexFields = $this->getIndexFields($indexSequences);
$indexOptions = $this->getIndexOptions(array_values($indexSequences)[0]);

$output = [];
$output[] = sprintf("%sif(\$this->table('%s')->hasIndex('%s')) {", $this->ind2, $table, $indexName);
$output[] = sprintf("%s%s", $this->ind, $this->getIndexRemove($table, $indexName));
$output[] = sprintf("%s}", $this->ind2);
$output[] = sprintf("%s\$this->table(\"%s\")->addIndex('%s', %s)->save();", $this->ind2, $table, $indexName, $indexOptions);
$output[] = sprintf("%s\$this->table(\"%s\")->addIndex(%s, %s)->save();", $this->ind2, $table, $indexFields, $indexOptions);

$result = implode($this->nl, $output);
return $result;
}

/**
* Get index fields.
*
* @param array $indexSequences
* @return string
*/
public function getIndexFields($indexSequences)
{
$indexFields = array();
foreach ($indexSequences as $indexData) {
$indexFields[] = $indexData['column_name'];
}
$result = "array('" . implode("','", $indexFields) . "')";
return $result;
}

/**
* Generate index options.
*
Expand Down Expand Up @@ -865,4 +896,50 @@ protected function getSetUniqueChecks($value)
return sprintf("%s\$this->execute(\"SET UNIQUE_CHECKS = %s;\");", $this->ind2, $value);
}

/**
* Compare array
*
* @param array $arr
* @param array $arr2
* @param array $keys
* @return bool
*/
protected function eq($arr, $arr2, $keys)
{
$val1 = $this->find($arr, $keys);
$val2 = $this->find($arr2, $keys);
return $val1 === $val2;
}

/**
* Compare array (not)
*
* @param array $arr
* @param array $arr2
* @param array $keys
* @return bool
*/
protected function neq($arr, $arr2, $key)
{
return !$this->eq($arr, $arr2, $key);
}

/**
* Get array value by keys.
*
* @param array $array
* @param array $parts
* @return mixed
*/
protected function find($array, $parts)
{
foreach ($parts as $part) {
if (!array_key_exists($part, $array)) {
return null;
}
$array = $array[$part];
}
return $array;
}

}
3 changes: 2 additions & 1 deletion src/Migration/Generator/MigrationGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public function generate()
return false;
}
$name = $this->createName($name);
$migration = $this->generator->createMigration($name, $diffs);
$migration = $this->generator->createMigration($name, $schema, $oldSchema);
$this->saveMigrationFile($name, $migration);

// Overwrite schema file
Expand Down Expand Up @@ -323,4 +323,5 @@ protected function createName($name)
{
return str_replace(' ', '', ucwords($name));
}

}

0 comments on commit 883a187

Please sign in to comment.