DBAL630Test.php 5.48 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) {
        }
32 33 34
        $this->running = true;
    }

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

        parent::tearDown();
44 45
    }

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

Sergei Morozov's avatar
Sergei Morozov committed
52
        $row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]);
53

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

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

Sergei Morozov's avatar
Sergei Morozov committed
67
        $row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]);
68

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

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

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

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

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

86
        self::assertNotEmpty($id);
87

Sergei Morozov's avatar
Sergei Morozov committed
88
        $row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630 WHERE id = ?', [$id]);
89

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

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

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

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

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

112
        self::assertNotEmpty($id);
113

Sergei Morozov's avatar
Sergei Morozov committed
114
        $row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', [$id]);
115

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

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

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

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

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

142
        self::assertNotEmpty($id);
143

Sergei Morozov's avatar
Sergei Morozov committed
144
        $row = $this->connection->fetchAssoc('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', [$id]);
145

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

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

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