From ae1560a6a17f118bd463bd1540bf2e8212bebb54 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Wed, 4 Mar 2015 23:33:12 -0500 Subject: [PATCH] Fix composite primary key reflection in postgres. Reflecting composite keys that use serial columns should behave correctly, marking the serial column as autoIncrement. --- src/Database/Schema/PostgresSchema.php | 11 ++++++-- .../Database/Schema/PostgresSchemaTest.php | 28 +++++++++++++++++++ tests/TestCase/ORM/TableTest.php | 4 +-- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/Database/Schema/PostgresSchema.php b/src/Database/Schema/PostgresSchema.php index 7a503cab4f8..11f5b234f57 100644 --- a/src/Database/Schema/PostgresSchema.php +++ b/src/Database/Schema/PostgresSchema.php @@ -139,6 +139,10 @@ public function convertColumnDescription(Table $table, $row) $row['default'] = 0; } } + // Sniff out serial types. + if (in_array($field['type'], ['integer', 'biginteger']) && strpos($row['default'], 'nextval(') === 0) { + $field['autoIncrement'] = true; + } $field += [ 'default' => $this->_defaultValue($row['default']), 'null' => $row['null'] === 'YES' ? true : false, @@ -231,9 +235,10 @@ public function convertIndexDescription(Table $table, $row) // If there is only one column in the primary key and it is integery, // make it autoincrement. $columnDef = $table->column($columns[0]); - if (count($columns) === 1 && - in_array($columnDef['type'], ['integer', 'biginteger']) && - $type === Table::CONSTRAINT_PRIMARY + if ( + $type === Table::CONSTRAINT_PRIMARY && + count($columns) === 1 && + in_array($columnDef['type'], ['integer', 'biginteger']) ) { $columnDef['autoIncrement'] = true; $table->addColumn($columns[0], $columnDef); diff --git a/tests/TestCase/Database/Schema/PostgresSchemaTest.php b/tests/TestCase/Database/Schema/PostgresSchemaTest.php index 2325357da82..49478866617 100644 --- a/tests/TestCase/Database/Schema/PostgresSchemaTest.php +++ b/tests/TestCase/Database/Schema/PostgresSchemaTest.php @@ -345,6 +345,34 @@ public function testDescribeTable() } } + /** + * Test describing a table with postgres and composite keys + * + * @return void + */ + public function testDescribeTableCompositeKey() + { + $this->_needsConnection(); + $connection = ConnectionManager::get('test'); + $sql = <<execute($sql); + $schema = new SchemaCollection($connection); + $result = $schema->describe('schema_composite'); + $connection->execute('DROP TABLE schema_composite'); + + $this->assertEquals(['id', 'site_id'], $result->primaryKey()); + $this->assertNull($result->column('site_id')['autoIncrement'], 'site_id should not be autoincrement'); + $this->assertTrue($result->column('id')['autoIncrement'], 'id should be autoincrement'); + } + + /** * Test describing a table containing defaults with Postgres * diff --git a/tests/TestCase/ORM/TableTest.php b/tests/TestCase/ORM/TableTest.php index 8cfce2ac3da..9bcacb13299 100644 --- a/tests/TestCase/ORM/TableTest.php +++ b/tests/TestCase/ORM/TableTest.php @@ -2004,10 +2004,10 @@ public function testSaveNewErrorCompositeKeyNoIncrement() public function testSaveNewCompositeKeyIncrement() { $articles = TableRegistry::get('SiteAuthors'); - $article = $articles->newEntity(['site_id' => 1, 'name' => 'new guy']); + $article = $articles->newEntity(['site_id' => 3, 'name' => 'new guy']); $this->assertSame($article, $articles->save($article)); $this->assertNotEmpty($article->id, 'Primary key should have been populated'); - $this->assertSame(1, $article->site_id); + $this->assertSame(3, $article->site_id); } /**