Konfigurace databáze pomocí factory
- jtousek
- Člen | 951
Nějak se neumím dostat přes následující problém. Potřebuji vytvářet Connection pomocí factory, v configu mám něco jako toto:
services:
database:
class: Nette\Database\Connection
factory: DbFactory::createConnection
Problém je, že v té továrně DbFactory::createConnection mám pak natvrdo toto:
$dsn = $container->expand('%database.driver%:host=%database.host%;dbname=%database.dbname%');
Tento zápis bere přímo jednotlivé složky patametru database
z configu. Moje aplikace se ale potřebuje připojit k více
databázím najednou (a connection je vždy nutné vytvořit přes tuto
továrnu) takže potřebuji té továrně nějak předat informaci, který
parametr z configu má použít. Jak na to?
Editoval jtousek (29. 6. 2012 22:12)
- Filip Procházka
- Moderator | 4668
Vsadím boty že to jde udělat lépe ;)
class ConnectionPool extends Nette\Object
{
private $connections = array();
private $configs = array();
public function __construct($configs)
{
$this->configs = $config;
}
public function getConnection($name = "default")
{
if (!isset($this->connections[$name]) {
$this->connections[$name] = $this->createConnection($name);
}
return $this->connections[$name];
}
protected function createConnection($name)
{
// if (!isset($this->configs[$name])) throw ...
$config = $this->configs[$name];
return new Nette\Database\Connection(
$config['driver'] . ":host=" . $config['host'] . ";dbname=" . $config['dbname'],
$config['username'],
$config['password']
);
}
}
nastavím
parameters:
database:
default:
host: ...
user
foo:
...
bar:
...
services:
connectionPoll:
class: ConnectionPool(%database%)
použvám
$fooConnection = $this->context->connectionPool->getConnection('foo');
Editoval HosipLan (30. 6. 2012 11:10)
- jtousek
- Člen | 951
Jde to udělat jinak, prostě jsem kód té továrny přesunul do konstruktoru poděděné Connection, zda je to lépe si nejsem úplně jistý.
Zaráží mne ale, že tento příklad je uveden v dokumentaci. Pokud tohle řešení neumožňuje připojení k více databázím najednou tak myslím, že v dokumentaci nemá co dělat.
Editoval jtousek (30. 6. 2012 11:23)
- Filip Procházka
- Moderator | 4668
Bože… tak to jsme se nepochopili :) ty chceš vytvářet pomocí factory method. Nevíš, proč jsem si v jednu ráno myslel, že chceš použít DIC factories? Promiň :)
Pomocí statické funkce
services:
database:
class: Nette\Database\Connection
factory: DbFactory::createConnection
arguments:
- "%database.driver%:host=%database.host%;dbname=%database.dbname%"
- %database.username%
- %database.password%
No tak to tam předej všechno, a pak si s tím pracuj jako s polem, tak jak jsem to udělal v tom příkladu
services:
database:
class: Nette\Database\Connection
factory: DbFactory::createConnection(%database%)
Každopádně, Nette nativně podporuje vytváření libovolného množství connections.
Editoval HosipLan (30. 6. 2012 11:16)
- jtousek
- Člen | 951
Aha, tak to pak jo. :-)
Akorát si nejsem jistej zda tohle bude fungovat… DI Container předává té factory jako první argument sám sebe, takže ta factory pak vypadá takto:
public static function createConnection(\Nette\DI\Container $container)
{
//...
$service = new \Nette\Database\Connection(...);
//...
return $service;
}
Co by s tím udělalo to
factory: DbFactory::createConnection(%database%)
? Předalo by se
%database% místo toho containeru? Nebo jako druhý parametr? Nebo by to
nefungovalo vůbec?
Ono už je to jedno, to řešení přes poděděnou Connection má pro mne ještě jinou výhodu takže to asi stejně nechám tak. :-)
- duke
- Člen | 650
Řeším podobný problém a mám dotaz. Když chci nahradit
Nette\Database\Connection
za jinou třídu (vylepšeného potomka),
musím parametry k databázi vyhodit ze sekce Nette
a dát je
přímo pod sekci parameters
, abych se na ně pak mohl odkazovat ve
své definici služby (např. nette.database.default
) v configu?
Nebo je pak lepší nette.database
úplně obejít a udělat si
vlastní databázové služby či rovnou vlastní extension?