Skip to content

Commit

Permalink
Fix default values in postgres.
Browse files Browse the repository at this point in the history
Postgres returns additional data that is not helpful when building
entities or rebuilding schema.

Refs #4398
  • Loading branch information
markstory committed Aug 31, 2014
1 parent 92627d1 commit a6eff18
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 5 deletions.
32 changes: 29 additions & 3 deletions src/Database/Schema/PostgresSchema.php
Expand Up @@ -135,16 +135,41 @@ public function convertColumnDescription(Table $table, $row) {
$row['default'] = 0;
}
}

$field += [
'default' => $this->_defaultValue($row['default']),
'null' => $row['null'] === 'YES' ? true : false,
'default' => $row['default'],
'comment' => $row['comment']
];
$field['length'] = $row['char_length'] ?: $field['length'];
$table->addColumn($row['name'], $field);
}

/**
* Manipulate the default value.
*
* Postgres includes sequence data and casting information in default values.
* We need to remove those.
*
* @param string $default The default value.
* @return string
*/
protected function _defaultValue($default) {
if (is_numeric($default) || $default === null) {
return $default;
}
// Sequences
if (strpos($default, 'nextval') === 0) {
return null;
}

// Remove quotes and postgres casts
return preg_replace(
"/^'(.*)'(?:::.*)$/",
"$1",
$default
);
}

/**
* {@inheritDoc}
*/
Expand Down Expand Up @@ -201,7 +226,8 @@ public function convertIndexDescription(Table $table, $row) {
$columnDef = $table->column($columns[0]);
if (
count($columns) === 1 &&
in_array($columnDef['type'], ['integer', 'biginteger'])
in_array($columnDef['type'], ['integer', 'biginteger']) &&
$type === Table::CONSTRAINT_PRIMARY
) {
$columnDef['autoIncrement'] = true;
$table->addColumn($columns[0], $columnDef);
Expand Down
68 changes: 66 additions & 2 deletions tests/TestCase/Database/Schema/PostgresSchemaTest.php
Expand Up @@ -51,9 +51,9 @@ protected function _createTables($connection) {
$table = <<<SQL
CREATE TABLE schema_authors (
id SERIAL,
name VARCHAR(50),
name VARCHAR(50) DEFAULT 'bob',
bio DATE,
position INT,
position INT DEFAULT 1,
created TIMESTAMP,
PRIMARY KEY (id),
CONSTRAINT "unique_position" UNIQUE ("position")
Expand Down Expand Up @@ -337,6 +337,70 @@ public function testDescribeTable() {
}
}

/**
* Test describing a table containing defaults with Postgres
*
* @return void
*/
public function testDescribeTableWithDefaults() {
$connection = ConnectionManager::get('test');
$this->_createTables($connection);

$schema = new SchemaCollection($connection);
$result = $schema->describe('schema_authors');
$expected = [
'id' => [
'type' => 'integer',
'null' => false,
'default' => null,
'length' => 10,
'precision' => null,
'unsigned' => null,
'comment' => null,
'autoIncrement' => true,
],
'name' => [
'type' => 'string',
'null' => true,
'default' => 'bob',
'length' => 50,
'precision' => null,
'comment' => null,
'fixed' => null,
],
'bio' => [
'type' => 'date',
'null' => true,
'default' => null,
'length' => null,
'precision' => null,
'comment' => null,
],
'position' => [
'type' => 'integer',
'null' => true,
'default' => '1',
'length' => 10,
'precision' => null,
'comment' => null,
'unsigned' => null,
'autoIncrement' => null,
],
'created' => [
'type' => 'timestamp',
'null' => true,
'default' => null,
'length' => null,
'precision' => null,
'comment' => null,
],
];
$this->assertEquals(['id'], $result->primaryKey());
foreach ($expected as $field => $definition) {
$this->assertEquals($definition, $result->column($field), "Mismatch in $field column");
}
}

/**
* Test describing a table with containing keywords
*
Expand Down

0 comments on commit a6eff18

Please sign in to comment.