diff --git a/system/Database/Seeder.php b/system/Database/Seeder.php index aacc8e9905ce..632008176031 100644 --- a/system/Database/Seeder.php +++ b/system/Database/Seeder.php @@ -27,7 +27,7 @@ class Seeder /** * The name of the database group to use. * - * @var non-empty-string + * @var non-empty-string|null */ protected $DBGroup; @@ -92,10 +92,16 @@ public function __construct(Database $config, ?BaseConnection $db = null) $this->config = &$config; - $db ??= Database::connect($this->DBGroup); - - $this->db = $db; - $this->forge = Database::forge($this->DBGroup); + if (isset($this->DBGroup)) { + $this->db = Database::connect($this->DBGroup); + $this->forge = Database::forge($this->DBGroup); + } elseif ($db instanceof BaseConnection) { + $this->db = $db; + $this->forge = Database::forge($db); + } else { + $this->db = Database::connect($config->defaultGroup); + $this->forge = Database::forge($config->defaultGroup); + } } /** @@ -145,7 +151,7 @@ public function call(string $class) } /** @var Seeder $seeder */ - $seeder = new $class($this->config); + $seeder = new $class($this->config, $this->db); $seeder->setSilent($this->silent)->run(); unset($seeder); diff --git a/tests/_support/Database/Seeds/SeederWithDBGroup.php b/tests/_support/Database/Seeds/SeederWithDBGroup.php new file mode 100644 index 000000000000..d25fb657bebf --- /dev/null +++ b/tests/_support/Database/Seeds/SeederWithDBGroup.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Tests\Support\Database\Seeds; + +use CodeIgniter\Database\BaseConnection; +use CodeIgniter\Database\Seeder; + +/** + * Test seeder with explicit DBGroup set. + */ +class SeederWithDBGroup extends Seeder +{ + protected $DBGroup = 'tests'; + + /** + * Store the connection used during run() for testing. + */ + public static ?BaseConnection $lastConnection = null; + + public function run(): void + { + self::$lastConnection = $this->db; + } + + /** + * Expose the db connection for testing. + */ + public function getDatabase(): BaseConnection + { + return $this->db; + } + + /** + * Reset static state for testing. + */ + public static function reset(): void + { + self::$lastConnection = null; + } +} diff --git a/tests/_support/Database/Seeds/SeederWithoutDBGroup.php b/tests/_support/Database/Seeds/SeederWithoutDBGroup.php new file mode 100644 index 000000000000..31ff72598eaf --- /dev/null +++ b/tests/_support/Database/Seeds/SeederWithoutDBGroup.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Tests\Support\Database\Seeds; + +use CodeIgniter\Database\BaseConnection; +use CodeIgniter\Database\Seeder; + +/** + * Test seeder without DBGroup set (should inherit connection). + */ +class SeederWithoutDBGroup extends Seeder +{ + /** + * Store the connection used during run() for testing. + */ + public static ?BaseConnection $lastConnection = null; + + public function run(): void + { + self::$lastConnection = $this->db; + } + + /** + * Expose the db connection for testing. + */ + public function getDatabase(): BaseConnection + { + return $this->db; + } + + /** + * Reset static state for testing. + */ + public static function reset(): void + { + self::$lastConnection = null; + } +} diff --git a/tests/system/Database/DatabaseSeederTest.php b/tests/system/Database/DatabaseSeederTest.php index 398052636246..e00599e26507 100644 --- a/tests/system/Database/DatabaseSeederTest.php +++ b/tests/system/Database/DatabaseSeederTest.php @@ -17,13 +17,23 @@ use Config\Database; use Faker\Generator; use PHPUnit\Framework\Attributes\Group; +use Tests\Support\Database\Seeds\SeederWithDBGroup; +use Tests\Support\Database\Seeds\SeederWithoutDBGroup; /** * @internal */ -#[Group('Others')] +#[Group('DatabaseLive')] final class DatabaseSeederTest extends CIUnitTestCase { + protected function tearDown(): void + { + parent::tearDown(); + + SeederWithDBGroup::reset(); + SeederWithoutDBGroup::reset(); + } + public function testInstantiateNoSeedPath(): void { $this->expectException('InvalidArgumentException'); @@ -57,4 +67,60 @@ public function testCallOnEmptySeeder(): void $seeder = new Seeder(new Database()); $seeder->call(''); } + + public function testSeederWithDBGroupUsesOwnConnection(): void + { + $config = new Database(); + $db = Database::connect('tests', false); + + $seeder = new SeederWithDBGroup($config, $db); + + $testsDb = Database::connect('tests'); + $this->assertSame($testsDb, $seeder->getDatabase()); + $this->assertNotSame($db, $seeder->getDatabase()); + } + + public function testSeederWithoutDBGroupUsesPassedConnection(): void + { + $config = new Database(); + $db = Database::connect('tests'); + + $seeder = new SeederWithoutDBGroup($config, $db); + + $this->assertSame($db, $seeder->getDatabase()); + } + + public function testSeederWithoutDBGroupAndNoConnectionUsesDefault(): void + { + $config = new Database(); + + $seeder = new SeederWithoutDBGroup($config); + + $defaultDb = Database::connect($config->defaultGroup); + $this->assertSame($defaultDb, $seeder->getDatabase()); + } + + public function testCallPassesConnectionToChildSeeder(): void + { + $config = new Database(); + $db = Database::connect('tests'); + + $seeder = new Seeder($config, $db); + $seeder->setSilent(true)->call(SeederWithoutDBGroup::class); + + $this->assertSame($db, SeederWithoutDBGroup::$lastConnection); + } + + public function testCallChildWithDBGroupUsesOwnConnection(): void + { + $config = new Database(); + $db = Database::connect('tests', false); + + $seeder = new Seeder($config, $db); + $seeder->setSilent(true)->call(SeederWithDBGroup::class); + + $testsDb = Database::connect('tests'); + $this->assertSame($testsDb, SeederWithDBGroup::$lastConnection); + $this->assertNotSame($db, SeederWithDBGroup::$lastConnection); + } } diff --git a/user_guide_src/source/changelogs/v4.6.5.rst b/user_guide_src/source/changelogs/v4.6.5.rst index 0ae6d47fe1be..98f3558dee92 100644 --- a/user_guide_src/source/changelogs/v4.6.5.rst +++ b/user_guide_src/source/changelogs/v4.6.5.rst @@ -30,6 +30,8 @@ Deprecations Bugs Fixed ********** +- **Database:** Fixed a bug where ``Seeder::call()`` did not pass the database connection to child seeders, causing them to use the default connection instead of the one specified via ``Database::seeder('group')``. + See the repo's `CHANGELOG.md `_ for a complete list of bugs fixed. diff --git a/user_guide_src/source/dbmgmt/seeds.rst b/user_guide_src/source/dbmgmt/seeds.rst index ded3836f36cd..dce9aa7cb6fc 100644 --- a/user_guide_src/source/dbmgmt/seeds.rst +++ b/user_guide_src/source/dbmgmt/seeds.rst @@ -44,6 +44,29 @@ You can grab a copy of the main seeder through the database config class: .. literalinclude:: seeds/004.php +Using a Different Database Group +================================ + +You can specify a different database group when obtaining a seeder instance by passing the group name +as the first parameter: + +.. literalinclude:: seeds/005.php + +When using ``call()`` to run child seeders, the database connection is automatically passed to them. +This means child seeders will use the same connection as the parent seeder, unless they explicitly +specify their own ``$DBGroup`` property. + +If a seeder needs to always use a specific database group regardless of the parent seeder's connection, +you can set the ``$DBGroup`` property in the seeder class: + +.. literalinclude:: seeds/006.php + +The connection priority is: + +1. If ``$DBGroup`` is set in the seeder class, that connection group is always used +2. Otherwise, if a connection was passed (from parent seeder via ``call()`` or from ``Database::seeder()``), it is used +3. Otherwise, the default connection group is used + Command Line Seeding ==================== diff --git a/user_guide_src/source/dbmgmt/seeds/005.php b/user_guide_src/source/dbmgmt/seeds/005.php new file mode 100644 index 000000000000..e709278fc4be --- /dev/null +++ b/user_guide_src/source/dbmgmt/seeds/005.php @@ -0,0 +1,4 @@ +call('TestSeeder'); diff --git a/user_guide_src/source/dbmgmt/seeds/006.php b/user_guide_src/source/dbmgmt/seeds/006.php new file mode 100644 index 000000000000..2ed2044c93c8 --- /dev/null +++ b/user_guide_src/source/dbmgmt/seeds/006.php @@ -0,0 +1,15 @@ +