Error in overrideing the function getDbConnection() to use 2 databases

Hi,

I’m trying to write a program to take data from one database, manipulate the data, and then place it into a different database. All while using the Yii framework.

In the /config/main.php file I have added a second database like such:

            'db'=>array(


                    'class'=>'CDbConnection',


                    'connectionString' => 'mysql:host=****;dbname=****',


                    'emulatePrepare' => true,


                    'username' => '***',


                    'password' => '***',


                    'charset' => 'utf8',


            ),





            'db2'=>array(


                    'class' => 'CDBConnection',


                    'connectionString' => 'mysql:host=****;dbname=****',


                    'emulatePrepare' => true,


                    'username' => '***',


                    'password' => '***',


                    'charset' => 'utf8',


            ),

Then in the /components directory I created a file called AltActiveRecord.php which extends CActiveRecord and overrides the function getDbConnection like such:

<?php

    abstract class AltActiveRecord extends CActiveRecord


    {


            public function getDbConnection()





            {





                    if(self::&#036;db&#33;==null)





                            return self::&#036;db;





                    else





                    {





                            self::&#036;db=Yii::app()-&gt;db2;





                            if(self::&#036;db instanceof CDbConnection)





                            {





                                    self::&#036;db-&gt;setActive(true);





                                    return self::&#036;db;





                            }





                            else





                                    throw new CDbException(Yii::t('yii','Active Record requires a &quot;db&quot; CDbConnection application component.'));





                    }





            }


    }

?>

In the model that I want to use db2 I have it extend AltActiveRecord instead of CActiveRecord. However when I try to go to the page I get an error.

Error 500

include(CDBConnection.php): failed to open stream: No such file or directory

With a stack dump of:

include(CDBConnection.php): failed to open stream: No such file or

directory (/Raid/www/restricted/code_store/yii_fw/1.1.3/YiiBase.php:338)

Stack trace:

#0 /Raid/www/restricted/code_store/yii_fw/1.1.3/YiiBase.php(184): import()

#1 /Raid/www/restricted/code_store/yii_fw/1.1.3/base/CModule.php(362):

createComponent()

#2 /Raid/www/restricted/code_store/yii_fw/1.1.3/base/CModule.php(86):

CWebApplication->getComponent()

#3

/Raid/www/restricted/www/sdms/DM/johnyii/protected/components/AltActiveRecord.php(16):

CWebApplication->__get()

#4

/Raid/www/restricted/code_store/yii_fw/1.1.3/db/ar/CActiveRecord.php(2048):

data_products->getDbConnection()

#5

/Raid/www/restricted/code_store/yii_fw/1.1.3/db/ar/CActiveRecord.php(353):

CActiveRecordMetaData->__construct()

#6

/Raid/www/restricted/www/sdms/DM/johnyii/protected/models/data_products.php(21):

model()

#7

/Raid/www/restricted/www/sdms/DM/johnyii/protected/controllers/SiteController.php(44):

model()

#8

/Raid/www/restricted/code_store/yii_fw/1.1.3/web/actions/CInlineAction.php(32):

SiteController->actionIndex()

#9 /Raid/www/restricted/code_store/yii_fw/1.1.3/web/CController.php(300):

CInlineAction->run()

#10 /Raid/www/restricted/code_store/yii_fw/1.1.3/web/CController.php(278):

SiteController->runAction()

#11 /Raid/www/restricted/code_store/yii_fw/1.1.3/web/CController.php(257):

SiteController->runActionWithFilters()

#12

/Raid/www/restricted/code_store/yii_fw/1.1.3/web/CWebApplication.php(324):

SiteController->run()

#13

/Raid/www/restricted/code_store/yii_fw/1.1.3/web/CWebApplication.php(121):

CWebApplication->runController()

#14

/Raid/www/restricted/code_store/yii_fw/1.1.3/base/CApplication.php(135):

CWebApplication->processRequest()

#15 /Raid/www/restricted/www/sdms/DM/johnyii/index.php(12):

CWebApplication->run()

REQUEST_URI=/sdms/DM/johnyii/index.php?r=site/index

Any help will be greatly appreciated.

Looks like your class name is wrong, CDBConnection should be CDbConnection. Note lowercase ‘b’.

Also, I think a better way to do this is to create a new model class that returns the correct db connection.

For instance, you have model ModelA which uses db. Create a subclass ModelB which extends ModelA but overrides the getDb method to return your second db (db2). Then you can read from ModelA and write to ModelB.

Thanks a lot. I can’t believe the problem was that simple. That saved me so much time, and thanks for the advice.

This worked perfectly for me on one system where both databases were on the same machine (localhost).

.../config/main.php




'db'=>array(

			'connectionString' => 'mysql:host=localhost;dbname=db1',

			'emulatePrepare' => true,

			'username' => '**',

			'password' => '**',

			'charset' => 'utf8',

		),

		'db2'=>array(

			'connectionString' => 'mysql:host=localhost;dbname=db2',

			'emulatePrepare' => true,

			'username' => '**',

			'password' => '**',

			'charset' => 'utf8',

			'class'	=> 'CDbConnection'

		),



But then I tried to use a similiar method to connect to 2 databases on different machines and it gave an error.

.../config/main.php




'db'=>array(

			'connectionString' => 'mysql:host=localhost;dbname=db1',

			'emulatePrepare' => true,

			'username' => '**',

			'password' => '**',

			'charset' => 'utf8',

		),

		'db2'=>array(

			'connectionString' => 'mysql:host=10.20.12.14;dbname=db2',

			'emulatePrepare' => true,

			'username' => '**',

			'password' => '**',

			'charset' => 'utf8',

			'class'	=> 'CDbConnection'

		),



The error I receive is the AltActiveRecord.php file followed by

"Fatal error: Class ‘AltActiveRecord’ not found in /var/www/q1media/protected/models/_base/BaseVideoTag.php on line 26 "

AltActiveRecord is defined in the BaseVideo.php class.




abstract class BaseVideo extends AltActiveRecord {

    

    public static function model($className = __CLASS__) {

        return parent::model($className);

    }


    public function tableName() {

        return 'db2.video';

    }

....



If I rename AltActiveRecord.php to something else, the view returns an error that makes sense. "Cannot open stream…"

Anyone with any clues ?

The servers are in the cloud and I can ping them, I can also connect to db2 from a php file on the webserver.

Thanks for any help!