Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Master/slave doesn't working with new database/connection.php
  • I got fuelphp by composer, there is a difference with fuelphp which downloaded from fuelphp.com:

    fuel\core\classes\database\connection.php

    public function select(array $args = null)
    {
    $instance = new \Database_Query_Builder_Select($args);
    return $instance->set_connection($this);
    }

    But, in fuel\core\classes\database\query.php

    if ($this->_connection !== null and $db === null)
    {
    $db = $this->_connection;
    }

    So, the select queries always use master connection, slave won't be switched
  • Yes, 

    Packagist (composer) is newer, as it is automatically updated from github, and therefore also contains hotfix releases. The zip on the website is only updated wth official releases, so it is still at 1.8.0.

    I am not sure what you mean with "master" and "slave".

    Fuel uses a readwrite connection (which is the default) and a readonly connection, which can be configured. Which of the two is used in the Database_Connection instance depends on the parameters passed when creating the instance ($writable must be set to false, and the db definition must define a readonly database name).

    So if something doesn't work the way you want it to work, start by showing us what your database conifugration is, and what code you are using to identify the fault.
  • return array('default' => array(
    'type'           => 'pdo',
    'connection'     => array(
    'dsn'            => 'pgsql:host=master.db;dbname=db_master',
    ...,
    ),
    ...,
    'readonly'       => array('slave1'),
    ),
    'slave1' => array(
    'type'           => 'pdo',
    'connection'     => array(
    'dsn'            => 'pgsql:host=slave1.db;dbname=db_slave',
    ...,
    ),
    ...,
    ),
    );

    Because this code:

    public function select(array $args = null)
    {
    $instance = new \Database_Query_Builder_Select($args);
    return $instance->set_connection($this);
    }

    The connection will be re-used and it always connect to master.db not switch to slave1.db. 
    It only work if I modify to:

    public function select(array $args = null)
    {
    return new \Database_Query_Builder_Select($args);
    }
  • And you're using a standard DB::Select() call, not ORM or Model_Crud?
  • I used and tested with both:

    - DB::select()->execute()
    - Orm\Model

    There is the same result: master.db always be connected, no connection to slave1.db
  • Ok. I'll see if I can reproduce it.

    I assume you have defined both readonly and readwrite in your ORM model? I don't think it will use the setting in your db.php, but I'll have to check.
  • Does it work if you do

    \Database_Connection::instance(null, null, false)->select()->execute();

    instead of

    \DB::select()->execute()

    ?
  • I've checked the ORM, if it has separate read and write connections defined, it will explicitly use them by passing the connection to execute() when running the generated query.

    If not, it will use the mechanism used in the database layer. It seems the problem is that the static frontend to the database layer, DB, doesn't use the writable flag when it creates a Database_Connection instance, which if so, the test in my previous post will prove.

    If you can confirm that passing (null, null, false) fixes your problem, I can push a fix to the repo.
  • Before, I used fuelphp 1.7 for my project without master/slave configuration. When I upgrade to fuelphp 1.8, I use master/slave configuration, so I cannot modify all source code to use:

    \Database_Connection::instance(null, null, false)->select()->execute();

    Currently, my solution is:

    Create custom database connection: Database_MyCon_Connection extends Fuel\Core\Database_PDO_Connection

    and then, I re-write the select method to:

    public function select(array $args = null)
    {
        return new \Database_Query_Builder_Select($args);
    }

    Now, it work for me!


  • I didn't say that, I just asked you to test it, and confirm that it will fix your problem.

    Your solution will break the next time you upgrade, as 1.9/dev contains major database changes.
  • HarroHarro
    Accepted Answer
    So, in /fuel/core/classes/db.php, change the select() method to

        public static function select($args = null)
        {
            return \Database_Connection::instance(null, null, false)->select(func_get_args());
        }

    That should solve it the correct way, and if it does, I can commit the fix and perpare a hotfix release.
  • Any feedback on this?
  • So, in /fuel/core/classes/db.php, change the select() method to

        public static function select($args = null)
        {
            return \Database_Connection::instance(null, null, false)->select(func_get_args());
        }

    That should solve it the correct way, and if it does, I can commit the fix and perpare a hotfix release.

    ==> Sorry for my late reply, it works for me with your solution.

    Please also apply it for:

    public static function select_array(array $columns = null)

    I tested with: DB::select(), DB::select_array(), Orm\Model (::find)

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion