Merge pull request #2752 from rchavik/2.4-postgres-alterschema

Fix: Changing boolean to integer for Postgres
This commit is contained in:
Mark Story 2014-01-31 06:46:52 -08:00
commit 405f3a1cb9
2 changed files with 42 additions and 2 deletions

View file

@ -528,14 +528,17 @@ class Postgres extends DboSource {
} }
break; break;
case 'change': case 'change':
$schema = $this->describe($curTable);
foreach ($column as $field => $col) { foreach ($column as $field => $col) {
if (!isset($col['name'])) { if (!isset($col['name'])) {
$col['name'] = $field; $col['name'] = $field;
} }
$original = $schema[$field];
$fieldName = $this->name($field); $fieldName = $this->name($field);
$default = isset($col['default']) ? $col['default'] : null; $default = isset($col['default']) ? $col['default'] : null;
$nullable = isset($col['null']) ? $col['null'] : null; $nullable = isset($col['null']) ? $col['null'] : null;
$boolToInt = $original['type'] == 'boolean' && $col['type'] == 'integer';
unset($col['default'], $col['null']); unset($col['default'], $col['null']);
if ($field !== $col['name']) { if ($field !== $col['name']) {
$newName = $this->name($col['name']); $newName = $this->name($col['name']);
@ -543,14 +546,23 @@ class Postgres extends DboSource {
$out .= 'ALTER TABLE ' . $this->fullTableName($curTable) . " \n"; $out .= 'ALTER TABLE ' . $this->fullTableName($curTable) . " \n";
$fieldName = $newName; $fieldName = $newName;
} }
$colList[] = 'ALTER COLUMN ' . $fieldName . ' TYPE ' . str_replace(array($fieldName, 'NOT NULL'), '', $this->buildColumn($col));
if ($boolToInt) {
$colList[] = 'ALTER COLUMN ' . $fieldName . ' SET DEFAULT NULL';
$colList[] = 'ALTER COLUMN ' . $fieldName . ' TYPE ' . str_replace(array($fieldName, 'NOT NULL'), '', $this->buildColumn($col)) . ' USING CASE WHEN TRUE THEN 1 ELSE 0 END';
} else {
$colList[] = 'ALTER COLUMN ' . $fieldName . ' TYPE ' . str_replace(array($fieldName, 'NOT NULL'), '', $this->buildColumn($col));
}
if (isset($nullable)) { if (isset($nullable)) {
$nullable = ($nullable) ? 'DROP NOT NULL' : 'SET NOT NULL'; $nullable = ($nullable) ? 'DROP NOT NULL' : 'SET NOT NULL';
$colList[] = 'ALTER COLUMN ' . $fieldName . ' ' . $nullable; $colList[] = 'ALTER COLUMN ' . $fieldName . ' ' . $nullable;
} }
if (isset($default)) { if (isset($default)) {
$colList[] = 'ALTER COLUMN ' . $fieldName . ' SET DEFAULT ' . $this->value($default, $col['type']); if (!$boolToInt) {
$colList[] = 'ALTER COLUMN ' . $fieldName . ' SET DEFAULT ' . $this->value($default, $col['type']);
}
} else { } else {
$colList[] = 'ALTER COLUMN ' . $fieldName . ' DROP DEFAULT'; $colList[] = 'ALTER COLUMN ' . $fieldName . ' DROP DEFAULT';
} }

View file

@ -695,6 +695,34 @@ class PostgresTest extends CakeTestCase {
$this->assertNotRegExp('/varchar\(36\) NOT NULL/i', $result); $this->assertNotRegExp('/varchar\(36\) NOT NULL/i', $result);
} }
/**
* Test the alterSchema changing boolean to integer
*
* @return void
*/
public function testAlterSchemaBooleanToIntegerField() {
$default = array(
'connection' => 'test',
'name' => 'BoolField',
'bool_fields' => array(
'id' => array('type' => 'integer', 'key' => 'primary'),
'name' => array('type' => 'string', 'length' => 50),
'active' => array('type' => 'boolean', 'null' => false),
)
);
$Old = new CakeSchema($default);
$result = $this->Dbo->query($this->Dbo->createSchema($Old));
$this->assertTrue($result);
$modified = $default;
$modified['bool_fields']['active'] = array('type' => 'integer', 'null' => true);
$New = new CakeSchema($modified);
$query = $this->Dbo->alterSchema($New->compare($Old));
$result = $this->Dbo->query($query);
$this->Dbo->query($this->Dbo->dropSchema($Old));
}
/** /**
* Test the alter index capabilities of postgres * Test the alter index capabilities of postgres
* *