Skip to content

Active Record parallel queries

Derek Jones edited this page Jul 4, 2012 · 24 revisions

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

This is a replacement of the [b]system/database/DB_active_rec.php[/b] file, allowing you to use several CI Active Record threads at the same time without overlapping. See the relevant [url=http://codeigniter.com/forums/viewthread/54113/]forum thread[/url].

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 [b]DB_active_rec.php[/b]. 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