readreplica implementation with codigniter - codeigniter

I'm developing PHP application with codigniter framework. And using amazon read replica setup. I need a way to handle all select query through read only DB and all update related query through master DB. Following is the current usage I use in my script.
database config file
$db['default']['hostname'] = 'master_db_host';
$db['default']['username'] = 'dbuser';
$db['default']['password'] = 'dbpassword';
$db['default']['database'] = 'db_name';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
model script
class replica_model extends CI_Model {
function __construct()
{
parent::__construct();
}
public function write($data)
{
$this->db->insert('dumy', $data);
return $this->db->insert_id();
}
public function read()
{
$query = $this->db->get("dumy");
return $query->result();
}
}
Can any one help me to alter the script to access master and replica based on read and write?

We can handle multiple DB with codeigniter. So first we can see how the config file need to be set.
$active_group = 'default';
$active_record = TRUE;
//Master DB config values
$db['default']['hostname'] = 'master_db_host';
$db['default']['username'] = 'db_user';
$db['default']['password'] = 'db_pass';
$db['default']['database'] = 'db_name';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
//Replica DB config values
$db['read_replica']['hostname'] = 'replica_db_host';
$db['read_replica']['username'] = 'db_user';
$db['read_replica']['password'] = 'db_password';
$db['read_replica']['database'] = 'db_name';
$db['read_replica']['dbdriver'] = 'mysql';
$db['read_replica']['dbprefix'] = '';
$db['read_replica']['pconnect'] = FALSE;
$db['read_replica']['db_debug'] = TRUE;
$db['read_replica']['cache_on'] = FALSE;
$db['read_replica']['cachedir'] = '';
$db['read_replica']['char_set'] = 'utf8';
$db['read_replica']['dbcollat'] = 'utf8_general_ci';
$db['read_replica']['swap_pre'] = '';
$db['read_replica']['autoinit'] = TRUE;
$db['read_replica']['stricton'] = FALSE;
Parameter "$db['read_replica']['pconnect']" should be true on master db config and it should be false on replica config. Other wise when we enable replica db master db config also overwritten by replica config.
Then model usage will be like follows.
class Replica_model extends CI_Model {
function __construct()
{
parent::__construct();
$this->db_replica = $this->load->database('read_replica',TRUE);
}
public function write($data)
{
$this->db->insert('dumy', $data);
return $this->db->insert_id();
}
public function read()
{
$query = $this->db_replica->get("dumy");
return $query->result();
}
}

CI allows you to connect to multiple databases via groups.
This is directly from their site:
https://ellislab.com/codeigniter/user-guide/database/connecting.html
$DB1 = $this->load->database('read', TRUE);
$DB2 = $this->load->database('write', TRUE);
hen you connect this way, you will use your object name to issue commands rather than the syntax used throughout this guide. In other words, rather than issuing commands with:
$this->db->query();
$this->db->result();
etc...
You will instead use:
$DB1->query();
$DB1->result();
etc...
In you will have a multi-dimensional array for your db
$db['read']['hostname'] = ...
$db['write']['hostname'] = ...
So when you read, you would use $DB1, when you write, you'd use $DB2 ...
I haven't used this exact setup. But that's the gist of it.

Related

Connect multiple database in controller or model Codeigniter

I want connect over database
because dbHost, dbUser, dbPass... is Variable should i want connect it in controller or model.
In controller file or model file, What should I write?
In config.php file set as follow:
$active_group = 'default';
$active_record = TRUE;
$db['default']['hostname'] = 'localhost';
$db['default']['username'] = '';
$db['default']['password'] = '';
$db['default']['database'] = 'db1';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
$db['db2']['hostname'] = 'localhost';
$db['db2']['username'] = '';
$db['db2']['password'] = '';
$db['db2']['database'] = 'db2';
$db['db2']['dbdriver'] = 'mysql';
$db['db2']['dbprefix'] = '';
$db['db2']['pconnect'] = TRUE;
$db['db2']['db_debug'] = TRUE;
$db['db2']['cache_on'] = FALSE;
$db['db2']['cachedir'] = '';
$db['db2']['char_set'] = 'utf8';
$db['db2']['dbcollat'] = 'utf8_general_ci';
$db['db2']['swap_pre'] = '';
$db['db2']['autoinit'] = TRUE;
$db['db2']['stricton'] = FALSE;
Or where you want to use directly do as follow:
$db2 = $this->load->database("database_name);
in active record:
$this->db2->select("*");
You can do this without adding to any file
1)We need to create DB Driver String from your given parameters
dbdriver://username:password#hostname/database
//Controller function
function connnectExternalDB()
{
$dbdriver = $this->input->get_post('dbdriver'); //mysqli or mysql
$username = $this->input->get_post('username'); // DB user name
$password = $this->input->get_post('password'); // DB password
$hostname = $this->input->get_post('hostname'); // DB host url
$database = $this->input->get_post('database'); // DB name
$dsn_string = "$dbdriver://$username:$password#$hostname/$database";
// Following will overwrite your current DB connection
$this->load->database($dsn_string, FALSE, TRUE); // 2nd parameter will return db object,3rd parameter will return active record enable for this db connection;
$this->load->model("example_model");
}
2) You can do the same without overwriting the current db connection like this
function connnectExternalDB()
{
$dbdriver = $this->input->get_post('dbdriver'); //mysqli or mysql
$username = $this->input->get_post('username'); // DB user name
$password = $this->input->get_post('password'); // DB password
$hostname = $this->input->get_post('hostname'); // DB host url
$database = $this->input->get_post('database'); // DB name
$dsn_string = "$dbdriver://$username:$password#$hostname/$database";
// Following will overwrite your current DB connection
$DB_OBJ = $this->load->database($dsn_string, TRUE, TRUE); // 2nd parameter will return db object,3rd parameter will return active record enable for this db connection;
$query = "select * from user";
$user_list = $DB_OBJ->query($query)->result_array();
}
It's in database.php in applications/config/ directory not config.php

how to check connection is build properly in codeigniter after configure database.php file?

this is my controller code for setting hostname,username,password,database_name programmatically & it's work properly in my code
function submit_installation()
{
$this->load->helper('url');
$this->load->helper('form');
$this->load->database();
if($_POST)
{
//--------------------to config database file----------------------
$old_hostname = '$db[\'default\'][\'hostname\']';
$old_username = '$db[\'default\'][\'username\']';
$old_password = '$db[\'default\'][\'password\']';
$old_database = '$db[\'default\'][\'database\']';
$fileName = "./application/config/database.php";
$file = file($fileName);
foreach( $file as $key=>$line ) {
if( false !== strpos($line, $old_hostname) )
{
$file[$key]=$old_hostname."='".$_POST['hostname']."';\n";
}
elseif( false !== strpos($line, $old_username) )
{
$file[$key]=$old_username."='".$_POST['username']."';\n";
}
elseif( false !== strpos($line, $old_password) )
{
$file[$key]=$old_password."='".$_POST['password']."';\n";
}
elseif( false !== strpos($line, $old_database) )
{
$file[$key]=$old_database."='".$_POST['database']."';\n";
}
}
file_put_contents($fileName, $file);
}
}
in database.php following code show database setting after execute controller file & changes made in database.php file.
<?php
$active_group = 'default';
$active_record = TRUE
$db['default']['hostname']='xxx';
$db['default']['username']='abc';
$db['default']['password']='abc';
$db['default']['database']='xyz';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = FALSE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
so how to check database connection is made or not using back-end code?
I think You have to try this one:
$db_host = 'localhost';
$db_user = 'abc';
$db_pass = 'xyz';
$db_database = 'qwerty';
$link = mysql_connect($db_host,$db_user,$db_pass) or die('Unable to establish a DB connection');
This one is easy method.

Extending CI_Model for use with report database

I am trying to add a separate report database to my application by extending CI_Model and setting up the correct database to use based on if the database is defined. The report database will be a replicated version of the regular database for performance reasons.
Is this the proper way?
In application/core/MY_Model:
<?php
class MY_Model extends CI_Model
{
function __construct()
{
parent::__construct();
include APPPATH.'config/database.php';
//If we have a reporting database load it and use it for all reporting functions
if (isset($db['reports']))
{
$this->report_db = $this->load->database('reports', TRUE);
}
else
{
$this->report_db = $this->load->database('default', TRUE);
}
}
}
?>
You can use both of your databases within your code. This you have to define in config/database.php
database.php
$active_group = 'default';
$active_record = TRUE;
$db['default']['hostname'] = 'localhost';
$db['default']['username'] = 'username';
$db['default']['password'] = 'password';
$db['default']['database'] = 'database1';
$db['default']['dbdriver'] = 'mysqli';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
$db['reports']['hostname'] = 'localhost';
$db['reports']['username'] = 'username';
$db['reports']['password'] = 'password';
$db['reports']['database'] = 'database2';
$db['reports']['dbdriver'] = 'mysqli';
$db['reports']['dbprefix'] = '';
$db['reports']['pconnect'] = TRUE;
$db['reports']['db_debug'] = TRUE;
$db['reports']['cache_on'] = FALSE;
$db['reports']['cachedir'] = '';
$db['reports']['char_set'] = 'utf8';
$db['reports']['dbcollat'] = 'utf8_general_ci';
$db['reports']['swap_pre'] = '';
$db['reports']['autoinit'] = TRUE;
$db['reports']['stricton'] = FALSE;
reports_model.php
<?php
class Reports_model extends CI_Model
{
public function __construct()
{
parent::__construct();
$this->db_reports = $this->load->database('reports', TRUE);
}
public function reports_list()
{
$this->db_reports->get('some_table');
}
}
other_model.php
<?php
class Other_model extends CI_Model
{
public function __construct()
{
parent::__construct();
}
public function xyz()
{
$this->db->get('some_table');
}
}
Explanation:
Since you have defined default as your active group, so whatever database you have defined in your default group, you can use as following in your model -
$this->db->get('some_table'); // as we defined normally
And sine you have other databases also you can have another group of them. We have defined them in reports group. So we have add an extra _reports after db like this -
$this->db_reports->get('some_table');

Why my Codeigniter unable to connect multiple database?

I am junior of codeigniter, what I want to do is connect multiple database to retrieve the database data, but it is not working for me, keep return me 404 error page
here is my code
config/database.php
$active_group = 'qm';
$active_record = TRUE;
$db['qm']['hostname'] = '192.168.0.128';
$db['qm']['username'] = 'callcenter';
$db['qm']['password'] = 'ca11c3nt3r';
$db['qm']['database'] = 'qm';
$db['qm']['dbdriver'] = 'mysql';
$db['qm']['dbprefix'] = '';
$db['qm']['pconnect'] = TRUE;
$db['qm']['db_debug'] = TRUE;
$db['qm']['cache_on'] = FALSE;
$db['qm']['cachedir'] = '';
$db['qm']['char_set'] = 'utf8';
$db['qm']['dbcollat'] = 'utf8_general_ci';
$db['qm']['swap_pre'] = '';
$db['qm']['autoinit'] = TRUE;
$db['qm']['stricton'] = FALSE;
/* call contact detail table */
$active_group = "reportcallcenter";
$active_record = TRUE;
$db['reportcallcenter']['hostname'] = '192.168.0.128';
$db['reportcallcenter']['username'] = 'callcenter';
$db['reportcallcenter']['password'] = 'ca11c3nt3r';
$db['reportcallcenter']['database'] = 'reportcallcenter';
$db['reportcallcenter']['dbdriver'] = 'mysql';
$db['reportcallcenter']['dbprefix'] = "";
$db['reportcallcenter']['pconnect'] = TRUE;
$db['reportcallcenter']['db_debug'] = TRUE;
$db['reportcallcenter']['cache_on'] = FALSE;
$db['reportcallcenter']['cachedir'] = "";
$db['reportcallcenter']['char_set'] = "utf8";
$db['reportcallcenter']['dbcollat'] = "utf8_general_ci";
$db['reportcallcenter']['swap_pre'] = '';
$db['reportcallcenter']['autoinit'] = TRUE;
$db['reportcallcenter']['stricton'] = FALSE;
Controller
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Qm extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->permission->is_logged_in();
//load model
$this->load->helper('url');
$this->load->model('callcontactsdetails_model');
$this->load->database('qm', TRUE);
$this->load->database('reportcallcenter', TRUE);
}
function qm_form()
{
$data = array();
$data['page'] = 'qm_form';
if($query = $this->callcontactsdetails_model->get_all())
{
$data['recordings_record'] = $query;
}
$data['main'] = 'qm/qm_form';
$data['js_function'] = array('qm');
$this->load->view('template/template',$data);
}
}//end of class
?>
Model (I using My_model)
<?php
class Callcontactsdetails_model extends MY_Model {
protected $_table = 'callcontactsdetails';
protected $primary_key = 'id';
}
?>
My Screen Return Result
Any Idea how to solve my problem or any mistake I did ?
Load your database like this
$this->db_report = $this->CI->load->database('reportcallcenter', TRUE);
assumed that 'qm' db will be set as default
or you can try like this
$DB1 = $this->load->database('qm', TRUE);
$DB2 = $this->load->database('reportcallcenter', TRUE);
then you can use like
$DB1->query();
$DB1->result();
and
$DB2->query();
$DB2->result();
in your case try like
if($query = $DB2->get_all())
{
$data['recordings_record'] = $query;
}

CodeIgniter MultiDatabse connect error

I see a lot of method/tutorial to connect multi database in CodeIgniter? Still far far away with me. Some one provide me to connect multi database in CI. This is my using way i was found it in a blog. pardon me, i don't recognize the blog address.
$active_group = 'default';
$active_record = TRUE;
$db['default']['hostname'] = 'localhost';
$db['default']['username'] = 'root';
$db['default']['password'] = 'root';
$db['default']['database'] = 'vk_global';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
//add alternate database settings
$db['wow']['hostname'] = 'localhost';
$db['wow']['username'] = 'root';
$db['wow']['password'] = 'root';
$db['wow']['database'] = 'auth';
$db['wow']['dbdriver'] = 'mysql';
$db['wow']['dbprefix'] = '';
$db['wow']['pconnect'] = TRUE;
$db['wow']['db_debug'] = TRUE;
$db['wow']['cache_on'] = FALSE;
$db['wow']['cachedir'] = '';
$db['wow']['char_set'] = 'utf8';
$db['wow']['dbcollat'] = 'utf8_general_ci';
$db['wow']['swap_pre'] = '';
$db['wow']['autoinit'] = TRUE;
$db['wow']['stricton'] = FALSE;
i was call it with this code
$DB2 = $this->load->database('auth',true);
and i was insert a simple row with this code
$this->$DB2->insert('events_grouptable',$data);
i got this error You have specified an invalid database connection group.
how should i solve this error?
$DB1 = $this->load->database('default', TRUE);
$DB2 = $this->load->database('wow', TRUE);
You need to set which db to use with which group otherwise the alternative does not work as
$active_group = 'default';
More details are here http://ellislab.com/codeigniter/user-guide/database/connecting.html

Resources