DBAL630Test.php 5.5 KB
Newer Older
1 2
<?php

3
namespace Doctrine\DBAL\Tests\Functional\Ticket;
4

5
use Doctrine\DBAL\DBALException;
6
use Doctrine\DBAL\ParameterType;
7
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
8
use Doctrine\DBAL\Tests\FunctionalTestCase;
9 10 11 12 13
use PDO;

/**
 * @group DBAL-630
 */
14
class DBAL630Test extends FunctionalTestCase
15
{
Sergei Morozov's avatar
Sergei Morozov committed
16
    /** @var bool */
17 18
    private $running = false;

19
    protected function setUp(): void
20 21 22
    {
        parent::setUp();

23
        if (! $this->connection->getDatabasePlatform() instanceof PostgreSQL94Platform) {
24
            self::markTestSkipped('Currently restricted to PostgreSQL');
25 26
        }

27
        try {
Sergei Morozov's avatar
Sergei Morozov committed
28 29
            $this->connection->exec('CREATE TABLE dbal630 (id SERIAL, bool_col BOOLEAN NOT NULL);');
            $this->connection->exec('CREATE TABLE dbal630_allow_nulls (id SERIAL, bool_col BOOLEAN);');
30 31
        } catch (DBALException $e) {
        }
Grégoire Paris's avatar
Grégoire Paris committed
32

33 34 35
        $this->running = true;
    }

36
    protected function tearDown(): void
37 38
    {
        if ($this->running) {
39 40 41
            $this->connection->getWrappedConnection()
                ->getWrappedConnection()
                ->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
42
        }
43 44

        parent::tearDown();
45 46
    }

47
    public function testBooleanConversionSqlLiteral(): void
48
    {
Sergei Morozov's avatar
Sergei Morozov committed
49 50
        $this->connection->executeUpdate('INSERT INTO dbal630 (bool_col) VALUES(false)');
        $id = $this->connection->lastInsertId('dbal630_id_seq');
51
        self::assertNotEmpty($id);
52

53
        $row = $this->connection->fetchAssociative('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]);
54

55
        self::assertFalse($row['bool_col']);
56 57
    }

58
    public function testBooleanConversionBoolParamRealPrepares(): void
59
    {
Sergei Morozov's avatar
Sergei Morozov committed
60
        $this->connection->executeUpdate(
61
            'INSERT INTO dbal630 (bool_col) VALUES(?)',
Sergei Morozov's avatar
Sergei Morozov committed
62 63
            ['false'],
            [ParameterType::BOOLEAN]
64
        );
Sergei Morozov's avatar
Sergei Morozov committed
65
        $id = $this->connection->lastInsertId('dbal630_id_seq');
66
        self::assertNotEmpty($id);
67

68
        $row = $this->connection->fetchAssociative('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]);
69

70
        self::assertFalse($row['bool_col']);
71 72
    }

73
    public function testBooleanConversionBoolParamEmulatedPrepares(): void
74
    {
75 76 77
        $this->connection->getWrappedConnection()
            ->getWrappedConnection()
            ->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
78

Sergei Morozov's avatar
Sergei Morozov committed
79
        $platform = $this->connection->getDatabasePlatform();
80

Sergei Morozov's avatar
Sergei Morozov committed
81
        $stmt = $this->connection->prepare('INSERT INTO dbal630 (bool_col) VALUES(?)');
82
        $stmt->bindValue(1, $platform->convertBooleansToDatabaseValue('false'), ParameterType::BOOLEAN);
83 84
        $stmt->execute();

Sergei Morozov's avatar
Sergei Morozov committed
85
        $id = $this->connection->lastInsertId('dbal630_id_seq');
86

87
        self::assertNotEmpty($id);
88

89
        $row = $this->connection->fetchAssociative('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]);
90

91
        self::assertFalse($row['bool_col']);
92
    }
93

94 95 96 97
    /**
     * @dataProvider booleanTypeConversionWithoutPdoTypeProvider
     */
    public function testBooleanConversionNullParamEmulatedPrepares(
98 99
        ?bool $statementValue,
        ?bool $databaseConvertedValue
100
    ): void {
101 102 103
        $this->connection->getWrappedConnection()
            ->getWrappedConnection()
            ->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
104

Sergei Morozov's avatar
Sergei Morozov committed
105
        $platform = $this->connection->getDatabasePlatform();
106

Sergei Morozov's avatar
Sergei Morozov committed
107
        $stmt = $this->connection->prepare('INSERT INTO dbal630_allow_nulls (bool_col) VALUES(?)');
108
        $stmt->bindValue(1, $platform->convertBooleansToDatabaseValue($statementValue));
109 110
        $stmt->execute();

Sergei Morozov's avatar
Sergei Morozov committed
111
        $id = $this->connection->lastInsertId('dbal630_allow_nulls_id_seq');
112

113
        self::assertNotEmpty($id);
114

115
        $row = $this->connection->fetchAssociative('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', [$id]);
116

117
        self::assertSame($databaseConvertedValue, $row['bool_col']);
118 119 120 121 122 123
    }

    /**
     * @dataProvider booleanTypeConversionUsingBooleanTypeProvider
     */
    public function testBooleanConversionNullParamEmulatedPreparesWithBooleanTypeInBindValue(
124 125
        ?bool $statementValue,
        bool $databaseConvertedValue
126
    ): void {
127 128 129
        $this->connection->getWrappedConnection()
            ->getWrappedConnection()
            ->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
130

Sergei Morozov's avatar
Sergei Morozov committed
131
        $platform = $this->connection->getDatabasePlatform();
132

Sergei Morozov's avatar
Sergei Morozov committed
133
        $stmt = $this->connection->prepare('INSERT INTO dbal630_allow_nulls (bool_col) VALUES(?)');
134 135 136 137 138
        $stmt->bindValue(
            1,
            $platform->convertBooleansToDatabaseValue($statementValue),
            ParameterType::BOOLEAN
        );
139 140
        $stmt->execute();

Sergei Morozov's avatar
Sergei Morozov committed
141
        $id = $this->connection->lastInsertId('dbal630_allow_nulls_id_seq');
142

143
        self::assertNotEmpty($id);
144

145
        $row = $this->connection->fetchAssociative('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', [$id]);
146

147
        self::assertSame($databaseConvertedValue, $row['bool_col']);
148 149 150 151
    }

    /**
     * Boolean conversion mapping provider
Sergei Morozov's avatar
Sergei Morozov committed
152
     *
Sergei Morozov's avatar
Sergei Morozov committed
153
     * @return mixed[][]
154
     */
155
    public static function booleanTypeConversionUsingBooleanTypeProvider(): iterable
156
    {
Sergei Morozov's avatar
Sergei Morozov committed
157
        return [
158
            // statement value, database converted value result
Sergei Morozov's avatar
Sergei Morozov committed
159 160 161 162
            [true, true],
            [false, false],
            [null, false],
        ];
163 164 165 166
    }

    /**
     * Boolean conversion mapping provider
Sergei Morozov's avatar
Sergei Morozov committed
167
     *
Sergei Morozov's avatar
Sergei Morozov committed
168
     * @return mixed[][]
169
     */
170
    public static function booleanTypeConversionWithoutPdoTypeProvider(): iterable
171
    {
Sergei Morozov's avatar
Sergei Morozov committed
172
        return [
173
            // statement value, database converted value result
Sergei Morozov's avatar
Sergei Morozov committed
174 175 176 177
            [true, true],
            [false, false],
            [null, null],
        ];
178
    }
179
}