-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Extending Database Drivers
Category:Help | Category:Help::TipsAndTricks | Category:Help::Databases
Much complaints about not being able to extend the CI database class. In the docs it says this can't be done, but here is a simple solution that fits it all! Don't believe it?, well read on..
1) Extend your loader class by creating the file MY_Loader.php. Put it into your core directory in the application path (or if you are using CI 2.x.x then put it into application\core\ path):
<?php
class MY_Loader extends CI_Loader {
}
?>
2) Add the following function to your MY_Loader class:
/**
* Database Loader
*
* @access public
* @param string the DB credentials
* @param bool whether to return the DB object
* @param bool whether to enable active record (this allows us to override the config setting)
* @return object
*/
function database($params = '', $return = FALSE, $active_record = FALSE)
{
// Do we even need to load the database class?
if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE)
{
return FALSE;
}
require_once(BASEPATH.'database/DB'.'.php');
// Load the DB class
$db =& DB($params, $active_record);
$my_driver = config_item('subclass_prefix').'DB_'.$db->dbdriver.'_driver';
$my_driver_file = APPPATH.'libraries/'.$my_driver.'.php';
if (file_exists($my_driver_file))
{
require_once($my_driver_file);
$db_obj = new $my_driver(get_object_vars($db));
$db=& $db_obj;
}
if ($return === TRUE)
{
return $db;
}
// Grab the super object
$CI =& get_instance();
// Initialize the db variable. Needed to prevent
// reference errors with some configurations
$CI->db = '';
$CI->db = $db;
// Assign the DB object to any existing models
$this->_ci_assign_to_models();
}
Please note if you are using CI 2.x.x then you need to comment out the last statement:-
// $this->_ci_assign_to_models();
3) Create your Database driver extension class, that you name MY_DB_mysql_driver.php (or substitute the mysql part for whatever driver you use - do that also for the classnames in the code below!). Put this file also in your applications libraries directory:
<?php
class MY_DB_mysql_driver extends CI_DB_mysql_driver {
function __construct($params){
parent::__construct($params);
log_message('debug', 'Extended DB driver class instantiated!');
}
function get_first($table){
return $this->limit(1)->get($table);
}
}
?>
Congrats, now you can use your own db functions! Eg. get_first($table), the sample function from above, now fetches the first entry from your table:```php $this->db->get_first('sometable');
(put them also in your Extended DB driver class)
/**
* nests like, where statements
* order in select clause is WHERE - LIKE
* so WHERE a=0 OR ((WHERE b=0 AND c LIKE '%me%') OR m LIKE '%us') AND f LIKE '%nobody%
* is possible
*/
function nest($kind, $start, $end, $kind2=false){
$kind = 'ar_'.$kind;
$this->{$kind}[$start-1] = preg_replace('/(^AND )|(^OR )|^/', "$1$2(", $this->{$kind}[$start-1]);
if($kind2){
$kind = 'ar_'.$kind2;
}
$this->{$kind}[$end-1] .= ')';
return $this;
}
/**
* a limit function that takes an array or an integer,
* so you only need one argument ever
*/
function ulimit($limit){
if($limit){
if(is_array($limit)){
$this->limit($limit[0], $limit[1]);
}else{
$this->limit($limit);
}
}
return $this;
}
You can use the same trick to extend the functionality of the DB_Cache library. Copy the DB_Cache.php file from the system/libraries directory to your APPPATH/libraries directory. Then add this to your MY_Loader library:
/**
* Database Loader extension, to load our version of the caching engine
*
* @access public
* @param string the DB credentials
* @param bool whether to return the DB object
* @param bool whether to enable active record (this allows us to override the config setting)
* @return object
*/
function database($params = '', $return = FALSE, $active_record = NULL)
{
// load our version of the CI_DB_Cache class. The database library checks
// if this class is already loaded before instantiating it. Loading it now
// makes sure our version is used when a controller enables query caching
if ( ! class_exists('CI_DB_Cache'))
{
@include(APPPATH.'libraries/DB_cache'.EXT);
}
// call the parent method to retain the CI functionality
return parent::database($params, $return, $active_record);
}