Welcome Guest, Not a member yet? Register   Sign In
Help with database load design
#1

The current design:
- I'm using v2.2 (don't have time just now to upgrade)
- The application is multi-tenant, with each tenant having separate database
- The correct "tenant" database name for each authenticated user is determined and stored in the user's session data
- I have a custom Model class, extending CI_Model, that defines a "tentantdb" property
- In the constructor of this class the database config is defined, loaded ("$this->load->database($config, TRUE)"), and stored in the tenantdb property
- All model database actions are then performed against $this->tenantdb

It works, but ...
I have some controllers that load a large (40 or so) number of models. As each model is loaded a new connection to the database is created. This is causing database connection limits to be reached.

Ideally I'd like to create the db connection outside the controller (at an "application" level) and then pass it to the model during construction, allowing the same connection to be reused. However, I'm a struggling to identify the best way of achieving this. Any guidance would be much appreciated.
Reply
#2

(This post was last modified: 08-09-2017, 06:42 PM by jarmen_kell. Edit Reason: CI's forum messes up with php code syntax highlight )

I've been thru the same case just like you, years ago.
here's what i did


create a "core" model, let's just call it "Coremodel" 
PHP Code:
<?php defined('BASEPATH') OR exit('No direct script access allowed');

class 
Coremodel extends CI_Model {
    
    public static 
$USR_DB;
    
    public function 
__construct()
    {
        
parent::__construct();
        
        
self::$USR_DB['user_1']     = $this->load->database('user_1',true);
        
self::$USR_DB['user_2']     = $this->load->database('user_2',true);
        
self::$USR_DB['user_3']     = $this->load->database('user_3',true);
        
// and so'on
    
}



this model will act as a core parent for all models that you'll create later on.notice that i put a public-static variable inside this 'core' model.


later on, when you try creating models for each of your user's custom db connection,
just extend from our "Coremodel" 
PHP Code:
class Model_user1 extends Coremodel {
    
    private 
$_DB;
    
    function 
__construct() { 
        
parent::__construct();
        
$this->_DB     parent::$USR_DB['user_1'];
    }
    
    public function 
get($id)
    {
        return 
$this->_DB->get_where("table_name", ['id'=>$id]);
    } 

notice that i put a private var "_DB" and then retrieve our db connection instance from "Coremodel",then put it in private var "_DB". 


lastly, make sure that our "Coremodel" is autoloaded from autoload config.
PHP Code:
$autoload['model'] = array('coremodel'); 


now you have all of your model's connected accordingly,
without haveing to create a new connection for each models.

hope this make sense.
Reply
#3

(This post was last modified: 08-10-2017, 01:36 PM by phpforever2017.)

If I understand you try this
PHP Code:
if ( ! isset( $this->db )
        {
            
$this->load->database();
        } 
and load all your models.
see in model construtor code have this line

PHP Code:
    $this->load->database(); 
Reply
#4

(08-09-2017, 07:38 AM)NickBrown1968 Wrote: The current design:
- I'm using v2.2 (don't have time just now to upgrade)

Not trying to bust any balls but you should take security more seriously...

I to have some clients who are not willing to pay to keep the basic framework up to date. But whenever they wat me to add some new feature later on I will perform the upgrade and calculate it in the price for that feature.
Reply
#5

(08-11-2017, 02:57 AM)Diederik Wrote:
(08-09-2017, 07:38 AM)NickBrown1968 Wrote: The current design:
- I'm using v2.2 (don't have time just now to upgrade)

Not trying to bust any balls but you should take security more seriously...
What an incredibly arrogant and presumptuous response given that you have absolutely no insight into the context in which my application is developed and operates. Might have been less so had you actually been able to provide some assistance to the question posed.
Reply
#6

@jarmen_kell - that's basically what I've already got in place with the core model setting up db config for the user in the constructor. However, as it stands it would still create a new connection for each model that is based on the core. The use of the static property for the db did set me on the right path though. By using a static property for the db in the core class and adding the code proposed by phpforever2017 in the constructor to test if the db connection had already been set I was able to ensure that the core class only ever established a single db connection.

Thanks for the help. Much appreciated.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB