Completed
Pull Request — master (#3133)
by Michael
63:30
created

BinaryTest::select()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\DBAL\Functional\Types;
6
7
use Doctrine\DBAL\Driver\IBMDB2\DB2Driver;
8
use Doctrine\DBAL\Driver\OCI8\Driver as OCI8Driver;
9
use Doctrine\DBAL\ParameterType;
10
use Doctrine\DBAL\Schema\Table;
11
use Doctrine\Tests\DbalFunctionalTestCase;
12
use function is_resource;
13
use function random_bytes;
14
use function str_replace;
15
use function stream_get_contents;
16
17
class BinaryTest extends DbalFunctionalTestCase
18
{
19
    protected function setUp()
20
    {
21
        parent::setUp();
22
23
        /** @see https://github.com/doctrine/dbal/issues/2787 */
24
        if ($this->_conn->getDriver() instanceof OCI8Driver) {
25
            $this->markTestSkipped('Filtering by binary fields is currently not supported on Oracle');
26
        }
27
28
        $table = new Table('binary_table');
29
        $table->addColumn('id', 'binary', [
30
            'length' => 16,
31
            'fixed' => true,
32
        ]);
33
        $table->addColumn('val', 'binary', ['length' => 64]);
34
        $table->setPrimaryKey(['id']);
35
36
        $sm = $this->_conn->getSchemaManager();
37
        $sm->dropAndCreateTable($table);
38
    }
39
40
    public function testInsertAndSelect()
41
    {
42
        $id1 = random_bytes(16);
43
        $id2 = random_bytes(16);
44
45
        $value1 = random_bytes(64);
46
        $value2 = random_bytes(64);
47
48
        /** @see https://bugs.php.net/bug.php?id=76322 */
49
        if ($this->_conn->getDriver() instanceof DB2Driver) {
50
            $value1 = str_replace("\x00", "\xFF", $value1);
51
            $value2 = str_replace("\x00", "\xFF", $value2);
52
        }
53
54
        $this->insert($id1, $value1);
55
        $this->insert($id2, $value2);
56
57
        $this->assertSame($value1, $this->select($id1));
58
        $this->assertSame($value2, $this->select($id2));
59
    }
60
61
    private function insert(string $id, string $value) : void
62
    {
63
        $result = $this->_conn->insert('binary_table', [
64
            'id'  => $id,
65
            'val' => $value,
66
        ], [
67
            ParameterType::LARGE_OBJECT,
68
            ParameterType::LARGE_OBJECT,
69
        ]);
70
71
        self::assertSame(1, $result);
72
    }
73
74
    private function select(string $id)
75
    {
76
        $value = $this->_conn->fetchColumn(
77
            'SELECT val FROM binary_table WHERE id = ?',
78
            [$id],
79
            0,
80
            [ParameterType::LARGE_OBJECT]
81
        );
82
83
        // Currently, `BinaryType` mistakenly converts string values fetched from the DB to a stream.
84
        // It should be the opposite. Streams should be used to represent large objects, not binary
85
        // strings. The confusion comes from the PostgreSQL's type system where binary strings and
86
        // large objects are represented by the same BYTEA type
87
        if (is_resource($value)) {
0 ignored issues
show
introduced by
The condition is_resource($value) is always false.
Loading history...
88
            $value = stream_get_contents($value);
89
        }
90
91
        return $value;
92
    }
93
}
94