Skip to content

Commit

Permalink
Generated SQL should not contain multi-column primary keys
Browse files Browse the repository at this point in the history
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
  • Loading branch information
markstory committed Jul 28, 2012
1 parent 99813e9 commit 27e2132
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
15 changes: 14 additions & 1 deletion lib/Cake/Model/Datasource/DboSource.php
Expand Up @@ -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') {
Expand Down
39 changes: 39 additions & 0 deletions lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php
Expand Up @@ -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
Expand Down

0 comments on commit 27e2132

Please sign in to comment.