Browse Source

Fix composite primary key reflection in postgres.

Reflecting composite keys that use serial columns should behave
correctly, marking the serial column as autoIncrement.
Mark Story 11 years ago
parent
commit
ae1560a6a1

+ 8 - 3
src/Database/Schema/PostgresSchema.php

@@ -139,6 +139,10 @@ class PostgresSchema extends BaseSchema
                 $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 @@ class PostgresSchema extends BaseSchema
             // 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);

+ 28 - 0
tests/TestCase/Database/Schema/PostgresSchemaTest.php

@@ -346,6 +346,34 @@ SQL;
     }
 
     /**
+     * Test describing a table with postgres and composite keys
+     *
+     * @return void
+     */
+    public function testDescribeTableCompositeKey()
+    {
+        $this->_needsConnection();
+        $connection = ConnectionManager::get('test');
+        $sql = <<<SQL
+CREATE TABLE schema_composite (
+    "id" SERIAL,
+    "site_id" INTEGER NOT NULL,
+    "name" VARCHAR(255),
+    PRIMARY KEY("id", "site_id")
+);
+SQL;
+        $connection->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
      *
      * @return void

+ 2 - 2
tests/TestCase/ORM/TableTest.php

@@ -2004,10 +2004,10 @@ class TableTest extends TestCase
     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);
     }
 
     /**