PortabilityTest.php 5.61 KB
Newer Older
1 2 3 4
<?php

namespace Doctrine\Tests\DBAL\Functional;

5
use Doctrine\DBAL\ColumnCase;
6 7
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager;
8
use Doctrine\DBAL\FetchMode;
9
use Doctrine\DBAL\Portability\Connection as ConnectionPortability;
Sergei Morozov's avatar
Sergei Morozov committed
10 11 12
use Doctrine\DBAL\Schema\Table;
use Doctrine\Tests\DbalFunctionalTestCase;
use Throwable;
13
use function strlen;
14 15 16 17

/**
 * @group DBAL-56
 */
Sergei Morozov's avatar
Sergei Morozov committed
18
class PortabilityTest extends DbalFunctionalTestCase
19
{
Sergei Morozov's avatar
Sergei Morozov committed
20
    /** @var Connection */
21
    private $portableConnection;
22

23
    protected function tearDown() : void
24 25 26 27
    {
        if ($this->portableConnection) {
            $this->portableConnection->close();
        }
28 29

        parent::tearDown();
30
    }
31

32
    private function getPortableConnection(
33 34 35
        int $portabilityMode = ConnectionPortability::PORTABILITY_ALL,
        int $case = ColumnCase::LOWER
    ) : Connection {
Sergei Morozov's avatar
Sergei Morozov committed
36
        if (! $this->portableConnection) {
Sergei Morozov's avatar
Sergei Morozov committed
37
            $params = $this->connection->getParams();
38 39 40 41 42

            $params['wrapperClass'] = ConnectionPortability::class;
            $params['portability']  = $portabilityMode;
            $params['fetch_case']   = $case;

Sergei Morozov's avatar
Sergei Morozov committed
43
            $this->portableConnection = DriverManager::getConnection($params, $this->connection->getConfiguration(), $this->connection->getEventManager());
44 45

            try {
Sergei Morozov's avatar
Sergei Morozov committed
46
                $table = new Table('portability_table');
47
                $table->addColumn('Test_Int', 'integer');
Sergei Morozov's avatar
Sergei Morozov committed
48 49 50
                $table->addColumn('Test_String', 'string', ['fixed' => true, 'length' => 32]);
                $table->addColumn('Test_Null', 'string', ['notnull' => false]);
                $table->setPrimaryKey(['Test_Int']);
51 52 53 54

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

Sergei Morozov's avatar
Sergei Morozov committed
55 56 57
                $this->portableConnection->insert('portability_table', ['Test_Int' => 1, 'Test_String' => 'foo', 'Test_Null' => '']);
                $this->portableConnection->insert('portability_table', ['Test_Int' => 2, 'Test_String' => 'foo  ', 'Test_Null' => null]);
            } catch (Throwable $e) {
58 59
            }
        }
60

61 62
        return $this->portableConnection;
    }
63

64
    public function testFullFetchMode() : void
65 66 67
    {
        $rows = $this->getPortableConnection()->fetchAll('SELECT * FROM portability_table');
        $this->assertFetchResultRows($rows);
68

69
        $stmt = $this->getPortableConnection()->query('SELECT * FROM portability_table');
70 71
        $stmt->setFetchMode(FetchMode::ASSOCIATIVE);

72 73 74 75 76
        foreach ($stmt as $row) {
            $this->assertFetchResultRow($row);
        }

        $stmt = $this->getPortableConnection()->query('SELECT * FROM portability_table');
77 78

        while (($row = $stmt->fetch(FetchMode::ASSOCIATIVE))) {
79 80
            $this->assertFetchResultRow($row);
        }
81

82 83
        $stmt = $this->getPortableConnection()->prepare('SELECT * FROM portability_table');
        $stmt->execute();
84 85

        while (($row = $stmt->fetch(FetchMode::ASSOCIATIVE))) {
86 87 88
            $this->assertFetchResultRow($row);
        }
    }
89

90
    public function testConnFetchMode() : void
91 92
    {
        $conn = $this->getPortableConnection();
93
        $conn->setFetchMode(FetchMode::ASSOCIATIVE);
94 95 96 97 98 99

        $rows = $conn->fetchAll('SELECT * FROM portability_table');
        $this->assertFetchResultRows($rows);

        $stmt = $conn->query('SELECT * FROM portability_table');
        foreach ($stmt as $row) {
Sergei Morozov's avatar
Sergei Morozov committed
100
            $this->assertFetchResultRow($row);
101 102 103 104
        }

        $stmt = $conn->query('SELECT * FROM portability_table');
        while (($row = $stmt->fetch())) {
Sergei Morozov's avatar
Sergei Morozov committed
105
            $this->assertFetchResultRow($row);
106 107 108 109 110
        }

        $stmt = $conn->prepare('SELECT * FROM portability_table');
        $stmt->execute();
        while (($row = $stmt->fetch())) {
Sergei Morozov's avatar
Sergei Morozov committed
111
            $this->assertFetchResultRow($row);
112 113 114
        }
    }

115 116 117 118
    /**
     * @param array<int, array<string, mixed>> $rows
     */
    private function assertFetchResultRows(array $rows) : void
119
    {
Gabriel Caruso's avatar
Gabriel Caruso committed
120
        self::assertCount(2, $rows);
jeroendedauw's avatar
jeroendedauw committed
121
        foreach ($rows as $row) {
122 123 124
            $this->assertFetchResultRow($row);
        }
    }
125

126 127 128 129
    /**
     * @param array<string, mixed> $row
     */
    public function assertFetchResultRow(array $row) : void
130
    {
Sergei Morozov's avatar
Sergei Morozov committed
131 132 133
        self::assertContains($row['test_int'], [1, 2], 'Primary key test_int should either be 1 or 2.');
        self::assertArrayHasKey('test_string', $row, 'Case should be lowered.');
        self::assertEquals(3, strlen($row['test_string']), 'test_string should be rtrimed to length of three for CHAR(32) column.');
134
        self::assertNull($row['test_null']);
Sergei Morozov's avatar
Sergei Morozov committed
135
        self::assertArrayNotHasKey(0, $row, 'The row should not contain numerical keys.');
136
    }
137

138
    /**
Sergei Morozov's avatar
Sergei Morozov committed
139 140
     * @param mixed[] $expected
     *
141 142
     * @dataProvider fetchAllColumnProvider
     */
143
    public function testFetchAllColumn(string $field, array $expected) : void
144 145 146 147
    {
        $conn = $this->getPortableConnection();
        $stmt = $conn->query('SELECT ' . $field . ' FROM portability_table');

148
        $column = $stmt->fetchAll(FetchMode::COLUMN);
149
        self::assertEquals($expected, $column);
150 151
    }

152 153 154 155
    /**
     * @return iterable<string, array<int, mixed>>
     */
    public static function fetchAllColumnProvider() : iterable
156
    {
Sergei Morozov's avatar
Sergei Morozov committed
157 158
        return [
            'int' => [
159
                'Test_Int',
Sergei Morozov's avatar
Sergei Morozov committed
160 161 162
                [1, 2],
            ],
            'string' => [
163
                'Test_String',
Sergei Morozov's avatar
Sergei Morozov committed
164 165 166
                ['foo', 'foo'],
            ],
        ];
167 168
    }

169
    public function testFetchAllNullColumn() : void
170 171 172 173
    {
        $conn = $this->getPortableConnection();
        $stmt = $conn->query('SELECT Test_Null FROM portability_table');

174
        $column = $stmt->fetchAll(FetchMode::COLUMN);
Sergei Morozov's avatar
Sergei Morozov committed
175
        self::assertSame([null, null], $column);
176
    }
177
}