[eluser]Unknown[/eluser]
Hi there,
I also have similar problems with multiple database profiler. My application have two database groups, one is 'master' and the other is 'slave'. 'master' is the active group.
I also write a base model class to make it easier to get the Master or Slave database connection and other model classes will have to extend this class.
Code:
class MY_Model extends Model
{
public function MY_Model()
{
parent::Model();
}
protected function getMasterDb()
{
return $this->load->database('master', TRUE);
}
protected function getSlaveDb()
{
return $this->load->database('slave', TRUE);
}
}
In User model, I have the following function:
Code:
class User_model extends MY_Model
{
public function getUser($uid)
{
$db = $this->getSlaveDb();
$sql = 'SELECT * FROM users WHERE uid = ?';
$data = $db->query($sql, array($uid));
if ($data->num_rows() > 0){
return $data->row();
}
return FALSE;
}
}
Function getUser runs perfectly but the profiler can not capture the query executed. If I use $this->getMasterDb instead of $this->getSlaveDb, the same problem will occur.
When looking through the CodeIgniter Loader class, I realize that if I set the second parameter of the function $this->load->database to TRUE to force the function return the database object, the database object will not be assign to $CI->db. Therefore, the profiler will not be able to display queries executed on the database.
Code:
function database($params = '', $return = FALSE, $active_record = FALSE)
{
// Grab the super object
$CI =& get_instance();
// Do we even need to load the database class?
if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE AND isset($CI->db) AND is_object($CI->db))
{
return FALSE;
}
require_once(BASEPATH.'database/DB'.EXT);
if ($return === TRUE)
{
return DB($params, $active_record);
}
// Initialize the db variable. Needed to prevent
// reference errors with some configurations
$CI->db = '';
// Load the DB class
$CI->db =& DB($params, $active_record);
// Assign the DB object to any existing models
$this->_ci_assign_to_models();
}
I also try to extend the CI Loader class to make sure that each database connection is assigned to a CI Super object's property. The profiler is now working as expected. Two queries boxes are display for Master and Slave connections.
Code:
class MY_Loader extends CI_Loader
{
public function MY_Loader()
{
parent::CI_Loader();
}
public function database($params = '', $return = FALSE, $active_record = FALSE)
{
// Grab the super object
$CI =& get_instance();
// Do we even need to load the database class?
if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE AND isset($CI->db) AND is_object($CI->db))
{
return FALSE;
}
require_once(BASEPATH.'database/DB'.EXT);
/**
* these lines are modified a litle bit
* to make sure that the database object
* is assigned to a CI Super Object's property
* even if the second parameter is set to TRUE
*
*/
if ($return === TRUE)
{
$db = 'db_' . $params;
if (isset($CI->$db)){
return $CI->$db;
}
$CI->$db = DB($params, $active_record);
return $CI->$db;
}
// Initialize the db variable. Needed to prevent
// reference errors with some configurations
$CI->db = '';
// Load the DB class
$CI->db =& DB($params, $active_record);
// Assign the DB object to any existing models
$this->_ci_assign_to_models();
}
}
However, this is just a test, not a solution. I would really appreciate if you can help me solve the problem.
p/s: I think it may be better to display the Database Group Name instead of the Database Name in the profiler since Master and Slave databases often have the same name but I currently don't know how.