[#460] Introduce db() helper to encapsulate Database DI lookup#465
Conversation
…okup - 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
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 6 minutes and 13 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughA new Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~15 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #465 +/- ##
============================================
+ Coverage 82.80% 82.83% +0.02%
+ Complexity 2861 2857 -4
============================================
Files 249 250 +1
Lines 7619 7614 -5
============================================
- Hits 6309 6307 -2
+ Misses 1310 1307 -3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1bc7aae74f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/Model/Factories/ModelFactory.php (1)
95-107:⚠️ Potential issue | 🟡 Minor
@throws ReflectionExceptionshould be retained.
db()callsDi::get(Database::class)which can throwReflectionExceptionduring container resolution (same reason the other refactored sites —RelationalTrait,TransactionTrait,MigrationManager— keptReflectionExceptionin their@throws). Removing it here creates inconsistency and under-documents the method's failure modes.createDynamicModel()on Line 71 still declaresReflectionException, so the call chain is also inconsistent internally.📝 Proposed fix
/** * `@param` array<string> $foreignKeys * `@param` array<string> $hidden - * `@throws` DiException|BaseException + * `@throws` DiException|BaseException|ReflectionException */ protected static function createOrmInstance(🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Model/Factories/ModelFactory.php` around lines 95 - 107, The docblock for ModelFactory::createOrmInstance currently omits ReflectionException even though db() -> Di::get(Database::class) can throw it; update the method PHPDoc to include `@throws` ReflectionException (alongside DiException|BaseException) so it matches createDynamicModel and other refactored sites (RelationalTrait, TransactionTrait, MigrationManager) and accurately documents the container resolution failure mode.
🧹 Nitpick comments (4)
src/Database/Helpers/db.php (1)
23-30: Guard against function redeclaration.Global helper files are prone to being loaded more than once (e.g., Composer
filesautoload + a helper-loader stage, or during test bootstrapping). Without afunction_exists()guard, a duplicate load will trigger a fatalCannot redeclare db()error. Recommend wrapping the definition:🛡️ Proposed fix
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); -} +if (!function_exists('db')) { + /** + * Gets the Database instance from DI + */ + function db(): Database + { + if (!Di::isRegistered(Database::class)) { + Di::register(Database::class); + } + + return Di::get(Database::class); + } +}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Database/Helpers/db.php` around lines 23 - 30, Wrap the global helper function db() with a function_exists check to prevent fatal redeclaration; specifically, before defining function db() (which uses Di::isRegistered, Di::register and Di::get with Database::class), add a guard like if (!function_exists('db')) { /* define function db() here */ } so the helper can be loaded multiple times safely without redefining db().tests/Unit/Database/Helpers/DbHelperTest.php (2)
10-13: RedundantsetUp()override.The override only calls
parent::setUp()and can be removed for brevity. Non-blocking.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/Unit/Database/Helpers/DbHelperTest.php` around lines 10 - 13, Remove the redundant setUp() override in the DbHelperTest class: the current setUp() method only calls parent::setUp() and can be deleted to simplify the test class; locate the public function setUp(): void in DbHelperTest and remove that method so the parent implementation is used directly.
15-26: Consider adding coverage for the lazy-registration branch.Both existing tests exercise the already-registered path after
AppTestCasebootstrapping. A test that resets the DI container (or unregistersDatabase::class) before callingdb()would exercise the!Di::isRegistered(...)branch insrc/Database/Helpers/db.php(Lines 25–27), which is currently not directly verified.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/Unit/Database/Helpers/DbHelperTest.php` around lines 15 - 26, Add a unit test that resets the DI registration before calling db() to cover the lazy-registration branch: in DbHelperTest add a new test (e.g., testDbHelperLazilyRegistersDatabase) that unregisters Database::class from the container (or resets Di) after AppTestCase bootstrapping, then calls db() and asserts it returns an instance of Database and that the container now has Database::class registered; reference the db() helper, Di::isRegistered/Di unregister behavior, and Database::class to locate the code paths in src/Database/Helpers/db.php.tests/Unit/View/ViewTest.php (1)
120-122: Line-ending normalization is fine, but consider normalizing the expected string instead.Mutating
$renderedViewbefore assertion masks what the renderer actually produced. An equivalent and clearer approach is to normalize both sides (or just the expected side) usingPHP_EOL. Non-blocking; matches the pattern already used intestRenderViewWithTwigon Line 187, so consistency-wise this is acceptable.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/Unit/View/ViewTest.php` around lines 120 - 122, Instead of mutating $renderedView before the assertion, normalize the expected string to use PHP_EOL (consistent with testRenderViewWithTwig) so the assertion compares the raw renderer output to a normalized expected value; update the assertion in ViewTest (the $renderedView variable and the assertEquals call) to remove the str_replace on $renderedView and apply PHP_EOL normalization to the expected HTML string used in assertEquals.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@src/Model/Factories/ModelFactory.php`:
- Around line 95-107: The docblock for ModelFactory::createOrmInstance currently
omits ReflectionException even though db() -> Di::get(Database::class) can throw
it; update the method PHPDoc to include `@throws` ReflectionException (alongside
DiException|BaseException) so it matches createDynamicModel and other refactored
sites (RelationalTrait, TransactionTrait, MigrationManager) and accurately
documents the container resolution failure mode.
---
Nitpick comments:
In `@src/Database/Helpers/db.php`:
- Around line 23-30: Wrap the global helper function db() with a function_exists
check to prevent fatal redeclaration; specifically, before defining function
db() (which uses Di::isRegistered, Di::register and Di::get with
Database::class), add a guard like if (!function_exists('db')) { /* define
function db() here */ } so the helper can be loaded multiple times safely
without redefining db().
In `@tests/Unit/Database/Helpers/DbHelperTest.php`:
- Around line 10-13: Remove the redundant setUp() override in the DbHelperTest
class: the current setUp() method only calls parent::setUp() and can be deleted
to simplify the test class; locate the public function setUp(): void in
DbHelperTest and remove that method so the parent implementation is used
directly.
- Around line 15-26: Add a unit test that resets the DI registration before
calling db() to cover the lazy-registration branch: in DbHelperTest add a new
test (e.g., testDbHelperLazilyRegistersDatabase) that unregisters
Database::class from the container (or resets Di) after AppTestCase
bootstrapping, then calls db() and asserts it returns an instance of Database
and that the container now has Database::class registered; reference the db()
helper, Di::isRegistered/Di unregister behavior, and Database::class to locate
the code paths in src/Database/Helpers/db.php.
In `@tests/Unit/View/ViewTest.php`:
- Around line 120-122: Instead of mutating $renderedView before the assertion,
normalize the expected string to use PHP_EOL (consistent with
testRenderViewWithTwig) so the assertion compares the raw renderer output to a
normalized expected value; update the assertion in ViewTest (the $renderedView
variable and the assertEquals call) to remove the str_replace on $renderedView
and apply PHP_EOL normalization to the expected HTML string used in
assertEquals.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9364f83c-835b-4eb7-9a40-6ece168483f7
📒 Files selected for processing (7)
src/Database/Helpers/db.phpsrc/Database/Traits/RelationalTrait.phpsrc/Database/Traits/TransactionTrait.phpsrc/Migration/MigrationManager.phpsrc/Model/Factories/ModelFactory.phptests/Unit/Database/Helpers/DbHelperTest.phptests/Unit/View/ViewTest.php
Document ReflectionException in ModelFactory::createOrmInstance and simplify DbHelperTest by removing redundant setup while adding lazy DI registration coverage for db(). Made-with: Cursor
Closes #460
Summary by CodeRabbit
New Features
db()helper function for convenient access to the database instance throughout the application.Tests
Chores