Project

General

Profile

Actions

Feature #84971

open

Support for Master slave database using wrapperClass and Doctrine's MasterSlaveConnection class

Added by Simon Ouellet almost 6 years ago. Updated over 1 year ago.

Status:
New
Priority:
Should have
Assignee:
-
Category:
Database API (Doctrine DBAL)
Target version:
-
Start date:
2018-05-11
Due date:
% Done:

0%

Estimated time:
PHP Version:
Tags:
Complexity:
Sprint Focus:

Description

It would be awesome to provide a wrapperClass for $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'] that support Doctrine\DBAL\Connections\MasterSlaveConnection.php.

I think i have a working prototype bundled into a typo3 extension.

Basically, it is just a class that extends \TYPO3\CMS\Core\Database\Connection containing some of the code from Doctrine\DBAL\Connections\MasterSlaveConnection.php

Actions #1

Updated by Susanne Moog about 4 years ago

  • Status changed from New to Needs Feedback

Can you publish the extension and link it here please?

Actions #2

Updated by Markus Bischof about 4 years ago

I would also be interested in such a feature.

Actions #3

Updated by Simon Ouellet about 4 years ago

https://extensions.typo3.org/extension/tm_masterslave

This is the extension.
I will write un simple configuation README

Actions #4

Updated by Christian Kuhn about 2 years ago

  • Status changed from Needs Feedback to New
Actions #5

Updated by Benni Mack over 1 year ago

This is how we solved it:


class PrimaryReplicaConnection extends \TYPO3\CMS\Core\Database\Connection
{
    public function connect(): bool
    {
        $allParams = $this->getParams();
        try {
            return parent::connect();
        } catch(\Doctrine\DBAL\Exception\ConnectionException $e) {
            if (!isset($allParams['replica'])) {
                throw $e;
            }
        }
        while ($nextReplica = array_shift($allParams['replica'])) {
            $allParams = array_replace_recursive($allParams, $nextReplica);
            $driverOptions = $allParams['driverOptions'] ?? [];
            $user          = $allParams['user'] ?? null;
            $password      = $allParams['password'] ?? null;
            try {
                $this->_conn = $this->_driver->connect($allParams, $user, $password, $driverOptions);
                if ($this->_eventManager->hasListeners(\Doctrine\DBAL\Events::postConnect)) {
                    $eventArgs = new \Doctrine\DBAL\Event\ConnectionEventArgs($this);
                    $this->_eventManager->dispatchEvent(\Doctrine\DBAL\Events::postConnect, $eventArgs);
                }
                return true;
            } catch(\Doctrine\DBAL\Exception\ConnectionException $e) {
                continue;
            }
        }
        // No connection available
        if ($e) {
            throw $e;
        }
    }
}

and in AdditionalConfiguration.php

        $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['host'] = getenv('DB_HOST_NODE1') ?: getenv('TYPO3_DB_HOST');
        $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['dbname'] = getenv('DB_NAME') ?: getenv('TYPO3_DB_DATABASE');
        $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['user'] = getenv('DB_USER') ?: getenv('TYPO3_DB_USERNAME');
        $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['password'] = getenv('DB_PASSWORD') ?: getenv('TYPO3_DB_PASSWORD');
        $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['replica'] = [
            ['user' => getenv('DB_USER'), 'password' => getenv('DB_PASSWORD'), 'host' => getenv('DB_HOST_NODE2'), 'dbname' => getenv('DB_NAME')],
            ['user' => getenv('DB_USER'), 'password' => getenv('DB_PASSWORD'), 'host' => getenv('DB_HOST_NODE3'), 'dbname' => getenv('DB_NAME')],
        ];
        $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['wrapperClass'] = \PrimaryReplicaConnection::class;
Actions

Also available in: Atom PDF