Yii Framework Forum: Switch Beetween Two Db (Read - Read/write) - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Switch Beetween Two Db (Read - Read/write) Load Balancing Rate Topic: -----

#1 User is offline   MaziTizeh 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 61
  • Joined: 12-June 12
  • Location:U.A.E

Posted 02 January 2013 - 12:17 PM

I have 2 database as A which is ReadOnly and B which is Read/Write,
now how can i handle it in all of my Models?
0

#2 User is offline   seenivasan 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 620
  • Joined: 17-June 12
  • Location:Chennai,TamilNadu,India.

Posted 02 January 2013 - 02:12 PM

Dear Friend

I am not fully able to comprehend your requirement.

I hope that you need one database for index and view actions;
another one for create,update and admin actions.

In main configuration file ,if you have set database A as your main db component,

Then in controller.php in components folder, we can override the beforeAction method.

class Controller extends CController
{
..............
..............

protected function beforeAction($action)
	{   if($action->id=="update" || $action->id=="create" || $action->id=="admin")
	       {
		    Yii::app()->db->setActive(false);
		    Yii::app()->setComponent('db',new CDbConnection('mysql:host=localhost;dbname=B',
			        'root','yourPassword'
			      ));//connectionstring,username,password
	            Yii::app()->db->setActive(true);
		}
	     return true;
	}


Thus actions index and view uses database A.
Actions create,update and admin uses database B.
Table structure for a particular Model should remain same in both databases.

Regards.
0

#3 User is offline   MaziTizeh 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 61
  • Joined: 12-June 12
  • Location:U.A.E

Posted 03 January 2013 - 02:54 AM

Thanks for you help, but now i have hundreds of action, for that what is the solution?

my requirements is something like this extension,

http://www.yiiframew...dwritesplitting
0

#4 User is offline   seenivasan 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 620
  • Joined: 17-June 12
  • Location:Chennai,TamilNadu,India.

Posted 03 January 2013 - 03:27 AM

Dear Friend

Now we can forget about overiding the before action method.

We can overide the init method of CController.

Components/Controller.php
.....................................
.....................................
public function init()
{   if(Yii::app()->user->id==1) //admin. here you can put whatever condition you want....
         {
                 Yii::app()->db->setActive(false);
                 Yii::app()->setComponent('db',new CDbConnection('mysql:host=localhost;dbname=B',
                                'root','yourPassword'
                              ));//connectionstring,username,password
                 Yii::app()->db->setActive(true);
          }
}


Regards
0

#5 User is offline   Blizz 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 23
  • Joined: 14-March 10

Posted 03 January 2013 - 05:19 AM

You should not even do this on a controller level, this should be done on Model level.
Every ActiveRecord has a "getDbConnection()" function that usually just returns the "db" component.
This is used by Yii for everything (both finds and updates)

What I did was make my own CActiveRecord derived class where my getDbConnection function returns a property ('oCurrentConnection'). By default this points to my read-only DB.

Then you override all data modifying functions like insert, update, delete and so on to set the connection to use to the write one, call the parent function and then put it back on the read one.

So for example the update function would go like:
public function update($aAttributes = NULL)
{
  $this->oCurrentConnection = Yii::app()->dbWrite;
  $result = parent::update($aAttributes);
  $this->oCurrentConnection = Yii::app()->db;
  return $result;
}

So during the call your getDbConnection function returns a handle to the write-connection and the rest of the time this would be the read connection.

If you do it like this then all you have to do is change the base class for your models from CActiveRecord to CMyActiveRecord (or however you call it).

This is just an oversimplified way of doing it (i have a generic callParent function that does this for me so I don't have to write the same code over and over), but this is how you would do it.
2

#6 User is offline   seenivasan 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 620
  • Joined: 17-June 12
  • Location:Chennai,TamilNadu,India.

Posted 04 January 2013 - 09:47 AM

Dear Blizz

Things are looking elegant when done at model level.

Many thanks for sharing the information.

Regards.
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users