Passed
Pull Request — 2.7 (#3217)
by Matthias
12:52
created

testInsertCanHandleStreamLongerThanChunkSize()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 22
rs 9.7998
c 0
b 0
f 0
cc 3
nc 2
nop 0
1
<?php
2
3
namespace Doctrine\Tests\DBAL\Functional;
4
5
use Doctrine\DBAL\ParameterType;
6
use Doctrine\DBAL\Types\Type;
7
use const CASE_LOWER;
8
use function array_change_key_case;
9
use function stream_get_contents;
10
use function fopen;
11
12
/**
13
 * @group DBAL-6
14
 */
15
class BlobTest extends \Doctrine\Tests\DbalFunctionalTestCase
16
{
17
    protected function setUp()
18
    {
19
        parent::setUp();
20
21
        if ($this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlsrv\Driver) {
22
            $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');
23
        }
24
25
        try {
26
            /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
27
            $table = new \Doctrine\DBAL\Schema\Table("blob_table");
28
            $table->addColumn('id', 'integer');
29
            $table->addColumn('clobfield', 'text');
30
            $table->addColumn('blobfield', 'blob');
31
            $table->addColumn('binaryfield', 'binary', array('length' => 50));
32
            $table->setPrimaryKey(array('id'));
33
34
            $sm = $this->_conn->getSchemaManager();
35
            $sm->createTable($table);
36
        } catch(\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
37
38
        }
39
        $this->_conn->exec($this->_conn->getDatabasePlatform()->getTruncateTableSQL('blob_table'));
40
    }
41
42
    public function testInsert()
43
    {
44
        $ret = $this->_conn->insert('blob_table', [
45
            'id'          => 1,
46
            'clobfield'   => 'test',
47
            'blobfield'   => 'test',
48
            'binaryfield' => 'test',
49
        ], [
50
            ParameterType::INTEGER,
51
            ParameterType::STRING,
52
            ParameterType::LARGE_OBJECT,
53
            ParameterType::LARGE_OBJECT,
54
        ]);
55
56
        self::assertEquals(1, $ret);
57
    }
58
59
    public function testInsertProcessesStream()
60
    {
61
        if (! $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver
62
            && ! $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\PDOMySql\Driver) {
63
            $this->markTestSkipped('Passing streams into insert() is supported in Mysqli and PDOMySql only');
64
        }
65
66
        $this->_conn->insert('blob_table', [
67
            'id'          => 1,
68
            'clobfield'   => 'ignored',
69
            'blobfield'   => fopen('data://text/plain,test', 'r'),
70
            'binaryfield' => fopen('data://text/plain,test', 'r'),
71
        ], [
72
            ParameterType::INTEGER,
73
            ParameterType::STRING,
74
            ParameterType::LARGE_OBJECT,
75
            ParameterType::LARGE_OBJECT,
76
        ]);
77
78
        $this->assertBlobContains('test');
79
        $this->assertBinaryContains('test');
80
    }
81
82
    public function testInsertCanHandleStreamLongerThanChunkSize()
83
    {
84
        if (! $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver
85
            && ! $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\PDOMySql\Driver) {
86
            $this->markTestSkipped('Passing streams into insert() is supported in Mysqli and PDOMySql only');
87
        }
88
89
        $longBlob = str_repeat('x', 40000);
90
91
        $this->_conn->insert('blob_table', [
92
            'id'          => 1,
93
            'clobfield'   => 'ignored',
94
            'blobfield'   => fopen('data://text/plain,' . $longBlob, 'r'),
95
            'binaryfield' => 'ignored',
96
        ], [
97
            ParameterType::INTEGER,
98
            ParameterType::STRING,
99
            ParameterType::LARGE_OBJECT,
100
            ParameterType::LARGE_OBJECT,
101
        ]);
102
103
        $this->assertBlobContains($longBlob);
104
    }
105
106
    public function testSelect()
107
    {
108
        $this->_conn->insert('blob_table', [
109
            'id'          => 1,
110
            'clobfield'   => 'test',
111
            'blobfield'   => 'test',
112
            'binaryfield' => 'test',
113
        ], [
114
            ParameterType::INTEGER,
115
            ParameterType::STRING,
116
            ParameterType::LARGE_OBJECT,
117
            ParameterType::LARGE_OBJECT,
118
        ]);
119
120
        $this->assertBlobContains('test');
121
    }
122
123
    public function testUpdate()
124
    {
125
        $this->_conn->insert('blob_table', [
126
            'id' => 1,
127
            'clobfield' => 'test',
128
            'blobfield' => 'test',
129
            'binaryfield' => 'test',
130
        ], [
131
            ParameterType::INTEGER,
132
            ParameterType::STRING,
133
            ParameterType::LARGE_OBJECT,
134
            ParameterType::LARGE_OBJECT,
135
        ]);
136
137
        $this->_conn->update('blob_table', [
138
            'blobfield' => 'test2',
139
            'binaryfield' => 'test2',
140
        ], ['id' => 1], [
141
            ParameterType::LARGE_OBJECT,
142
            ParameterType::LARGE_OBJECT,
143
            ParameterType::INTEGER,
144
        ]);
145
146
        $this->assertBlobContains('test2');
147
        $this->assertBinaryContains('test2');
148
    }
149
150
    public function testUpdateProcessesStream()
151
    {
152
        if (! $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\Mysqli\Driver
153
            && ! $this->_conn->getDriver() instanceof \Doctrine\DBAL\Driver\PDOMySql\Driver) {
154
            $this->markTestSkipped('Passing streams into update() is supported in Mysqli and PDOMySql only');
155
        }
156
157
        $this->_conn->insert('blob_table', [
158
            'id'          => 1,
159
            'clobfield'   => 'ignored',
160
            'blobfield'   => 'test',
161
            'binaryfield' => 'test',
162
        ], [
163
            ParameterType::INTEGER,
164
            ParameterType::STRING,
165
            ParameterType::LARGE_OBJECT,
166
            ParameterType::LARGE_OBJECT,
167
        ]);
168
169
        $this->_conn->update('blob_table', [
170
            'id'          => 1,
171
            'blobfield'   => fopen('data://text/plain,test2', 'r'),
172
            'binaryfield' => fopen('data://text/plain,test2', 'r'),
173
        ], ['id' => 1], [
174
            ParameterType::INTEGER,
175
            ParameterType::LARGE_OBJECT,
176
            ParameterType::LARGE_OBJECT,
177
        ]);
178
179
        $this->assertBlobContains('test2');
180
        $this->assertBinaryContains('test2');
181
    }
182
183
    private function assertBinaryContains($text)
184
    {
185
        $rows = $this->_conn->fetchAll('SELECT * FROM blob_table');
186
187
        self::assertCount(1, $rows);
188
        $row = array_change_key_case($rows[0], CASE_LOWER);
189
190
        $blobValue = Type::getType('binary')->convertToPHPValue($row['binaryfield'], $this->_conn->getDatabasePlatform());
191
192
        self::assertInternalType('resource', $blobValue);
193
        self::assertEquals($text, stream_get_contents($blobValue));
194
    }
195
196
    private function assertBlobContains($text)
197
    {
198
        $rows = $this->_conn->fetchAll('SELECT * FROM blob_table');
199
200
        self::assertCount(1, $rows);
201
        $row = array_change_key_case($rows[0], CASE_LOWER);
202
203
        $blobValue = Type::getType('blob')->convertToPHPValue($row['blobfield'], $this->_conn->getDatabasePlatform());
204
205
        self::assertInternalType('resource', $blobValue);
206
        self::assertEquals($text, stream_get_contents($blobValue));
207
    }
208
}
209