Skip to content

Active Record parallel queries

captainkuro edited this page Jan 11, 2013 · 16 revisions

Category:Core | Category:Core::Database | Category:Core::Community

This is a replacement of the system/database/DB_active_rec.php file, allowing you to use several CI Active Record threads at the same time without overlapping. See the relevant forum thread.

Sample code:

$this->db->set_identifier('my_first_query');
$this->db->from('blabla');
$this->db->where('blibli');

$this->db->set_identifier('my_second_query');
$this->db->from('tatata');
$this->db->where('tititi');

$this->db->set_identifier('my_first_query');
$first_query = $this->db->get();

$this->db->set_identifier('my_second_query');
$second_query = $this->db->get();

It's fully backward compatible, and you could use it also this way (adding two lines around the code to protect from other AR calls):

$this->db->set_identifier("my unique string that I won't use twice unless it's really clean");
$query = $this->db->getwhere('a_table', array('id' => $id));
$result = $query->first_row();
$this->db->set_identifier('default');

Some apps (like Rapyd in dataset.php around line 253) tweak some AR variables without using the public functions. You'll have to hack them if you want to use the new DB_active_rec.php. For example in Rapyd, the lines

// ...
$this->db->ar_limit = FALSE;
// ...
$this->db->ar_select = array('COUNT(*) AS totalrows');  
// ...
$this->db->ar_orderby = array();
// ...
$this->db->ar_order = FALSE;

becomes

// ...
$this->db->ar_limit['default'] = FALSE;
// ...
$this->db->ar_select['default'] = array('COUNT(*) AS totalrows');  
// ...
$this->db->ar_orderby['default'] = array();
// ...
$this->db->ar_order['default'] = FALSE;

Here is a piece of the code of this new file.

<?php
/**
 * Active Record Class
 *
 * This is the platform-independent base Active Record implementation class.
 *
 * Changes by Christophe Gragnic on 2007/06/14 are:
 *         vars now arrays of old vars
 *         added var $ar_identifier and its setter
 *         everywhere you had $this->ar_somevar, you now have
 *         $this->ar_somevar[$this->ar_identifier]
 *
 * Those changes allow us to use Active Record parallel queries.
 * The "identifier" is a simple string (default:'default').
 * Backward compatible, set_identifier('some_identifier') is optional.
 *
 * Sample code:
 * $this->db->set_identifier('my_first_query');
 * $this->db->from('blabla');
 * $this->db->where('blibli');
 *
 * $this->db->set_identifier('my_second_query');
 * $this->db->from('tatata');
 * $this->db->where('tititi');
 *
 * $this->db->set_identifier('my_first_query');
 * $first_query = $this->db->get();
 *
 * $this->db->set_identifier('my_second_query');
 * $second_query = $this->db->get();
 *
 * @package        CodeIgniter
 * @subpackage    Drivers
 * @category    Database
 * @author        Rick Ellis
 * @author        Christophe Gragnic (grahack) for the identifier stuff only
 * @link        http://www.codeigniter.com/user_guide/database/
 */
class CI_DB_active_record extends CI_DB_driver {
    
    var $ar_identifier = 'default';
    
    var $ar_select    = array('default' => array());
    var $ar_distinct  = array('default' => FALSE);
    var $ar_from      = array('default' => array());
    var $ar_join      = array('default' => array());
    var $ar_where     = array('default' => array());
    var $ar_like      = array('default' => array());
    var $ar_groupby   = array('default' => array());
    var $ar_having    = array('default' => array());
    var $ar_limit     = array('default' => FALSE);
    var $ar_offset    = array('default' => FALSE);
    var $ar_order     = array('default' => FALSE);
    var $ar_orderby   = array('default' => array());
    var $ar_set       = array('default' => array());

    /**
     * Set_identifier
     *
     * Chooses the channel to use
     *
     * @access    public
     * @param    string
     * @return    object
     */
    function set_identifier($identifier = 'default')
    {
        if ( ! is_string($identifier))
        {
            $identifier = 'default';
        }
        
        $this->ar_identifier = $identifier;
        
        // we have to init the values only if it is a new key
        // let's check on the first array
        if ( ! array_key_exists($identifier, $this->ar_select))
        {
            $this->ar_select        [$identifier] = array();
            $this->ar_distinct      [$identifier] = FALSE;
            $this->ar_from          [$identifier] = array();
            $this->ar_join          [$identifier] = array();
            $this->ar_where         [$identifier] = array();
            $this->ar_like          [$identifier] = array();
            $this->ar_groupby       [$identifier] = array();
            $this->ar_having        [$identifier] = array();
            $this->ar_limit         [$identifier] = FALSE;
            $this->ar_offset        [$identifier] = FALSE;
            $this->ar_order         [$identifier] = FALSE;
            $this->ar_orderby       [$identifier] = array();
            $this->ar_set           [$identifier] = array();
        }
        return $this;
    }

Download

File:DB_active_rec.zip

version 1.7.2 edited by Afro Radio Head Loved this added feature, so I had to update it File:DB_active_rec_v1.7.2.zip

Clone this wiki locally