Nette database – Výběr aktuální DB (USE database;)
- Lukes
- Silver Partner | 68
Zdravím,
potřeboval bych pomoct s následujícím problémem. Mám 3 databáze na jednom MySQL serveru, a rád bych našel nějaký způsob přepnutí databáze. Jako třeba mysql_select_db() v PHP. V předchozích verzích to šlo vyřešit uvedením prefixu před tabulku metodě table(„databáze2.tabulka“) každopádně v 2.0.7 Nette už mi to hlásí, že table(„databáze1.databáze2.tabulka“) neexistuje.
(QLSTATE[42S02]: Base table or view not found: 1146 Table ‚databáze1.databáze2.tabulka‘ doesn't exist)
Neví někdo co s tím ? Je to poměrně běžná věc, čili je mi divné kdyby to nešlo.
Editoval Lukes (27. 12. 2012 2:45)
- castamir
- Člen | 629
Možná by bylo dobré si udělat nějakou nádstavbu, tzv. model, a v něm volat metody, které provedou konkrétní dotaz z požadované databáze. Údaje k připojení ke všem databázím pak snadno abstrahuješ do configu (DI container) a metody v modelu pak můžeš znovu použít i jinde.
config:
nette:
database:
default:
driver: mysql
host: localhost
dbname: database1
user: john
password: doe
test:
driver: mysql
host: localhost
dbname: database2
user: john
password: doe
services:
myModel: MyModel(@database.default, @database.test)
MyModel.php:
class MyModel extends Nette\Object
{
/** @var Nette\Database\Connection */
protected $database1;
/** @var Nette\Database\Connection */
protected $database2;
public function __construct(Nette\Database\Connection $db1, Nette\Database\Connection $db2)
{
$this->database1 = $db1;
$this->database2 = $db2;
}
public function dotazZprvni()
{
return $this->database1->table(...)...;
}
public function dotazZdruhe()
{
return $this->database2->table(...)...;
}
}
Určitě to půjde zapsat ještě lépe, ale tohle by tě mohlo přinejmenším nasměrovat…
Editoval castamir (27. 12. 2012 7:06)
- thunderbuff
- Člen | 164
A nestačilo by, kdybys do své aplikace pomocí DI dostal správné connection? Pak bys jí nemusel přepisovat vůbec a DI bys využil přesně pro takový případ, pro jaký bylo navrženo.
Config bys měl stejně, jak píše @castamir. Pak bys měl třídu:
<?php
class ConnectionManager extends Nette\Object
{
/** @var Nette\Database\Connection */
protected $database1;
/** @var Nette\Database\Connection */
protected $database2;
public function __construct(Nette\Database\Connection $db1, Nette\Database\Connection $db2)
{
$this->database1 = $db1;
$this->database2 = $db2;
}
public function getDatabase1() {
return $this->database1;
}
public function getDatabase2() {
return $this->database2;
}
}
?>
… a tvá aplikace by přijímala správné connection třeba v konstruktoru:
<?php
$app = new MojeAplikace($connMan->getDatabase1());
?>
Editoval thunderbuff (31. 12. 2012 0:46)
- enumag
- Člen | 2118
@thunderbuff: FUJ!! To co jsi napsal je Service Locator. Jinak tvá myšlenka dát do každého modelu to jedno správné Connection pomocí DI a neonu je samozřejmě správná. Obávám se ale, že daná aplikace pravděpodobně není psaná tímto způsobem a takto jednoduché to zřejmě nebude.
- Lukes
- Silver Partner | 68
Momentálně to mám takto…
public function getTable1(){
$this->database->table("databaze1.tabulka1");
}
public function getTable2(){
$this->database->table("databaze2.tabulka2");
}
A představoval bych si to nějak takto
public function getTable2(){
// USE databaze2 //
$this->database->table("tabulka2");
}
- thunderbuff
- Člen | 164
@enumag: To není service locator v tom „zavrženíhodném“ slova smyslu. Pokud mám v connectionmanageru dvě připojení a obě potřebuji, netahám do aplikace klavír, ale malou krabičku právě na ty dva doutníky. Myslím, že v takovém případě to lze s klidem použít.
// Edit: pokud budou ty připojení jen dvě pevně zadrátovaná v configu, pak ConnectionManager nemá význam, stačí je jen obě injektovat do repository.
Lukes napsal(a):
A představoval bych si to nějak takto
public function getTable2(){ // USE databaze2 // $this->database->table("tabulka2"); }
Při zachování „$this->database->table("tabulka2“);" by šlo „USE DATABASE“ napsat jako setter pro $this->database. Není to vůbec hezké, ale nebudeš muset přepisovat program. Přesto si myslím, že tvé současné řešení je mnohem elegantnější a čístší než to vysněné.
<?php
protected $db1;
protected $db2;
protected function useDatabase1() {
$this->database = &$this->db1;
}
protected function useDatabase2() {
$this->database = &$this->db2;
}
?>
Editoval thunderbuff (31. 12. 2012 10:44)