why CodeIgniter's database class is unusable
Update 2011/05/22: I take back my words. db->query()
calls return FALSE
on failure, and the error messages can be accessed via the "private" methods _error_message()
(CI doesn't have language-enforced private methods; they are only indicated as such by naming convention and @access
doc.).
For a recent project, I built a site on top of CI. The requirements were such that I had to add state/persistence. For me (and most people), it meant database interaction.
As usual, CI comes with helpers for many common tasks, and database interaction is no exception. In fact, it also comes with a very simple Active Record implementation. Unfortunately, after writing some code, I wrote those off as "unusable".
Why? (Or, like Shaw, why not?)
The crux of the issue was the horridly restricted error handling exposed to the developer. Whenever a database error was encountered, a call to Exceptions::show_error()
is made. That results in a templated error page to be displayed. In fact, that is how other parts of CI handle errors too.
This is unacceptable if one wishes to customize error handling/display. Granted, one could override/replace the built-in Exceptions class to do the appropriate display, or even raise an exception...but to me this is overly convoluted.
Why exceptions? The "bubbly" property of exceptions gives you the flexibility to specify which function in the call path/stack can catch/handle the error. So, in this case, if a database statement failed, an exception would be raised, and this would bubble through, say, the query()
function in the DB helper, through the insert()
function, to your controller function. Your call stack might even contain a function that logs the DB error, and re-throws the exception up for the controller.
For this reason, I decided to use dbFacile in my CI app. It's pretty small, and has the object keys-to-columns insert()
that I'm looking for. In my fork, I added exceptions - a fairly trivial task.
This brings us to CI's concern over backward-incompatibility; it is commendable from a code-maintainability standpoint, yet it's a burden that prevents uptake of important new language features - exceptions come to mind. Perhaps this is something that keep project maintainers up in the night; I don't see an easy solution to this.