Skip to content

Extending Database Drivers

World Wide Web Server edited this page Jul 4, 2012 · 29 revisions

Category:Databases Category:Database Drivers

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! [b]Don't believe it?, well read on..[/b]

[size=4][b]The solution comes in 3 simple steps:[/b][/size]

[size=4][b]1)[/b][/size] Extend your loader class by creating the file MY_Loader.php. Put it into your libraries directory in the application path:

[code] <?php

class MY_Loader extends CI_Loader {

}

?> [/code]

[size=4][b]2)[/b][/size] Add the following function to your MY_Loader class:

[code] /** * 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'.EXT);

        // 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.EXT;

        if (file_exists($my_driver_file))
        {
            require_once($my_driver_file);
            $db =& new $my_driver(get_object_vars($db));
        }

        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();
}

[/code]

[size=4][b]3)[/b][/size] 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:

[code] <?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); }

} ?> [/code]

[b]Congrats, now you can use your own db functions![/b] Eg. get_first($table), the sample function from above, now fetches the first entry from your table:

[code] $this->db->get_first('sometable'); [/code]

[size=4][b]Other Example Functions[/b][/size]

[code] /** * easy to use filter function (instead of using a ton of where's) */ function filter($filter=array()){ //print_r($filter); foreach($filter as $key=>$value){ if(is_int($key)){ $this->where($value); } $this->where($key, $value); } return $this; }

/**
* 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 always only need one argument
  */
  function ulimit($limit){
   if($limit){
        if(is_array($limit)){
            $this->limit($limit[0], $limit[1]);
        }else{
            $this->limit($limit);
        }
    }
    return $this;
  }

[/code]

Clone this wiki locally