Welcome Guest, Not a member yet? Register   Sign In
Multiple databases across all models without breaking reusability
#1

[eluser]elverion[/eluser]
So, I need two use two databases in one of my projects. No big problem there, as that is covered in the user guide. The problem, however, is that I'm not sure how to best go about loading those databases to prevent a number of issues.

First, both databases should be accessible from all models. Using global variables to store the handles works, but then you run into the problem that now your models aren't reusable without changing the variable names when you want to use it in a new project. Globals are just kind of a bad option, but they "work."

Now, I could also load the databases in each function in a model or within the model constructor. It is better for reusability, but you might be making multiple function calls to models or even using multiple models per page, so wouldn't it create multiple handles per database (seeing as how persistent connections don't work well with multiple databases)? I could see this causing issues with many page accesses at the same time.

So, how would you avoid globals (or similar methods) without potentially re-loading databases when it isn't necessary?
#2

[eluser]pickupman[/eluser]
CI will on load one instance of an object. You can code loading a class a 100 times, and CI should load it just once. You may want to look at extending the models class (CI_Model). By extending the model class, you can add in the constructor to load both DB's. You would just need to remember to use MY_Model in any future project you would like to reuse your models in. There are some popular [url="https://bitbucket.org/jamierumbelow/codeigniter-base-model"]MY_Model[/url] files out there that build in some basic CRUD stuff.
Code:
//application/core/MY_Model.php
class MY_Model extends CI_Model{

  public function __construct(){
     parent::__construct();
     //Load DB1 stuff here

     //Load DB2 stuff here
  }
}

//In the rest of your models
class User_model extends MY_Model{
  
  public function __construct(){
    parent::__construct(); //Loads contruct from MY_Model which is loading your DB stuff
  }

  //rest of code here
}
#3

[eluser]CI_avatar[/eluser]
You can try to load your models in constructor.
#4

[eluser]elverion[/eluser]
Are you sure that loading the same database twice is supposed to return the same object? I thought that was only true if persistent connections were enabled (which cannot be when using multiple databases).

I just tried this:
Code:
$DB1 = $this->load->database('DB1', TRUE);
$DB2 = $this->load->database('DB1', TRUE);
echo "DB1: " . $DB1->conn_id . ", DB2: " . $DB2->conn_id;

In that test, I loaded DB1's config twice to see if the connection ID would be the same, but got two different ones instead.
#5

[eluser]pickupman[/eluser]
If you loaded the databases in each of the models that way, that DB connection could be repeated, but by extending the Model library(core) it should only load once.
#6

[eluser]pickupman[/eluser]
Also what if you tested if connection existed before loading?
Code:
if( !is_object($DB1) ){
  $DB1 = $this->load->database('DB1', TRUE);
}

if( !is_object($DB2) ) {
  $DB2 = $this->load->database('DB2', TRUE);
}
#7

[eluser]elverion[/eluser]
I must be overlooking something important.
Code:
class MY_Model extends CI_Model {

    public function __construct()
    {
        parent::__construct();

        if( !is_object($read_db)  )
            $read_db = $this->load->database('read', TRUE);

        if( !is_object($write_db) )
            $write_db = $this->load->database('write', TRUE);

        echo "MY_MODEL, R: " . $read_db->conn_id . ", W: " . $write_db->conn_id . "<br /><br />";
    }
}

And yet, the connection IDs of any models that extend MY_Model are different to both each other and of MY_Model.




Theme © iAndrew 2016 - Forum software by © MyBB