MasterSlaveConnectionTest.php 5.36 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

/**
 * @group DBAL-20
 */
class MasterSlaveConnectionTest extends DbalFunctionalTestCase
{
14
    protected function setUp()
15 16 17
    {
        parent::setUp();

18 19 20 21 22
        $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));
23 24 25 26 27 28 29 30 31 32 33
        }

        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);

34

35 36
        } catch(\Exception $e) {
        }
37 38 39

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

42 43 44 45 46 47
    private function createMasterSlaveConnection(bool $keepSlave = false) : MasterSlaveConnection
    {
        return DriverManager::getConnection($this->createMasterSlaveConnectionParams($keepSlave));
    }

    private function createMasterSlaveConnectionParams(bool $keepSlave = false) : array
48 49
    {
        $params = $this->_conn->getParams();
50 51 52
        $params['master']       = $params;
        $params['slaves']       = array($params, $params);
        $params['keepSlave']    = $keepSlave;
53 54 55 56 57 58 59 60 61 62 63
        $params['wrapperClass'] = MasterSlaveConnection::class;

        return $params;
    }

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

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
        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))
            );
        }
88 89 90 91 92 93
    }

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

94
        self::assertFalse($conn->isConnectedToMaster());
95
        $conn->connect('slave');
96
        self::assertFalse($conn->isConnectedToMaster());
97
        $conn->connect('master');
98
        self::assertTrue($conn->isConnectedToMaster());
99 100 101 102 103 104 105 106 107 108
    }

    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);

109 110
        self::assertEquals(1, $data[0]['num']);
        self::assertFalse($conn->isConnectedToMaster());
111 112 113 114 115 116 117
    }

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

118
        self::assertTrue($conn->isConnectedToMaster());
119 120 121 122 123

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

124 125
        self::assertEquals(2, $data[0]['num']);
        self::assertTrue($conn->isConnectedToMaster());
126
    }
127 128 129 130 131 132 133 134

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

136
        $conn->beginTransaction();
137
        $conn->insert('master_slave_table', array('test_int' => 30));
138
        $conn->commit();
139

140
        self::assertTrue($conn->isConnectedToMaster());
141 142

        $conn->connect();
143
        self::assertTrue($conn->isConnectedToMaster());
144 145

        $conn->connect('slave');
146
        self::assertFalse($conn->isConnectedToMaster());
147
    }
148 149 150 151 152 153 154 155 156 157 158

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

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

159
        self::assertTrue($conn->isConnectedToMaster());
160 161

        $conn->connect();
162
        self::assertTrue($conn->isConnectedToMaster());
163 164

        $conn->connect('slave');
165
        self::assertFalse($conn->isConnectedToMaster());
166
    }
167 168 169 170 171

    public function testMasterSlaveConnectionCloseAndReconnect()
    {
        $conn = $this->createMasterSlaveConnection();
        $conn->connect('master');
172
        self::assertTrue($conn->isConnectedToMaster());
173 174

        $conn->close();
175
        self::assertFalse($conn->isConnectedToMaster());
176 177

        $conn->connect('master');
178
        self::assertTrue($conn->isConnectedToMaster());
179
    }
180
}