DBAL630Test.php 5.18 KB
Newer Older
1 2 3 4
<?php

namespace Doctrine\Tests\DBAL\Functional\Ticket;

5
use Doctrine\DBAL\DBALException;
6
use Doctrine\DBAL\ParameterType;
Sergei Morozov's avatar
Sergei Morozov committed
7
use Doctrine\Tests\DbalFunctionalTestCase;
8
use PDO;
9
use function in_array;
10 11 12 13

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

    protected function setUp()
    {
        parent::setUp();

Sergei Morozov's avatar
Sergei Morozov committed
23
        $platform = $this->connection->getDatabasePlatform()->getName();
24

Sergei Morozov's avatar
Sergei Morozov committed
25
        if (! in_array($platform, ['postgresql'])) {
26 27 28
            $this->markTestSkipped('Currently restricted to PostgreSQL');
        }

29
        try {
Sergei Morozov's avatar
Sergei Morozov committed
30 31
            $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);');
32 33
        } catch (DBALException $e) {
        }
34 35 36 37 38 39
        $this->running = true;
    }

    protected function tearDown()
    {
        if ($this->running) {
Sergei Morozov's avatar
Sergei Morozov committed
40
            $this->connection->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
41
        }
42 43

        parent::tearDown();
44 45 46 47
    }

    public function testBooleanConversionSqlLiteral()
    {
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 58
    }

    public function testBooleanConversionBoolParamRealPrepares()
    {
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 73
    }

    public function testBooleanConversionBoolParamEmulatedPrepares()
    {
Sergei Morozov's avatar
Sergei Morozov committed
74
        $this->connection->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
75

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

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

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

84
        self::assertNotEmpty($id);
85

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

88
        self::assertFalse($row['bool_col']);
89
    }
90

91 92 93 94 95 96 97
    /**
     * @dataProvider booleanTypeConversionWithoutPdoTypeProvider
     */
    public function testBooleanConversionNullParamEmulatedPrepares(
        $statementValue,
        $databaseConvertedValue
    ) {
Sergei Morozov's avatar
Sergei Morozov committed
98
        $this->connection->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
99

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

Sergei Morozov's avatar
Sergei Morozov committed
102
        $stmt = $this->connection->prepare('INSERT INTO dbal630_allow_nulls (bool_col) VALUES(?)');
103
        $stmt->bindValue(1, $platform->convertBooleansToDatabaseValue($statementValue));
104 105
        $stmt->execute();

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

108
        self::assertNotEmpty($id);
109

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

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

    /**
     * @dataProvider booleanTypeConversionUsingBooleanTypeProvider
     */
    public function testBooleanConversionNullParamEmulatedPreparesWithBooleanTypeInBindValue(
        $statementValue,
        $databaseConvertedValue
    ) {
Sergei Morozov's avatar
Sergei Morozov committed
122
        $this->connection->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
123

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

Sergei Morozov's avatar
Sergei Morozov committed
126
        $stmt = $this->connection->prepare('INSERT INTO dbal630_allow_nulls (bool_col) VALUES(?)');
127 128 129 130 131
        $stmt->bindValue(
            1,
            $platform->convertBooleansToDatabaseValue($statementValue),
            ParameterType::BOOLEAN
        );
132 133
        $stmt->execute();

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

136
        self::assertNotEmpty($id);
137

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

140
        self::assertSame($databaseConvertedValue, $row['bool_col']);
141 142 143 144
    }

    /**
     * Boolean conversion mapping provider
Sergei Morozov's avatar
Sergei Morozov committed
145
     *
Sergei Morozov's avatar
Sergei Morozov committed
146
     * @return mixed[][]
147 148 149
     */
    public function booleanTypeConversionUsingBooleanTypeProvider()
    {
Sergei Morozov's avatar
Sergei Morozov committed
150
        return [
151
            // statement value, database converted value result
Sergei Morozov's avatar
Sergei Morozov committed
152 153 154 155
            [true, true],
            [false, false],
            [null, false],
        ];
156 157 158 159
    }

    /**
     * Boolean conversion mapping provider
Sergei Morozov's avatar
Sergei Morozov committed
160
     *
Sergei Morozov's avatar
Sergei Morozov committed
161
     * @return mixed[][]
162 163 164
     */
    public function booleanTypeConversionWithoutPdoTypeProvider()
    {
Sergei Morozov's avatar
Sergei Morozov committed
165
        return [
166
            // statement value, database converted value result
Sergei Morozov's avatar
Sergei Morozov committed
167 168 169 170
            [true, true],
            [false, false],
            [null, null],
        ];
171
    }
172
}