From 1bc7aae74f10d934e775be62e550dadde37bf520 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Tue, 21 Apr 2026 14:40:02 +0400 Subject: [PATCH 1/2] [#460] Introduce db() helper to encapsulate Database DI lookup - Create src/Database/Helpers/db.php with db() service-locator helper - Replace DI boilerplate in RelationalTrait, TransactionTrait, ModelFactory, and MigrationManager with db() calls - Add DbHelperTest covering instance type and singleton behavior - Normalize line endings in ViewTest::testRenderWithLayout to fix cross-platform test failure Made-with: Cursor --- src/Database/Helpers/db.php | 30 ++++++++++++++++++++ src/Database/Traits/RelationalTrait.php | 8 +----- src/Database/Traits/TransactionTrait.php | 8 +----- src/Migration/MigrationManager.php | 7 +---- src/Model/Factories/ModelFactory.php | 10 ++----- tests/Unit/Database/Helpers/DbHelperTest.php | 27 ++++++++++++++++++ tests/Unit/View/ViewTest.php | 2 ++ 7 files changed, 64 insertions(+), 28 deletions(-) create mode 100644 src/Database/Helpers/db.php create mode 100644 tests/Unit/Database/Helpers/DbHelperTest.php diff --git a/src/Database/Helpers/db.php b/src/Database/Helpers/db.php new file mode 100644 index 000000000..cd8e4fd5c --- /dev/null +++ b/src/Database/Helpers/db.php @@ -0,0 +1,30 @@ + + * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) + * @link http://quantum.softberg.org/ + * @since 3.0.0 + */ + +use Quantum\Database\Database; +use Quantum\Di\Di; + +/** + * Gets the Database instance from DI + */ +function db(): Database +{ + if (!Di::isRegistered(Database::class)) { + Di::register(Database::class); + } + + return Di::get(Database::class); +} diff --git a/src/Database/Traits/RelationalTrait.php b/src/Database/Traits/RelationalTrait.php index efabbc259..0ffe98f98 100644 --- a/src/Database/Traits/RelationalTrait.php +++ b/src/Database/Traits/RelationalTrait.php @@ -16,8 +16,6 @@ namespace Quantum\Database\Traits; -use Quantum\Database\Database; -use Quantum\Di\Di; use Quantum\Di\Exceptions\DiException; use ReflectionException; @@ -87,10 +85,6 @@ public static function queryLog(): array */ protected static function resolveQuery(string $method, string $query = '', array $parameters = []) { - if (!Di::isRegistered(Database::class)) { - Di::register(Database::class); - } - - return Di::get(Database::class)->getOrmClass()::$method($query, $parameters); + return db()->getOrmClass()::$method($query, $parameters); } } diff --git a/src/Database/Traits/TransactionTrait.php b/src/Database/Traits/TransactionTrait.php index c88e63569..e82114dde 100644 --- a/src/Database/Traits/TransactionTrait.php +++ b/src/Database/Traits/TransactionTrait.php @@ -18,9 +18,7 @@ use Quantum\Database\Exceptions\DatabaseException; use Quantum\App\Exceptions\BaseException; -use Quantum\Database\Database; use ReflectionException; -use Quantum\Di\Di; use Throwable; /** @@ -64,11 +62,7 @@ public static function rollback(): void */ protected static function resolveTransaction(string $method) { - if (!Di::isRegistered(Database::class)) { - Di::register(Database::class); - } - - $db = Di::get(Database::class)->getOrmClass(); + $db = db()->getOrmClass(); if (!method_exists($db, $method)) { throw DatabaseException::methodNotSupported($method, self::class); diff --git a/src/Migration/MigrationManager.php b/src/Migration/MigrationManager.php index aef60cb04..982583b29 100644 --- a/src/Migration/MigrationManager.php +++ b/src/Migration/MigrationManager.php @@ -28,7 +28,6 @@ use Quantum\Storage\FileSystem; use Quantum\Database\Database; use ReflectionException; -use Quantum\Di\Di; /** * Class MigrationManager @@ -77,11 +76,7 @@ public function __construct() { $this->fs = FileSystemFactory::get(); - if (!Di::isRegistered(Database::class)) { - Di::register(Database::class); - } - - $this->db = Di::get(Database::class); + $this->db = db(); $this->tableFactory = new TableFactory(); diff --git a/src/Model/Factories/ModelFactory.php b/src/Model/Factories/ModelFactory.php index f7ad35fe1..9b95b6481 100644 --- a/src/Model/Factories/ModelFactory.php +++ b/src/Model/Factories/ModelFactory.php @@ -20,11 +20,9 @@ use Quantum\Model\Exceptions\ModelException; use Quantum\App\Exceptions\BaseException; use Quantum\Di\Exceptions\DiException; -use Quantum\Database\Database; use Quantum\Model\DbModel; use Quantum\Model\Model; use ReflectionException; -use Quantum\Di\Di; /** * Class ModelFactory @@ -97,7 +95,7 @@ public static function createDynamicModel( /** * @param array $foreignKeys * @param array $hidden - * @throws DiException|BaseException|ReflectionException + * @throws DiException|BaseException */ protected static function createOrmInstance( string $table, @@ -106,11 +104,7 @@ protected static function createOrmInstance( array $foreignKeys = [], array $hidden = [] ): DbalInterface { - if (!Di::isRegistered(Database::class)) { - Di::register(Database::class); - } - - $ormClass = Di::get(Database::class)->getOrmClass(); + $ormClass = db()->getOrmClass(); $instance = new $ormClass( $table, diff --git a/tests/Unit/Database/Helpers/DbHelperTest.php b/tests/Unit/Database/Helpers/DbHelperTest.php new file mode 100644 index 000000000..717ca01a6 --- /dev/null +++ b/tests/Unit/Database/Helpers/DbHelperTest.php @@ -0,0 +1,27 @@ +assertInstanceOf(Database::class, db()); + } + + public function testDbHelperReturnsSameInstance(): void + { + $first = db(); + $second = db(); + + $this->assertSame($first, $second); + } +} diff --git a/tests/Unit/View/ViewTest.php b/tests/Unit/View/ViewTest.php index a5d777d3a..ff06859b5 100644 --- a/tests/Unit/View/ViewTest.php +++ b/tests/Unit/View/ViewTest.php @@ -117,6 +117,8 @@ public function testRenderWithLayout(): void $this->assertIsString($renderedView); + $renderedView = str_replace("\n", PHP_EOL, $renderedView); + $this->assertEquals('' . PHP_EOL . '' . PHP_EOL . '' . PHP_EOL . '

Hello World, this is rendered html view

' . PHP_EOL . '' . PHP_EOL, $renderedView); } From eda2b8da5eaa05a16fa30f4c69d3e49ddfedb484 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Tue, 21 Apr 2026 15:36:06 +0400 Subject: [PATCH 2/2] [#460] Align db helper follow-up docs and tests Document ReflectionException in ModelFactory::createOrmInstance and simplify DbHelperTest by removing redundant setup while adding lazy DI registration coverage for db(). Made-with: Cursor --- src/Model/Factories/ModelFactory.php | 2 +- tests/Unit/Database/Helpers/DbHelperTest.php | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Model/Factories/ModelFactory.php b/src/Model/Factories/ModelFactory.php index 9b95b6481..c3972ab13 100644 --- a/src/Model/Factories/ModelFactory.php +++ b/src/Model/Factories/ModelFactory.php @@ -95,7 +95,7 @@ public static function createDynamicModel( /** * @param array $foreignKeys * @param array $hidden - * @throws DiException|BaseException + * @throws DiException|BaseException|ReflectionException */ protected static function createOrmInstance( string $table, diff --git a/tests/Unit/Database/Helpers/DbHelperTest.php b/tests/Unit/Database/Helpers/DbHelperTest.php index 717ca01a6..8f223668c 100644 --- a/tests/Unit/Database/Helpers/DbHelperTest.php +++ b/tests/Unit/Database/Helpers/DbHelperTest.php @@ -4,14 +4,10 @@ use Quantum\Tests\Unit\AppTestCase; use Quantum\Database\Database; +use Quantum\Di\Di; class DbHelperTest extends AppTestCase { - public function setUp(): void - { - parent::setUp(); - } - public function testDbHelperReturnsDatabaseInstance(): void { $this->assertInstanceOf(Database::class, db()); @@ -24,4 +20,13 @@ public function testDbHelperReturnsSameInstance(): void $this->assertSame($first, $second); } + + public function testDbHelperLazilyRegistersDatabase(): void + { + Di::resetContainer(); + + $this->assertFalse(Di::isRegistered(Database::class)); + $this->assertInstanceOf(Database::class, db()); + $this->assertTrue(Di::isRegistered(Database::class)); + } }