MasterSlaveConnectionTest.php 5.5 KB
Newer Older
1 2 3 4
<?php

namespace Doctrine\Tests\DBAL\Functional;

5
use Doctrine\DBAL\Connections\MasterSlaveConnection;
6
use Doctrine\DBAL\DriverManager;
jeroendedauw's avatar
jeroendedauw committed
7
use Doctrine\Tests\DbalFunctionalTestCase;
8 9 10 11 12 13
use const CASE_LOWER;
use function array_change_key_case;
use function sprintf;
use function strlen;
use function strtolower;
use function substr;
14 15 16 17 18 19

/**
 * @group DBAL-20
 */
class MasterSlaveConnectionTest extends DbalFunctionalTestCase
{
20
    protected function setUp()
21 22 23
    {
        parent::setUp();

24 25 26 27 28
        $platformName = $this->_conn->getDatabasePlatform()->getName();

        // This is a MySQL specific test, skip other vendors.
        if ($platformName != 'mysql') {
            $this->markTestSkipped(sprintf('Test does not work on %s.', $platformName));
29 30 31 32 33 34 35 36 37 38 39
        }

        try {
            /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
            $table = new \Doctrine\DBAL\Schema\Table("master_slave_table");
            $table->addColumn('test_int', 'integer');
            $table->setPrimaryKey(array('test_int'));

            $sm = $this->_conn->getSchemaManager();
            $sm->createTable($table);

40

41 42
        } catch(\Exception $e) {
        }
43 44 45

        $this->_conn->executeUpdate('DELETE FROM master_slave_table');
        $this->_conn->insert('master_slave_table', array('test_int' => 1));
46 47
    }

48 49 50 51 52 53
    private function createMasterSlaveConnection(bool $keepSlave = false) : MasterSlaveConnection
    {
        return DriverManager::getConnection($this->createMasterSlaveConnectionParams($keepSlave));
    }

    private function createMasterSlaveConnectionParams(bool $keepSlave = false) : array
54 55
    {
        $params = $this->_conn->getParams();
56 57 58
        $params['master']       = $params;
        $params['slaves']       = array($params, $params);
        $params['keepSlave']    = $keepSlave;
59 60 61 62 63 64 65 66 67 68 69
        $params['wrapperClass'] = MasterSlaveConnection::class;

        return $params;
    }

    public function testInheritCharsetFromMaster() : void
    {
        $charsets = [
            'utf8',
            'latin1'
        ];
70

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
        foreach ($charsets as $charset) {
            $params = $this->createMasterSlaveConnectionParams();
            $params['master']['charset'] = $charset;

            foreach ($params['slaves'] as $index => $slaveParams) {
                if (isset($slaveParams['charset'])) {
                    unset($params['slaves'][$index]['charset']);
                }
            }

            /** @var MasterSlaveConnection $conn */
            $conn = DriverManager::getConnection($params);
            $conn->connect('slave');

            self::assertFalse($conn->isConnectedToMaster());

            $clientCharset = $conn->fetchColumn('select @@character_set_client as c');

            self::assertSame(
                $charset,
                substr(strtolower($clientCharset), 0, strlen($charset))
            );
        }
94 95 96 97 98 99
    }

    public function testMasterOnConnect()
    {
        $conn = $this->createMasterSlaveConnection();

100
        self::assertFalse($conn->isConnectedToMaster());
101
        $conn->connect('slave');
102
        self::assertFalse($conn->isConnectedToMaster());
103
        $conn->connect('master');
104
        self::assertTrue($conn->isConnectedToMaster());
105 106 107 108 109 110 111 112 113 114
    }

    public function testNoMasterOnExecuteQuery()
    {
        $conn = $this->createMasterSlaveConnection();

        $sql = "SELECT count(*) as num FROM master_slave_table";
        $data = $conn->fetchAll($sql);
        $data[0] = array_change_key_case($data[0], CASE_LOWER);

115 116
        self::assertEquals(1, $data[0]['num']);
        self::assertFalse($conn->isConnectedToMaster());
117 118 119 120 121 122 123
    }

    public function testMasterOnWriteOperation()
    {
        $conn = $this->createMasterSlaveConnection();
        $conn->insert('master_slave_table', array('test_int' => 30));

124
        self::assertTrue($conn->isConnectedToMaster());
125 126 127 128 129

        $sql = "SELECT count(*) as num FROM master_slave_table";
        $data = $conn->fetchAll($sql);
        $data[0] = array_change_key_case($data[0], CASE_LOWER);

130 131
        self::assertEquals(2, $data[0]['num']);
        self::assertTrue($conn->isConnectedToMaster());
132
    }
133 134 135 136 137 138 139 140

    /**
     * @group DBAL-335
     */
    public function testKeepSlaveBeginTransactionStaysOnMaster()
    {
        $conn = $this->createMasterSlaveConnection($keepSlave = true);
        $conn->connect('slave');
141

142
        $conn->beginTransaction();
143
        $conn->insert('master_slave_table', array('test_int' => 30));
144
        $conn->commit();
145

146
        self::assertTrue($conn->isConnectedToMaster());
147 148

        $conn->connect();
149
        self::assertTrue($conn->isConnectedToMaster());
150 151

        $conn->connect('slave');
152
        self::assertFalse($conn->isConnectedToMaster());
153
    }
154 155 156 157 158 159 160 161 162 163 164

    /**
     * @group DBAL-335
     */
    public function testKeepSlaveInsertStaysOnMaster()
    {
        $conn = $this->createMasterSlaveConnection($keepSlave = true);
        $conn->connect('slave');

        $conn->insert('master_slave_table', array('test_int' => 30));

165
        self::assertTrue($conn->isConnectedToMaster());
166 167

        $conn->connect();
168
        self::assertTrue($conn->isConnectedToMaster());
169 170

        $conn->connect('slave');
171
        self::assertFalse($conn->isConnectedToMaster());
172
    }
173 174 175 176 177

    public function testMasterSlaveConnectionCloseAndReconnect()
    {
        $conn = $this->createMasterSlaveConnection();
        $conn->connect('master');
178
        self::assertTrue($conn->isConnectedToMaster());
179 180

        $conn->close();
181
        self::assertFalse($conn->isConnectedToMaster());
182 183

        $conn->connect('master');
184
        self::assertTrue($conn->isConnectedToMaster());
185
    }
186
}