mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
Adding indexes to alterSchema() and CakeSchema::compare(). Thanks for the test case and patch 'bamyers99'. Fixes #5862
git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@7910 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
parent
2d9f2c5ac8
commit
d405d1d1c3
3 changed files with 195 additions and 5 deletions
|
@ -536,9 +536,14 @@ class DboMysql extends DboSource {
|
|||
$out = '';
|
||||
$colList = array();
|
||||
foreach ($compare as $curTable => $types) {
|
||||
$indexes = array();
|
||||
if (!$table || $table == $curTable) {
|
||||
$out .= 'ALTER TABLE ' . $this->fullTableName($curTable) . " \n";
|
||||
foreach ($types as $type => $column) {
|
||||
if (isset($column['indexes'])) {
|
||||
$indexes[$type] = $column['indexes'];
|
||||
unset($column['indexes']);
|
||||
}
|
||||
switch ($type) {
|
||||
case 'add':
|
||||
foreach ($column as $field => $col) {
|
||||
|
@ -566,6 +571,7 @@ class DboMysql extends DboSource {
|
|||
break;
|
||||
}
|
||||
}
|
||||
$colList = array_merge($colList, $this->_alterIndexes($curTable, $indexes));
|
||||
$out .= "\t" . join(",\n\t", $colList) . ";\n\n";
|
||||
}
|
||||
}
|
||||
|
@ -592,5 +598,46 @@ class DboMysql extends DboSource {
|
|||
}
|
||||
return $out;
|
||||
}
|
||||
/**
|
||||
* Generate MySQL index alteration statements for a table.
|
||||
*
|
||||
* @param string $table Table to alter indexes for
|
||||
* @param array $new Indexes to add and drop
|
||||
* @return array Index alteration statements
|
||||
*/
|
||||
function _alterIndexes($table, $indexes) {
|
||||
$alter = array();
|
||||
if (isset($indexes['drop'])) {
|
||||
foreach($indexes['drop'] as $name => $value) {
|
||||
$out = 'DROP ';
|
||||
if ($name == 'PRIMARY') {
|
||||
$out .= 'PRIMARY KEY';
|
||||
} else {
|
||||
$out .= 'KEY ' . $name;
|
||||
}
|
||||
$alter[] = $out;
|
||||
}
|
||||
}
|
||||
if (isset($indexes['add'])) {
|
||||
foreach ($indexes['add'] as $name => $value) {
|
||||
$out = 'ADD ';
|
||||
if ($name == 'PRIMARY') {
|
||||
$out .= 'PRIMARY ';
|
||||
$name = null;
|
||||
} else {
|
||||
if (!empty($value['unique'])) {
|
||||
$out .= 'UNIQUE ';
|
||||
}
|
||||
}
|
||||
if (is_array($value['column'])) {
|
||||
$out .= 'KEY '. $name .' (' . join(', ', array_map(array(&$this, 'name'), $value['column'])) . ')';
|
||||
} else {
|
||||
$out .= 'KEY '. $name .' (' . $this->name($value['column']) . ')';
|
||||
}
|
||||
$alter[] = $out;
|
||||
}
|
||||
}
|
||||
return $alter;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -407,7 +407,7 @@ class CakeSchema extends Object {
|
|||
foreach ($fields as $field => $value) {
|
||||
if (isset($old[$table][$field])) {
|
||||
$diff = array_diff_assoc($value, $old[$table][$field]);
|
||||
if (!empty($diff)) {
|
||||
if (!empty($diff) && $field !== 'indexes') {
|
||||
$tables[$table]['change'][$field] = array_merge($old[$table][$field], $diff);
|
||||
}
|
||||
}
|
||||
|
@ -421,6 +421,14 @@ class CakeSchema extends Object {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($old[$table]['indexes']) && isset($new[$table]['indexes'])) {
|
||||
$diff = $this->_compareIndexes($new[$table]['indexes'], $old[$table]['indexes']);
|
||||
if ($diff) {
|
||||
$tables[$table]['drop']['indexes'] = $diff['drop'];
|
||||
$tables[$table]['add']['indexes'] = $diff['add'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
@ -487,5 +495,55 @@ class CakeSchema extends Object {
|
|||
|
||||
return $columns;
|
||||
}
|
||||
/**
|
||||
* Compare two schema indexes
|
||||
*
|
||||
* @param array $new New indexes
|
||||
* @param array $old Old indexes
|
||||
* @return mixed false on failure or array of indexes to add and drop
|
||||
*/
|
||||
function _compareIndexes($new, $old) {
|
||||
if (!is_array($new) || !is_array($old)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$add = $drop = array();
|
||||
|
||||
$diff = array_diff_assoc($new, $old);
|
||||
if (!empty($diff)) {
|
||||
$add = $diff;
|
||||
}
|
||||
|
||||
$diff = array_diff_assoc($old, $new);
|
||||
if (!empty($diff)) {
|
||||
$drop = $diff;
|
||||
}
|
||||
|
||||
foreach ($new as $name => $value) {
|
||||
if (isset($old[$name])) {
|
||||
$newUnique = isset($value['unique']) ? $value['unique'] : 0;
|
||||
$oldUnique = isset($old[$name]['unique']) ? $old[$name]['unique'] : 0;
|
||||
$newColumn = $value['column'];
|
||||
$oldColumn = $old[$name]['column'];
|
||||
|
||||
$diff = false;
|
||||
|
||||
if ($newUnique != $oldUnique) {
|
||||
$diff = true;
|
||||
} elseif (is_array($newColumn) && is_array($oldColumn)) {
|
||||
$diff = ($newColumn !== $oldColumn);
|
||||
} elseif (is_string($newColumn) && is_string($oldColumn)) {
|
||||
$diff = ($newColumn != $oldColumn);
|
||||
} else {
|
||||
$diff = true;
|
||||
}
|
||||
if ($diff) {
|
||||
$drop[$name] = null;
|
||||
$add[$name] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array_filter(compact('add', 'drop'));
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -22,10 +22,6 @@
|
|||
* @lastmodified $Date$
|
||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||
*/
|
||||
|
||||
if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) {
|
||||
define('CAKEPHP_UNIT_TEST_EXECUTION', 1);
|
||||
}
|
||||
App::import('Core', array('Model', 'DataSource', 'DboSource', 'DboMysql'));
|
||||
|
||||
/**
|
||||
|
@ -190,6 +186,23 @@ class DboMysqlTest extends CakeTestCase {
|
|||
function tearDown() {
|
||||
unset($this->db);
|
||||
}
|
||||
/**
|
||||
* startCase
|
||||
*
|
||||
* @return void
|
||||
**/
|
||||
function startCase() {
|
||||
$this->_debug = Configure::read('debug');
|
||||
Configure::write('debug', 1);
|
||||
}
|
||||
/**
|
||||
* endCase
|
||||
*
|
||||
* @return void
|
||||
**/
|
||||
function endCase() {
|
||||
Configure::write('debug', $this->_debug);
|
||||
}
|
||||
/**
|
||||
* Test Dbo value method
|
||||
*
|
||||
|
@ -395,6 +408,78 @@ class DboMysqlTest extends CakeTestCase {
|
|||
$expected = 'float';
|
||||
$this->assertEqual($result, $expected);
|
||||
}
|
||||
/**
|
||||
* testAlterSchemaIndexes method
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function testAlterSchemaIndexes() {
|
||||
App::import('Core', 'Schema');
|
||||
$this->db->cacheSources = $this->db->testing = false;
|
||||
|
||||
$schema1 =& new CakeSchema(array(
|
||||
'name' => 'AlterTest1',
|
||||
'connection' => 'test_suite',
|
||||
'altertest' => array(
|
||||
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
|
||||
'name' => array('type' => 'string', 'null' => false, 'length' => 50),
|
||||
'group1' => array('type' => 'integer', 'null' => true),
|
||||
'group2' => array('type' => 'integer', 'null' => true)
|
||||
)));
|
||||
$this->db->query($this->db->createSchema($schema1));
|
||||
|
||||
$schema2 =& new CakeSchema(array(
|
||||
'name' => 'AlterTest2',
|
||||
'connection' => 'test_suite',
|
||||
'altertest' => array(
|
||||
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
|
||||
'name' => array('type' => 'string', 'null' => false, 'length' => 50),
|
||||
'group1' => array('type' => 'integer', 'null' => true),
|
||||
'group2' => array('type' => 'integer', 'null' => true),
|
||||
'indexes' => array(
|
||||
'name_idx' => array('column' => 'name', 'unique' => 0),
|
||||
'group_idx' => array('column' => 'group1', 'unique' => 0),
|
||||
'compound_idx' => array('column' => array('group1', 'group2'), 'unique' => 0),
|
||||
'PRIMARY' => array('column' => 'id', 'unique' => 1))
|
||||
)));
|
||||
$this->db->query($this->db->alterSchema($schema2->compare($schema1)));
|
||||
|
||||
$indexes = $this->db->index('altertest');
|
||||
$this->assertEqual($schema2->tables['altertest']['indexes'], $indexes);
|
||||
|
||||
// Change three indexes, delete one and add another one
|
||||
$schema3 =& new CakeSchema(array(
|
||||
'name' => 'AlterTest3',
|
||||
'connection' => 'test_suite',
|
||||
'altertest' => array(
|
||||
'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
|
||||
'name' => array('type' => 'string', 'null' => false, 'length' => 50),
|
||||
'group1' => array('type' => 'integer', 'null' => true),
|
||||
'group2' => array('type' => 'integer', 'null' => true),
|
||||
'indexes' => array(
|
||||
'name_idx' => array('column' => 'name', 'unique' => 1),
|
||||
'group_idx' => array('column' => 'group2', 'unique' => 0),
|
||||
'compound_idx' => array('column' => array('group2', 'group1'), 'unique' => 0),
|
||||
'id_name_idx' => array('column' => array('id', 'name'), 'unique' => 0))
|
||||
)));
|
||||
|
||||
$this->db->query($this->db->alterSchema($schema3->compare($schema2)));
|
||||
|
||||
$indexes = $this->db->index('altertest');
|
||||
$this->assertEqual($schema3->tables['altertest']['indexes'], $indexes);
|
||||
|
||||
// Compare us to ourself.
|
||||
$this->assertEqual($schema3->compare($schema3), array());
|
||||
|
||||
// Drop the indexes
|
||||
$this->db->query($this->db->alterSchema($schema1->compare($schema3)));
|
||||
|
||||
$indexes = $this->db->index('altertest');
|
||||
$this->assertEqual(array(), $indexes);
|
||||
|
||||
$this->db->query($this->db->dropSchema($schema1));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
Loading…
Reference in a new issue