/**
  * Test multiple db resources specified in a local dbResources table
  * loop through each connection specified and request connection info
  * via the connection manager
  */
 public function testLoopThroughDifferentDbResources()
 {
     $dbFactory = \Yii::$app->get('dbFactory');
     $dbResources = DbResource::find()->orderBy('id')->all();
     $counter = 1;
     foreach ($dbResources as $dbResource) {
         $counter++;
         $dbClient = $dbFactory->getConnection($dbResource->resourceName, true);
         $this->assertInstanceOf(Connection::className(), $dbClient);
         $this->assertEquals($dbResource->dbDsn, $dbClient->dsn);
         $this->assertEquals($counter, $dbFactory->getResourceCount());
         // models want to make use of a dbClient connection so add an alias to it
         $this->assertTrue($dbFactory->addResourceAlias($dbResource->resourceName, 'dbClient'));
         // we should be able to get a connection
         $this->assertTrue($dbFactory->connectResource('dbClient'));
         $this->assertTrue($dbFactory->isResourceConnected('dbClient'));
         $this->assertInstanceOf('\\PDO', $dbClient->pdo);
         if ($dbResource->resourceName == 'dbClient1') {
             $this->assertRegExp('/dbTestClient1/', $dbClient->dsn);
         } else {
             $this->assertRegExp('/dbTestClient2/', $dbClient->dsn);
         }
         $customer = new Customer();
         if ($dbResource->resourceName == 'dbClient1') {
             $this->assertTrue(!$customer->hasAttribute('extraField'));
         } else {
             // the customer table for CLIENT2 has an extra extraField attribute
             $this->assertTrue($customer->hasAttribute('extraField'));
         }
         $dbRemoteResource = ClientDbResource::find()->where(['resourceName' => 'dbRemote'])->one();
         $dbParams = array('class' => $dbRemoteResource->dbClass, 'dsn' => $dbRemoteResource->dbDsn, 'username' => $dbRemoteResource->dbUser, 'password' => $dbRemoteResource->dbPass, 'charset' => $dbRemoteResource->dbCharset, 'tablePrefix' => $dbRemoteResource->dbPrefix, 'connect' => false, 'enableSchemaCache' => $dbClient->enableSchemaCache, 'schemaCacheDuration' => $dbClient->schemaCacheDuration, 'schemaCacheExclude' => array(), 'schemaCache' => $dbClient->schemaCache, 'enableQueryCache' => $dbClient->enableQueryCache, 'queryCacheDuration' => $dbClient->queryCacheDuration, 'queryCache' => $dbClient->queryCache, 'emulatePrepare' => NULL);
         $this->assertTrue($dbFactory->addResource('dbRemote', false, false, $dbParams));
         $dbRemote = $dbFactory->getConnection('dbRemote');
         $this->assertInstanceOf(Connection::className(), $dbRemote);
         $this->assertEquals($dbRemoteResource->dbDsn, $dbRemote->dsn);
         $this->assertEquals($counter + 1, $dbFactory->getResourceCount());
         // we should be able to get a connection
         $this->assertTrue($dbFactory->connectResource('dbRemote'));
         $this->assertTrue($dbFactory->isResourceConnected('dbRemote'));
         $this->assertInstanceOf('\\PDO', $dbRemote->pdo);
         if ($dbResource->resourceName == 'dbClient1') {
             $this->assertRegExp('/dbTestRemote1/', $dbRemote->dsn);
         } else {
             $this->assertRegExp('/dbTestRemote2/', $dbRemote->dsn);
         }
         $robot = Robot::findOne(1);
         if ($dbResource->resourceName == 'dbClient1') {
             $this->assertTrue(!$robot->hasAttribute('extraField'));
         } else {
             // the robot table for CLIENT2s dbRemote connection has an extra extraField attribute
             $this->assertTrue($robot->hasAttribute('extraField'));
         }
         $this->assertTrue($dbFactory->removeResourceAlias('dbClient'));
         $this->assertTrue($dbFactory->removeResource('dbRemote'));
     }
     $this->assertTrue($dbFactory->removeAllResources());
     $this->assertEquals(1, $dbFactory->getResourceCount());
     $this->assertTrue($dbFactory->removeAllResources(true));
     $this->assertEquals(0, $dbFactory->getResourceCount());
 }
Ejemplo n.º 2
0
 /**
  * Add a new resource and setup the DB connection
  *
  * @param string $resourceName
  * @param boolean $clientResource default to loading the resource from the clients resources table rather than the master resources table
  * @param boolean $checkServices check services for db connections that have not been registered via the connection manager (default true)
  * @param array|false $dbParams array of parameters for the connection, similar to what would be found in config (default false)
  * @return boolean success
  */
 public function addResource($resourceName, $clientResource = false, $checkServices = true, $dbParams = false)
 {
     if ($checkServices) {
         if ($this->hasService($resourceName)) {
             /* @var Connection $connection */
             $connection = $this->getService($resourceName);
             if ($connection) {
                 $class = get_class($connection);
                 $this->extendResourceArray($resourceName, $connection, $class);
             }
         }
     }
     $resourceNameCheck = $this->getResourceNameByAlias($resourceName);
     if ($resourceName && isset($this->resources['Resources'][$resourceNameCheck])) {
         // resource already exists
         return true;
     } elseif ($resourceName) {
         $dbResource = false;
         if ($dbParams && is_array($dbParams)) {
             // use the dbParams provided
         } elseif ($resourceName == 'dbClient') {
             /*
              * We need to load up the client DB connection and it is not defined as config
              * so we will get the details from the db.clients table
              */
             $dbResource = $this->getService('client');
             if ($dbResource && $dbResource instanceof Client) {
                 // take some default values form the defaul connection (which would have come from config
                 $connection = $this->getConnection();
             }
         } elseif ($clientResource) {
             $client = $this->getService('client');
             if ($client && $client instanceof Client) {
                 $connection = $this->getClientConnection(true);
                 if ($connection && $connection instanceof Connection) {
                     try {
                         $dbResource = ClientDbResource::find()->where(['resourceName' => $resourceName])->one();
                     } catch (YiiDbException $e) {
                         throw new Exception('Unable to load client dbResources');
                     }
                 } else {
                     throw new Exception('No connections to client db available');
                 }
             } else {
                 throw new Exception('No client service available');
             }
         } else {
             $connection = $this->getConnection();
             if ($connection && $connection instanceof Connection) {
                 try {
                     $dbResource = DbResource::find()->where(['resourceName' => $resourceName])->one();
                 } catch (YiiDbException $e) {
                     throw new Exception('Unable to load dbResources');
                 }
             } else {
                 throw new Exception('No connections to load dbResources');
             }
         }
         if ($dbResource) {
             $dbParams = array('class' => $dbResource->dbClass, 'dsn' => $dbResource->dbDsn, 'username' => $dbResource->dbUser, 'password' => $dbResource->dbPass, 'charset' => $dbResource->dbCharset, 'tablePrefix' => $dbResource->dbPrefix, 'connect' => false, 'enableSchemaCache' => $connection->enableSchemaCache, 'schemaCacheDuration' => $connection->schemaCacheDuration, 'schemaCacheExclude' => array(), 'schemaCache' => $connection->schemaCache, 'enableQueryCache' => $connection->enableQueryCache, 'queryCacheDuration' => $connection->queryCacheDuration, 'queryCache' => $connection->queryCache, 'emulatePrepare' => NULL);
         }
         if ($dbParams) {
             if (isset($dbParams['password']) && substr($dbParams['password'], 0, 1) == '#') {
                 $dbParams['password'] = $this->decrypt($dbParams['password']);
             }
             $connection = $this->setupConnection($dbParams);
             if ($connection) {
                 $class = get_class($connection);
                 $this->extendResourceArray($resourceName, $connection, $class, isset($dbParams['connect']) ? $dbParams['connect'] : false);
                 // add resourceName to the service manager as well (setup as not shared)
                 if ($this->hasService($resourceName)) {
                     $this->setService($resourceName, null);
                 }
                 $this->setService($resourceName, $connection);
                 return true;
             }
         } else {
             throw new Exception('Missing dbParams on addResource');
         }
     }
     return false;
 }