Skip to content

Commit

Permalink
Merge pull request #743 from cakephp/fix-sqlite-constraint
Browse files Browse the repository at this point in the history
Disable foreign key checks when removing temp tables
  • Loading branch information
markstory authored Sep 9, 2024
2 parents 0716a4b + d8ac1b0 commit 2fb93e5
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/Db/Adapter/SqliteAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,15 @@ protected function copyAndDropTmpTable(AlterInstructions $instructions, string $
$state['selectColumns']
);

$result = $this->fetchRow('PRAGMA foreign_keys');
$foreignKeysEnabled = $result ? (bool)$result['foreign_keys'] : false;
if ($foreignKeysEnabled) {
$this->execute('PRAGMA foreign_keys = OFF');
}
$this->execute(sprintf('DROP TABLE %s', $this->quoteTableName($tableName)));
if ($foreignKeysEnabled) {
$this->execute('PRAGMA foreign_keys = ON');
}
$this->execute(sprintf(
'ALTER TABLE %s RENAME TO %s',
$this->quoteTableName($state['tmpTableName']),
Expand Down
1 change: 1 addition & 0 deletions src/Db/Table/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

/**
* @internal
* @TODO rename this to `TableMetadata` having two classes with very similar names is confusing for me.
*/
class Table
{
Expand Down
26 changes: 26 additions & 0 deletions tests/TestCase/Db/Adapter/SqliteAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1601,6 +1601,32 @@ public function testAddColumnWithComment()
$this->assertMatchesRegularExpression('/\/\* Comments from "column1" \*\//', $sql);
}

public function testAddColumnTableWithConstraint()
{
$this->adapter->execute('PRAGMA foreign_keys = ON');
$roles = new Table('constraint_roles', [], $this->adapter);
$roles->addColumn('name', 'string')
->save();
$users = new Table('constraint_users', [], $this->adapter);
$users->addColumn('username', 'string')
->addColumn('role_id', 'integer', ['null' => false])
->addForeignKey(['role_id'], $roles->getTable(), ['id'])
->save();

$this->adapter->insert($roles->getTable(), ['name' => 'admin']);
$this->adapter->insert($users->getTable(), ['username' => 'test', 'role_id' => 1]);

$updatedRoles = new Table($roles->getName(), [], $this->adapter);
// This should fail, but passes locally :(
$updatedRoles
->addColumn('description', 'string', ['default' => 'short desc'])
->update();
$res = $this->adapter->fetchAll('select * from sqlite_master where type = \'table\'');
$res = $this->adapter->fetchRow('select * from constraint_roles LIMIT 1');
$this->assertArrayHasKey('description', $res, 'Should have new column in output');
$this->assertEquals('short desc', $res['description']);
}

public function testPhinxTypeLiteral()
{
$this->assertEquals(
Expand Down

0 comments on commit 2fb93e5

Please sign in to comment.