diff --git a/src/Db/Adapter/SqliteAdapter.php b/src/Db/Adapter/SqliteAdapter.php index 7a9df3e7..98f3cd82 100644 --- a/src/Db/Adapter/SqliteAdapter.php +++ b/src/Db/Adapter/SqliteAdapter.php @@ -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']), diff --git a/src/Db/Table/Table.php b/src/Db/Table/Table.php index 9b2685b1..70f270f6 100644 --- a/src/Db/Table/Table.php +++ b/src/Db/Table/Table.php @@ -12,6 +12,7 @@ /** * @internal + * @TODO rename this to `TableMetadata` having two classes with very similar names is confusing for me. */ class Table { diff --git a/tests/TestCase/Db/Adapter/SqliteAdapterTest.php b/tests/TestCase/Db/Adapter/SqliteAdapterTest.php index aa9e7a5a..9b34858c 100644 --- a/tests/TestCase/Db/Adapter/SqliteAdapterTest.php +++ b/tests/TestCase/Db/Adapter/SqliteAdapterTest.php @@ -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(