Problema com Multi Bancos

Bom dia,

Estou enfrentando um problema, temos sistema de gerenciamento de conteúdo e estou querendo passar ele pra YII.

Mas, no caso eu teria multi bancos, no nosso servidor temos os dados do cliente (tabela abaixo) e queria configurar o ‘db’ do ‘config/main.php’

para pegar os dados de acesso de acordo com o id do cliente.

Alguma ideia de como fazer isso?

tabela_bancos


| id_banco  |       host      |  nome_banco  |   usuario    |   senha    |

--------------------------------------------------------------------------

|    1      |  189.255.212.4  |   banco_1    |    root      |   123456   |

|    2      |   72.11.12.89   |   cliente    |  cliente_rs  |   x54ds7   | 


'db'=>array(

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

	'emulatePrepare' => true,

	'username' => 'root',

	'password' => '123456',

	'charset' => 'utf8',

),

É só adicionar as conexões no seu arquivo de configuração:


'db'=>array(

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

        'emulatePrepare' => true,

        'username' => 'root',

        'password' => '123456',

        'charset' => 'utf8',

),

'db2'=>array(

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

        'emulatePrepare' => true,

        'username' => 'cliente2',

        'password' => '123456',

        'charset' => 'utf8',

),


'db3'=>array(

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

        'emulatePrepare' => true,

        'username' => 'cliente3',

        'password' => '123456',

        'charset' => 'utf8',

),




Para cada usuário é só chamar um banco que você quer:


 $query = Yii::app()->db2->createCommand("SELECT FROM TABLE");


 $query = Yii::app()->db3->createCommand("SELECT FROM TABLE2");

Já fiz algo parecido para um cliente, usei o module do yii para cada banco de dados. Assim ele separa em separar as views, controllers, models para cada banco.

Guia:

www.yiiframework.com/doc/guide/1.1/en/basics.module

Clayton, a ideia é boa, mas tenho muitos clientes (+100), o arquivo vai ficar muito extenso mesmo!

A idéia é ter uma estrutura fixa para todos, exibindo para cada um dos clientes somente os módulos que ele alugou, então usar:


 $query = Yii::app()->db2->createCommand("SELECT FROM TABLE");


 $query = Yii::app()->db3->createCommand("SELECT FROM TABLE2");

Geraria o problema de repetição de código. Fugiria completamente da POO.

A ideia é:


1° -> o 'db' primeiro com os valores do meu banco,

2° -> confere se o usuário é válido,

3° -> pega os dados na tabela "tabela_bancos" (que passei acima)

4° -> usa os dados dessa tabela no 'db' para fazer alterações no banco do cliente.

Mas é no 4° passo que tá o problema. Como fazer isso?

Gustavo, analise a idéia abaixo e veja se ela te auxilia:

Após identificar o banco para o usuário modifique o componente ‘db’:




$db = 'bd';

$component=Yii::createComponent(array(

	'class' => 'CDbConnection',

	'connectionString' => "mysql:host=localhost;dbname=$db",

	'emulatePrepare' => true,

	'username' => '',

	'password' => '',

	'charset' => 'utf8',

));


Yii::app()->setComponent('db',$component);



FLw

:wq!

Acho a idéia do Thiago uma boa.

Aqui um exemplo de como pode ser feito. Coloque o código no seu components/controller.php


public function init() {   

		   	

                      // Retorna os dados do usuário de acordo com o login	    

			 $dadosUsuario=cliente::model()->find('......'),

                         

		     $banco = dadosUsuario->banco;

			 $usuario= dadosUsuario->usuario;

			 $senha = dadosUsuario->senha;

		   

	        $configuracaoBanco = array(

	                'class'=>'CDbConnection',

	                'connectionString'=>'mysql:host=localhost;dbname=$banco',

	                'username'=> $usuario,

	                'password'=> $senha,

	        );

	        Yii::app()->setComponent('db',Yii::CreateComponent($configuracaoBanco);

	    }

Clayton, perfeito!

Estava fazendo os testes e não conseguia achar o lugar correto para colocar o código que postei, com a sua dica funcionou como previsto.

Gustavo, testa ae e diga se resolveu seu problema.

Vlw!

“Quase” funcionou assim! :lol:

O "components/controller.php" ficou assim:


	public function init()

	{

		if(!Yii::app()->user->isGuest)

		{

			$cliente = Clientes::model()->findByPk(Yii::app()->user->id);

			$configuracaoBanco = array(

			        'class' => 'CDbConnection',

			        'connectionString' => "mysql:host=".$cliente->host.";dbname=".$cliente->banco,

			        'emulatePrepare' => true,

			        'username' => $cliente->usuario,

			        'password' => $cliente->senha,

			        'charset' => 'utf8',

			);

			Yii::app()->setComponent('db',Yii::CreateComponent($configuracaoBanco));

		}

	}



Se eu der:


echo Yii::app()->db->connectionString."<br>";

echo Yii::app()->db->username."<br>";

echo Yii::app()->db->password."<br>";

Aparece certinho todos os dados, mas ainda está fazendo consulta no banco de dados local e não do banco do cliente :o

Existe alguma função de "reload" de componentes?

Gustavo, estranho! Trabalhei com 2 bd(s) aqui variando de acordo com o login.

Teste:




public function init() {

	if (Yii::app()->user->name == 'demo')

		$db = 'teste';

	if (Yii::app()->user->name == 'admin')

		$db = 'teste2';


	if (isset($db)) {

		$component = Yii::createComponent(array(

			'class' => 'CDbConnection',

                        'connectionString' => "mysql:host=localhost;dbname=$db",

			'emulatePrepare' => true,

			'username' => 'teste',

			'password' => 'teste',

			'charset' => 'utf8',

		));

                Yii::app()->setComponent('db', $component);

	}

}



Os 2 bd(s) no exemplo existem em minha estrutura…

Em cada tabela dos db(s) existe uma linha…

No controller do modelo:




public function actionView($id){

	$model = $this->loadModel($id);

	$model->nome = Yii::app()->user->name;

	$model->save();

	$this->render('view',array(

		'model'=>$model,

	));

}



Acessei como ‘admin’ e ‘demo’ e ambos valores foram atualizados para os respectivos bd(s)…

Carreguei um modelo e analisei a conexão:


echo $model->dbConnection;

O bd está variando de acordo com o login…

Flw!

Bom saber que dá certo, mas olha só o meu como tá ficando:

Com o seguinte código:


<?php

echo Yii::app()->db->connectionString."<br>";

echo Yii::app()->db->username."<br>";

echo Yii::app()->db->password."<br>"; 

?>

<?php

echo "<pre>";

print_r($model->dbConnection);

?>

Tenho essa saída:


mysql:host=xxx.xxx.xxx.xxx;dbname=banco2

usuario_teste

252536


CDbConnection Object

(

    [connectionString] => mysql:host=localhost;dbname=banco1

    [username] => root

    [password] => 123456

    [schemaCachingDuration] => 0

    [schemaCachingExclude] => Array

        (

        )



O componente ‘db’ é a conexão do banco padrão do Yii. Ao invés de usá-la você mesmo pode fazer a conexão com o banco de acordo com o login do usuário.




$connection=new CDbConnection($dsn,$username,$password);



www.yiiframework.com/doc/api/1.1/CDbConnection#init-detail

Existe um forma tb que vc pode trabalhar com subdominio, fiz um sistema que trabalha desta forma.

Segue o Wiki:

http://www.yiiframework.com/wiki/200/sub-domains-with-different-databases-in-yii

Fica mais personalizado.

Falow