mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
Adding alterSchema() to dbo_postgres. Also handles index alters. Tests added for field and index alter sql.
git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@7923 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
parent
48c65c4092
commit
ea9c080b1c
2 changed files with 233 additions and 1 deletions
|
@ -446,7 +446,7 @@ class DboPostgres extends DboSource {
|
|||
AND n.nspname ~ '^(" . $this->config['schema'] . ")$'
|
||||
)
|
||||
AND c.oid = i.indrelid AND i.indexrelid = c2.oid
|
||||
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname");
|
||||
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname", false);
|
||||
foreach ($indexes as $i => $info) {
|
||||
$key = array_pop($info);
|
||||
if ($key['indisprimary']) {
|
||||
|
@ -464,6 +464,119 @@ class DboPostgres extends DboSource {
|
|||
}
|
||||
return $index;
|
||||
}
|
||||
/**
|
||||
* Alter the Schema of a table.
|
||||
*
|
||||
* @param array $compare Results of CakeSchema::compare()
|
||||
* @param string $table name of the table
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
function alterSchema($compare, $table = null) {
|
||||
if (!is_array($compare)) {
|
||||
return false;
|
||||
}
|
||||
$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) {
|
||||
$col['name'] = $field;
|
||||
$alter = 'ADD COLUMN '.$this->buildColumn($col);
|
||||
if (isset($col['after'])) {
|
||||
$alter .= ' AFTER '. $this->name($col['after']);
|
||||
}
|
||||
$colList[] = $alter;
|
||||
}
|
||||
break;
|
||||
case 'drop':
|
||||
foreach ($column as $field => $col) {
|
||||
$col['name'] = $field;
|
||||
$colList[] = 'DROP COLUMN '.$this->name($field);
|
||||
}
|
||||
break;
|
||||
case 'change':
|
||||
foreach ($column as $field => $col) {
|
||||
if (!isset($col['name'])) {
|
||||
$col['name'] = $field;
|
||||
}
|
||||
$fieldName = $this->name($field);
|
||||
$colList[] = 'ALTER COLUMN '. $fieldName .' TYPE ' . str_replace($fieldName, '', $this->buildColumn($col));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isset($indexes['drop']['PRIMARY'])) {
|
||||
$colList[] = 'DROP CONSTRAINT ' . $curTable . '_pkey';
|
||||
}
|
||||
if (isset($indexes['add']['PRIMARY'])) {
|
||||
$cols = $indexes['add']['PRIMARY']['column'];
|
||||
if (is_array($cols)) {
|
||||
$cols = implode(', ', $cols);
|
||||
}
|
||||
$colList[] = 'ADD PRIMARY KEY (' . $cols . ')';
|
||||
}
|
||||
|
||||
if (!empty($colList)) {
|
||||
$out .= "\t" . join(",\n\t", $colList) . ";\n\n";
|
||||
} else {
|
||||
$out = '';
|
||||
}
|
||||
$out .= join(";\n\t", $this->_alterIndexes($curTable, $indexes)) . ";";
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
/**
|
||||
* Generate PostgreSQL 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') {
|
||||
continue;
|
||||
} else {
|
||||
$out .= 'INDEX ' . $name;
|
||||
}
|
||||
$alter[] = $out;
|
||||
}
|
||||
}
|
||||
if (isset($indexes['add'])) {
|
||||
foreach ($indexes['add'] as $name => $value) {
|
||||
$out = 'CREATE ';
|
||||
if ($name == 'PRIMARY') {
|
||||
continue;
|
||||
} else {
|
||||
if (!empty($value['unique'])) {
|
||||
$out .= 'UNIQUE ';
|
||||
}
|
||||
$out .= 'INDEX ';
|
||||
}
|
||||
if (is_array($value['column'])) {
|
||||
$out .= $name . ' ON ' . $table . ' (' . join(', ', array_map(array(&$this, 'name'), $value['column'])) . ')';
|
||||
} else {
|
||||
$out .= $name . ' ON ' . $table . ' (' . $this->name($value['column']) . ')';
|
||||
}
|
||||
$alter[] = $out;
|
||||
}
|
||||
}
|
||||
return $alter;
|
||||
}
|
||||
/**
|
||||
* Returns a limit statement in the correct format for the particular database.
|
||||
*
|
||||
|
|
|
@ -511,5 +511,124 @@ class DboPostgresTest extends CakeTestCase {
|
|||
$this->assertEqual($expected, $result);
|
||||
$this->db->query('DROP TABLE ' . $name);
|
||||
}
|
||||
/**
|
||||
* Test the alterSchema capabilities of postgres
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function testAlterSchema() {
|
||||
$Old =& new CakeSchema(array(
|
||||
'connection' => 'test_suite',
|
||||
'name' => 'AlterPosts',
|
||||
'alter_posts' => array(
|
||||
'id' => array('type' => 'integer', 'key' => 'primary'),
|
||||
'author_id' => array('type' => 'integer', 'null' => false),
|
||||
'title' => array('type' => 'string', 'null' => false),
|
||||
'body' => array('type' => 'text'),
|
||||
'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
|
||||
'created' => array('type' => 'datetime'),
|
||||
'updated' => array('type' => 'datetime'),
|
||||
)
|
||||
));
|
||||
$this->db->query($this->db->createSchema($Old));
|
||||
|
||||
$New =& new CakeSchema(array(
|
||||
'connection' => 'test_suite',
|
||||
'name' => 'AlterPosts',
|
||||
'alter_posts' => array(
|
||||
'id' => array('type' => 'integer', 'key' => 'primary'),
|
||||
'author_id' => array('type' => 'integer', 'null' => false),
|
||||
'title' => array('type' => 'string', 'null' => false),
|
||||
'body' => array('type' => 'string', 'length' => 500),
|
||||
'status' => array('type' => 'integer', 'length' => 3),
|
||||
'created' => array('type' => 'datetime'),
|
||||
'updated' => array('type' => 'datetime'),
|
||||
)
|
||||
));
|
||||
$this->db->query($this->db->alterSchema($New->compare($Old), 'alter_posts'));
|
||||
|
||||
$model = new CakeTestModel(array('table' => 'alter_posts', 'ds' => 'test_suite'));
|
||||
$result = $model->schema();
|
||||
$this->assertTrue(isset($result['status']));
|
||||
$this->assertFalse(isset($result['published']));
|
||||
$this->assertEqual($result['body']['type'], 'string');
|
||||
|
||||
$this->db->query($this->db->dropSchema($New));
|
||||
}
|
||||
/**
|
||||
* Test the alter index capabilities of postgres
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function testAlterIndexes() {
|
||||
$this->db->cacheSources = 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),
|
||||
'another_idx' => array('column' => array('group1', '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