Completed
Push — develop ( 40c4f3...ed7ad1 )
by Sergei
62:39
created

BlobTest   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 77
dl 0
loc 153
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A testUpdateProcessesStream() 0 27 2
A assertBlobContains() 0 10 1
A testBindParamProcessesStream() 0 19 2
A testInsertProcessesStream() 0 20 2
A testInsert() 0 13 1
A setUp() 0 17 2
A testSelect() 0 13 1
A testUpdate() 0 18 1
1
<?php
2
3
namespace Doctrine\Tests\DBAL\Functional;
4
5
use Doctrine\DBAL\Driver\PDOSqlsrv\Driver as PDOSQLSrvDriver;
6
use Doctrine\DBAL\FetchMode;
7
use Doctrine\DBAL\ParameterType;
8
use Doctrine\DBAL\Schema\AbstractSchemaManager;
9
use Doctrine\DBAL\Schema\Table;
10
use Doctrine\DBAL\Types\Type;
11
use Doctrine\Tests\DbalFunctionalTestCase;
12
use function fopen;
13
use function in_array;
14
use function str_repeat;
15
use function stream_get_contents;
16
17
/**
18
 * @group DBAL-6
19
 */
20
class BlobTest extends DbalFunctionalTestCase
21
{
22
    protected function setUp()
23
    {
24
        parent::setUp();
25
26
        if ($this->connection->getDriver() instanceof PDOSQLSrvDriver) {
27
            $this->markTestSkipped('This test does not work on pdo_sqlsrv driver due to a bug. See: http://social.msdn.microsoft.com/Forums/sqlserver/en-US/5a755bdd-41e9-45cb-9166-c9da4475bb94/how-to-set-null-for-varbinarymax-using-bindvalue-using-pdosqlsrv?forum=sqldriverforphp');
28
        }
29
30
        /** @var AbstractSchemaManager $sm */
31
        $table = new Table('blob_table');
32
        $table->addColumn('id', 'integer');
33
        $table->addColumn('clobfield', 'text');
34
        $table->addColumn('blobfield', 'blob');
35
        $table->setPrimaryKey(['id']);
36
37
        $sm = $this->connection->getSchemaManager();
38
        $sm->dropAndCreateTable($table);
39
    }
40
41
    public function testInsert()
42
    {
43
        $ret = $this->connection->insert('blob_table', [
44
            'id'          => 1,
45
            'clobfield'   => 'test',
46
            'blobfield'   => 'test',
47
        ], [
48
            ParameterType::INTEGER,
49
            ParameterType::STRING,
50
            ParameterType::LARGE_OBJECT,
51
        ]);
52
53
        self::assertEquals(1, $ret);
54
    }
55
56
    public function testInsertProcessesStream()
57
    {
58
        if (in_array($this->connection->getDatabasePlatform()->getName(), ['oracle', 'db2'], true)) {
59
            // https://github.com/doctrine/dbal/issues/3288 for DB2
60
            // https://github.com/doctrine/dbal/issues/3290 for Oracle
61
            $this->markTestIncomplete('Platform does not support stream resources as parameters');
62
        }
63
64
        $longBlob = str_repeat('x', 4 * 8192); // send 4 chunks
65
        $this->connection->insert('blob_table', [
66
            'id'        => 1,
67
            'clobfield' => 'ignored',
68
            'blobfield' => fopen('data://text/plain,' . $longBlob, 'r'),
69
        ], [
70
            ParameterType::INTEGER,
71
            ParameterType::STRING,
72
            ParameterType::LARGE_OBJECT,
73
        ]);
74
75
        $this->assertBlobContains($longBlob);
76
    }
77
78
    public function testSelect()
79
    {
80
        $this->connection->insert('blob_table', [
81
            'id'          => 1,
82
            'clobfield'   => 'test',
83
            'blobfield'   => 'test',
84
        ], [
85
            ParameterType::INTEGER,
86
            ParameterType::STRING,
87
            ParameterType::LARGE_OBJECT,
88
        ]);
89
90
        $this->assertBlobContains('test');
91
    }
92
93
    public function testUpdate()
94
    {
95
        $this->connection->insert('blob_table', [
96
            'id' => 1,
97
            'clobfield' => 'test',
98
            'blobfield' => 'test',
99
        ], [
100
            ParameterType::INTEGER,
101
            ParameterType::STRING,
102
            ParameterType::LARGE_OBJECT,
103
        ]);
104
105
        $this->connection->update('blob_table', ['blobfield' => 'test2'], ['id' => 1], [
106
            ParameterType::LARGE_OBJECT,
107
            ParameterType::INTEGER,
108
        ]);
109
110
        $this->assertBlobContains('test2');
111
    }
112
113
    public function testUpdateProcessesStream()
114
    {
115
        if (in_array($this->connection->getDatabasePlatform()->getName(), ['oracle', 'db2'], true)) {
116
            // https://github.com/doctrine/dbal/issues/3288 for DB2
117
            // https://github.com/doctrine/dbal/issues/3290 for Oracle
118
            $this->markTestIncomplete('Platform does not support stream resources as parameters');
119
        }
120
121
        $this->connection->insert('blob_table', [
122
            'id'          => 1,
123
            'clobfield'   => 'ignored',
124
            'blobfield'   => 'test',
125
        ], [
126
            ParameterType::INTEGER,
127
            ParameterType::STRING,
128
            ParameterType::LARGE_OBJECT,
129
        ]);
130
131
        $this->connection->update('blob_table', [
132
            'id'          => 1,
133
            'blobfield'   => fopen('data://text/plain,test2', 'r'),
134
        ], ['id' => 1], [
135
            ParameterType::INTEGER,
136
            ParameterType::LARGE_OBJECT,
137
        ]);
138
139
        $this->assertBlobContains('test2');
140
    }
141
142
    public function testBindParamProcessesStream()
143
    {
144
        if (in_array($this->connection->getDatabasePlatform()->getName(), ['oracle', 'db2'], true)) {
145
            // https://github.com/doctrine/dbal/issues/3288 for DB2
146
            // https://github.com/doctrine/dbal/issues/3290 for Oracle
147
            $this->markTestIncomplete('Platform does not support stream resources as parameters');
148
        }
149
150
        $stmt = $this->connection->prepare("INSERT INTO blob_table(id, clobfield, blobfield) VALUES (1, 'ignored', ?)");
151
152
        $stream = null;
153
        $stmt->bindParam(1, $stream, ParameterType::LARGE_OBJECT);
154
155
        // Bind param does late binding (bind by reference), so create the stream only now:
156
        $stream = fopen('data://text/plain,test', 'r');
157
158
        $stmt->execute();
159
160
        $this->assertBlobContains('test');
161
    }
162
163
    private function assertBlobContains($text)
164
    {
165
        $rows = $this->connection->query('SELECT blobfield FROM blob_table')->fetchAll(FetchMode::COLUMN);
166
167
        self::assertCount(1, $rows);
168
169
        $blobValue = Type::getType('blob')->convertToPHPValue($rows[0], $this->connection->getDatabasePlatform());
170
171
        self::assertInternalType('resource', $blobValue);
172
        self::assertEquals($text, stream_get_contents($blobValue));
173
    }
174
}
175