Connect to multiple datases

2 years ago

akrall
Member | 6
+
0
-

Im trying to connect to multiple databases, so far I have:

parameters:

database:
    default:
        dsn: 'mysql:host=127.0.0.1;dbname=pbx'
        user: 'xx'
        password: 'rxxoot'
        options:
            lazy: yes
    db2:
        dsn: 'mysql:host=127.0.0.1;dbname=pbx2'
        user: 'xx'
        password: 'xx'
        options:
            lazy: yes

But then what? how do I actually use this on different databases:

class HomepagePresenter extends Nette\Application\UI\Presenter
{
    /** @var Nette\Database\Context */
    private $database;

    public function __construct(Nette\Database\Context $database)
    {
        $this->database = $database;
    }

    public function renderDefault()
    {
        $this->template->posts = $this->database->table('log_cdr')
            ->order('started DESC')
            ->limit(50);
    }
}

This only works on the default database, how do I query db2?

2 years ago

David Matějka
Moderator | 5729
+
0
-

Hi,
only the first db connection is automatically autowired. when you need to pass the second connection, you have to do it manually.

e.g. if you need to pass db2 to HomepagePresenter, just register it as a service and select second db connection:

services:
    - HomepagePresenter(@database.db2.context)

2 years ago

akrall
Member | 6
+
0
-

David Matějka wrote:

Hi,
only the first db connection is automatically autowired. when you need to pass the second connection, you have to do it manually.

e.g. if you need to pass db2 to HomepagePresenter, just register it as a service and select second db connection:

services:
  - HomepagePresenter(@database.db2.context)

How do you select it? to use in something like this:

<?php
$this->template->posts = $this->database->table('log_cdr')
            ->order('started DESC')
            ->limit(50);
?>

2 years ago

akrall
Member | 6
+
0
-

BTW, I added:

services
App\Model\UserManager
App\Forms\FormFactory
App\Forms\SignInFormFactory
App\Forms\SignUpFormFactory
HomepagePresenter(@database.db2.context)

router: App\RouterFactory::createRouter

to config.neon and now I get this error:

Class HomepagePresenter used in service ‘32_HomepagePresenter’ not found

2 years ago

akrall
Member | 6
+
0
-

I figured it out and hope it helps somebody else.

The solution was quite simple and elegant but it is not mentioned in any document.

Here is what your config.local.neon should look like:

<?php

parameters:

database:
    default:
        dsn: 'mysql:host=127.0.0.1;dbname=xxx'
        user: 'xxx'
        password: 'xxx'
        options:
            lazy: yes
    <name of your database dsn>:
        dsn: 'mysql:host=host.domain.com;dbname=xxx'
        user: 'xxx'
        password: 'xxx'
        options:
            lazy: yes

?>

Here its config.neon:

<?php
services:
    - App\Model\UserManager
    - App\Forms\FormFactory
    - App\Forms\SignInFormFactory
    - App\Forms\SignUpFormFactory
    router: App\RouterFactory::createRouter
    - App\Presenters\HomepagePresenter(@database.<name of your database dsn>.context)
?>

Where App\Presenters\HomepagePresenter is the route to your presenter php file.
@database.<name of your database dsn>.context (where is the needed part, .context tells Nette that the returned content should be a context, if not specified, a connection content is returned)

and last:

<?php
class HomepagePresenter extends Nette\Application\UI\Presenter
{
    /** @var Nette\Database\Context */
    private $database;

    public function __construct(Nette\Database\Context $<name of your database dsn>)
    {
        $this->database = $<name of your database dsn>;
    }

    public function renderDefault()
    {

        $this->template->posts = $this->database->table('xxx')
            ->order('started DESC')
            ->limit(50);
        }
}
?>

Hope it helps!

2 years ago

CZechBoY
Member | 3231
+
0
-

Parameter name in presenter constructor is on you. Only position od parameter is important in this case.