Issues (201)

tests/Functional/Ticket/DBAL630Test.php (1 issue)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\DBAL\Tests\Functional\Ticket;
6
7
use Doctrine\DBAL\DBALException;
8
use Doctrine\DBAL\Driver\PDOConnection;
9
use Doctrine\DBAL\ParameterType;
10
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
11
use Doctrine\DBAL\Tests\FunctionalTestCase;
12
use PDO;
13
use function assert;
14
15
/**
16
 * @group DBAL-630
17
 */
18
class DBAL630Test extends FunctionalTestCase
19
{
20
    /** @var bool */
21
    private $running = false;
22
23
    protected function setUp() : void
24
    {
25
        parent::setUp();
26
27
        if (! $this->connection->getDatabasePlatform() instanceof PostgreSQL94Platform) {
28
            self::markTestSkipped('Currently restricted to PostgreSQL');
29
        }
30
31
        try {
32
            $this->connection->exec('CREATE TABLE dbal630 (id SERIAL, bool_col BOOLEAN NOT NULL);');
33
            $this->connection->exec('CREATE TABLE dbal630_allow_nulls (id SERIAL, bool_col BOOLEAN);');
34
        } catch (DBALException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
35
        }
36
37
        $this->running = true;
38
    }
39
40
    protected function tearDown() : void
41
    {
42
        if ($this->running) {
43
            $pdo = $this->getPDO();
44
45
            $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
46
        }
47
48
        parent::tearDown();
49
    }
50
51
    public function testBooleanConversionSqlLiteral() : void
52
    {
53
        $this->connection->executeUpdate('INSERT INTO dbal630 (bool_col) VALUES(false)');
54
        $id = $this->connection->lastInsertId('dbal630_id_seq');
55
        self::assertNotEmpty($id);
56
57
        $row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]);
58
59
        self::assertIsArray($row);
60
        self::assertFalse($row['bool_col']);
61
    }
62
63
    public function testBooleanConversionBoolParamRealPrepares() : void
64
    {
65
        $this->connection->executeUpdate(
66
            'INSERT INTO dbal630 (bool_col) VALUES(?)',
67
            ['false'],
68
            [ParameterType::BOOLEAN]
69
        );
70
        $id = $this->connection->lastInsertId('dbal630_id_seq');
71
        self::assertNotEmpty($id);
72
73
        $row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]);
74
75
        self::assertIsArray($row);
76
        self::assertFalse($row['bool_col']);
77
    }
78
79
    public function testBooleanConversionBoolParamEmulatedPrepares() : void
80
    {
81
        $pdo = $this->getPDO();
82
        $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
83
84
        $platform = $this->connection->getDatabasePlatform();
85
86
        $stmt = $this->connection->prepare('INSERT INTO dbal630 (bool_col) VALUES(?)');
87
        $stmt->bindValue(1, $platform->convertBooleansToDatabaseValue('false'), ParameterType::BOOLEAN);
88
        $stmt->execute();
89
90
        $id = $this->connection->lastInsertId('dbal630_id_seq');
91
92
        self::assertNotEmpty($id);
93
94
        $row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]);
95
96
        self::assertIsArray($row);
97
        self::assertFalse($row['bool_col']);
98
    }
99
100
    /**
101
     * @dataProvider booleanTypeConversionWithoutPdoTypeProvider
102
     */
103
    public function testBooleanConversionNullParamEmulatedPrepares(
104
        ?bool $statementValue,
105
        ?bool $databaseConvertedValue
106
    ) : void {
107
        $pdo = $this->getPDO();
108
        $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
109
110
        $platform = $this->connection->getDatabasePlatform();
111
112
        $stmt = $this->connection->prepare('INSERT INTO dbal630_allow_nulls (bool_col) VALUES(?)');
113
        $stmt->bindValue(1, $platform->convertBooleansToDatabaseValue($statementValue));
114
        $stmt->execute();
115
116
        $id = $this->connection->lastInsertId('dbal630_allow_nulls_id_seq');
117
118
        self::assertNotEmpty($id);
119
120
        $row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', [$id]);
121
122
        self::assertIsArray($row);
123
        self::assertSame($databaseConvertedValue, $row['bool_col']);
124
    }
125
126
    /**
127
     * @dataProvider booleanTypeConversionUsingBooleanTypeProvider
128
     */
129
    public function testBooleanConversionNullParamEmulatedPreparesWithBooleanTypeInBindValue(
130
        ?bool $statementValue,
131
        bool $databaseConvertedValue
132
    ) : void {
133
        $pdo = $this->getPDO();
134
        $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
135
136
        $platform = $this->connection->getDatabasePlatform();
137
138
        $stmt = $this->connection->prepare('INSERT INTO dbal630_allow_nulls (bool_col) VALUES(?)');
139
        $stmt->bindValue(
140
            1,
141
            $platform->convertBooleansToDatabaseValue($statementValue),
142
            ParameterType::BOOLEAN
143
        );
144
        $stmt->execute();
145
146
        $id = $this->connection->lastInsertId('dbal630_allow_nulls_id_seq');
147
148
        self::assertNotEmpty($id);
149
150
        $row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', [$id]);
151
152
        self::assertIsArray($row);
153
        self::assertSame($databaseConvertedValue, $row['bool_col']);
154
    }
155
156
    /**
157
     * Boolean conversion mapping provider
158
     *
159
     * @return mixed[][]
160
     */
161
    public static function booleanTypeConversionUsingBooleanTypeProvider() : iterable
162
    {
163
        return [
164
            // statement value, database converted value result
165
            [true, true],
166
            [false, false],
167
            [null, false],
168
        ];
169
    }
170
171
    /**
172
     * Boolean conversion mapping provider
173
     *
174
     * @return mixed[][]
175
     */
176
    public static function booleanTypeConversionWithoutPdoTypeProvider() : iterable
177
    {
178
        return [
179
            // statement value, database converted value result
180
            [true, true],
181
            [false, false],
182
            [null, null],
183
        ];
184
    }
185
186
    private function getPDO() : PDO
187
    {
188
        $wrappedConnection = $this->connection->getWrappedConnection();
189
        assert($wrappedConnection instanceof PDOConnection);
190
191
        return $wrappedConnection->getWrappedConnection();
192
    }
193
}
194