From 27e2132a1341adeb93f98bfed877f758545f4bcd Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 27 Jul 2012 22:31:49 -0400 Subject: [PATCH] Generated SQL should not contain multi-column primary keys While totally valid in databases, the Schema system is not designed to handle multi-column primary keys in a sane way. In MySQL this results in two auto_increment columns, and in postgres this results in two serial columns. Fixes #3069 --- lib/Cake/Model/Datasource/DboSource.php | 15 ++++++- .../Model/Datasource/Database/MysqlTest.php | 39 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php index ce19daa2910..bc3d7eb2ce9 100644 --- a/lib/Cake/Model/Datasource/DboSource.php +++ b/lib/Cake/Model/Datasource/DboSource.php @@ -2953,11 +2953,24 @@ public function createSchema($schema, $tableName = null) { $primary = null; $table = $this->fullTableName($curTable); + $primaryCount = 0; + foreach ($columns as $col) { + if (isset($col['key']) && $col['key'] === 'primary') { + $primaryCount++; + } + } + foreach ($columns as $name => $col) { if (is_string($col)) { $col = array('type' => $col); } - if (isset($col['key']) && $col['key'] === 'primary') { + $isPrimary = isset($col['key']) && $col['key'] === 'primary'; + // Multi-column primary keys are not supported. + if ($isPrimary && $primaryCount > 1) { + unset($col['key']); + $isPrimary = false; + } + if ($isPrimary) { $primary = $name; } if ($name !== 'indexes' && $name !== 'tableParameters') { diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php index dcd9aefe1e0..c6645a3c5e4 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php @@ -838,6 +838,45 @@ public function testDescribeGettingFieldParameters() { $this->assertEquals('Test Comment', $result['other_col']['comment']); } +/** + * Test that two columns with key => primary doesn't create invalid sql. + * + * @return void + */ + public function testTwoColumnsWithPrimaryKey() { + $schema = new CakeSchema(array( + 'connection' => 'test', + 'roles_users' => array( + 'role_id' => array( + 'type' => 'integer', + 'null' => false, + 'default' => null, + 'key' => 'primary' + ), + 'user_id' => array( + 'type' => 'integer', + 'null' => false, + 'default' => null, + 'key' => 'primary' + ), + 'indexes' => array( + 'user_role_index' => array( + 'column' => array('role_id', 'user_id'), + 'unique' => 1 + ), + 'user_index' => array( + 'column' => 'user_id', + 'unique' => 0 + ) + ), + ) + )); + + $result = $this->Dbo->createSchema($schema); + $this->assertContains('`role_id` int(11) NOT NULL,', $result); + $this->assertContains('`user_id` int(11) NOT NULL,', $result); + } + /** * Tests that listSources method sends the correct query and parses the result accordingly * @return void