[Dynamic Connection] Save() Doesn't Work!

Long story short,

[color="#0000FF"]I need a dynamic connection to separate DB’s for multiple tenants[/color]

I modified my model for when the constructor() is given a $tenantID, it will search within his DB.




class TENANT_Page extends CActiveRecord

{

         public $tenantID = null;


         /* Overridden */         

         public function __construct( $scenario = 'insert', $tenantID = null )

         {

                if ( $tenantID != null)

                {

                        $this->tenantID = $tenantID;

                }

                parent::__construct($scenario);

         }

         

         /* Overridden */  

         public function getDbConnection()

         {

             return Yii::app()->dynamicDB->getTenantConnection($this->tenantID); 

         }



This is my custom component to manage all my connections to all DB’s.




class DynamicDB extends CApplicationComponent 

{

        public $connection;

        public $externalTenant;

        

        public function getDbConnection($IPaddress,$dbName, $username, $password) 

        {

            $this->connection=new CDbConnection('mysql:host='.$IPaddress.';dbname='.$dbName, $username, $password);

            $this->connection->active=true;

            return $this->connection;

        }


        

        public function getTenantConnection($tenantID = null)

        {

                if ($tenantID == null){

                       return Yii::app()->tenant->db;

                } else {        

                       $this->externalTenant = GTBtenant::model()->findByPk($tenantID); 

                       if ($this->externalTenant == null){

                            Yii::app()->alert->sendAlert(Alert::ERROR_ALERT, 'the tenant ('.$tenantID.') couldnt be found, when requested by class ['.__CLASS__.']');

                       } else {

                          

                          return $this->getDbConnection(  $this->externalTenant->IPaddress,

                                                            $this->externalTenant->DBname,

                                                            $this->externalTenant->username,

                                                            $this->externalTenant->password );

                       }

                }

        }

        

}




[color="#0000FF"]Now the usage of all this![/color]

[color="#FF0000"]THIS DOESN’T WORK!!![/color]




$newPage = new TENANT_Page(null, $_GET['tenantID'] );

                $newPage->attributes=$_POST['TENANT_Page'];

                

               if ($newPage->validate()){

                        $newPage->save(false);

               } else {

                        Yii::app()->alert->sendAlert(Alert::ERROR_ALERT_IGNORE, 'When trying to create a page and error occured!');

               }



[color="#00FF00"]THIS WORKS!!![/color]




$newPage = new TENANT_Page(null, $_GET['tenantID'] );

                $newPage->attributes=$_POST['TENANT_Page'];

                

               if ($newPage->validate()){

                        $newPage->saveCustom();

               } else {

                        Yii::app()->alert->sendAlert(Alert::ERROR_ALERT_IGNORE, 'When trying to create a page and error occured!');

               }



[color="#00FF00"]—>WITH THIS UGLY HACK <_< [/color]




class TENANT_Page extends CActiveRecord

{

[...]

        public function saveCustom(){

            $table=tableName(); //

            $val=$this->pageName.','.$this->pageTitle.','.$this->IDtemplate;

            

            $dns=$this->getDbConnection()->connectionString;  

            $connection=new CDbConnection( $dns,'username','password');

            $connection->active=true;

                yii::app()->toolbox->alert('dddd');

             

            $sql="INSERT INTO $table (pageName, pageTitle,IDtemplate) VALUES($val)";

           

            $command=$connection->createCommand($sql);

            $command->query();

            $connection->active=false;

           /* */return true;

        }



Why the save(false) method doesn’t work!? I tried to crack this problem for a while now… All this is pretty straight forward…

When you call save(false), does it hit your overridden getDbConnection method?

Also, the default implementation assigns the connection to a static property $db




public function getDbConnection()

{

    if(self::$db!==null)

        return self::$db;

    else

    {

        self::$db=Yii::app()->getDb();

        if(self::$db instanceof CDbConnection)

            return self::$db;

        else

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

    }

}



I can’t see any other instances that property is used, but you probably want to assign it too.





/* Overridden */  

public function getDbConnection()

{

	parent::$db = Yii::app()->dynamicDB->getTenantConnection($this->tenantID); 


	return parent::$db;

}



Matt

I haven’t read it all, I must confess. Also, I recommend against “ugly hacks” (as you say).

Maybe the simple procedure described in this short wiki article could help you (only if its validation issue).

In any case, use your Yii system logging to help you debug the problem.

Waterloomatt, Boaz… Thank you all for your replies. :)

I’m sorry I haven’t got back to you sooner but I had a lot of work these past few days.

Yes it does! I can trace it all the way there!

I can’t see any other instances that property is used, but you probably want to assign it too.

I tried that and nothing is working.

This is the error I have:




SQLSTATE[42S02]: Base table or view not found: 1146 Table 'gtbentre_DB1.GTBtenant' doesn't exist. The SQL statement executed was: SELECT * FROM `GTBtenant` `t` WHERE `t`.`ID`=1 LIMIT 1






/var/www/xxxxxxxxxx/protected/components/DynamicDB.php(23): CActiveRecord->findByPk("1")

18         public function getTenantConnection($tenantID = null)

19         {

20                 if ($tenantID == null){

21                        return Yii::app()->tenant->db;

22                 } else {        

23///////ERROR///////////////$this->externalTenant = GTBtenant::model()->findByPk($tenantID); 

24                        if ($this->externalTenant == null){

25                             Yii::app()->alert->sendAlert(Alert::ERROR_ALERT, 'the tenant ('.$tenantID.') couldnt be found, when requested by class ['.__CLASS__.']');

26                        } else {

27                           

28                           return $this->getDbConnection(  $this->externalTenant->IPaddress,

#4	

–  /var/www/xxxxxxxxxxx/protected/models/TENANT_Layout.php(28): DynamicDB->getTenantConnection("1")

23          }

24          

25          

26          public function getDbConnection()

27          {

28//////////////$this->tenantDB = Yii::app()->dynamicDB->getTenantConnection($this->tenantID); 

29              parent::$db = $this->tenantDB;

30              return $this->tenantDB;

31                         

32          }



[color="#FF0000"]I have 2 DB[/color]

[color="#0000FF"]DB1 = gtbentre_DB1

DB2 = SaaS[/color]

It’s basically trying to get the table GTBtenant(inside [Saas]) from the gtbentre_DB1.

For some reason it mixes connections… Anyone have an idea? :D