Passed
Pull Request — master (#2952)
by Sergei
24:02 queued 48s
created

StatementTest::testFetchLongBlob()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 44
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 44
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 31
nc 1
nop 0
1
<?php
2
3
namespace Doctrine\Tests\DBAL\Functional;
4
5
use Doctrine\DBAL\Driver\Statement;
6
use Doctrine\DBAL\Schema\Table;
7
use Doctrine\DBAL\Types\Type;
8
9
class StatementTest extends \Doctrine\Tests\DbalFunctionalTestCase
10
{
11
    protected function setUp()
12
    {
13
        parent::setUp();
14
15
        $table = new Table('stmt_test');
16
        $table->addColumn('id', 'integer');
17
        $table->addColumn('name', 'text', array('notnull' => false));
18
        $this->_conn->getSchemaManager()->dropAndCreateTable($table);
19
    }
20
21
    public function testStatementIsReusableAfterClosingCursor()
22
    {
23
        $this->_conn->insert('stmt_test', array('id' => 1));
24
        $this->_conn->insert('stmt_test', array('id' => 2));
25
26
        $stmt = $this->_conn->prepare('SELECT id FROM stmt_test ORDER BY id');
27
28
        $stmt->execute();
29
30
        $id = $stmt->fetchColumn();
31
        self::assertEquals(1, $id);
32
33
        $stmt->closeCursor();
34
35
        $stmt->execute();
36
        $id = $stmt->fetchColumn();
37
        self::assertEquals(1, $id);
38
        $id = $stmt->fetchColumn();
39
        self::assertEquals(2, $id);
40
    }
41
42
    public function testReuseStatementWithLongerResults()
43
    {
44
        $sm = $this->_conn->getSchemaManager();
45
        $table = new Table('stmt_longer_results');
46
        $table->addColumn('param', 'string');
47
        $table->addColumn('val', 'text');
48
        $sm->createTable($table);
49
50
        $row1 = array(
51
            'param' => 'param1',
52
            'val' => 'X',
53
        );
54
        $this->_conn->insert('stmt_longer_results', $row1);
55
56
        $stmt = $this->_conn->prepare('SELECT param, val FROM stmt_longer_results ORDER BY param');
57
        $stmt->execute();
58
        self::assertArraySubset(array(
59
            array('param1', 'X'),
60
        ), $stmt->fetchAll(\PDO::FETCH_NUM));
61
62
        $row2 = array(
63
            'param' => 'param2',
64
            'val' => 'A bit longer value',
65
        );
66
        $this->_conn->insert('stmt_longer_results', $row2);
67
68
        $stmt->execute();
69
        self::assertArraySubset(array(
70
            array('param1', 'X'),
71
            array('param2', 'A bit longer value'),
72
        ), $stmt->fetchAll(\PDO::FETCH_NUM));
73
    }
74
75
    public function testFetchLongBlob()
76
    {
77
        // make sure memory limit is large enough to not cause false positives,
78
        // but is still not enough to store a LONGBLOB of the max possible size
79
        $this->iniSet('memory_limit', '4G');
80
81
        $sm = $this->_conn->getSchemaManager();
82
        $table = new Table('stmt_long_blob');
83
        $table->addColumn('contents', 'blob', array(
84
            'length' => 0xFFFFFFFF,
85
        ));
86
        $sm->createTable($table);
87
88
        $contents = base64_decode(<<<EOF
89
H4sICJRACVgCA2RvY3RyaW5lLmljbwDtVNtLFHEU/ia1i9fVzVWxvJSrZmoXS6pd0zK7QhdNc03z
90
lrpppq1pWqJCFERZkUFEDybYBQqJhB6iUOqhh+whgl4qkF6MfGh+s87O7GVmO6OlBfUfdIZvznxn
91
fpzznW9gAI4unQ50XwirH2AAkEygEuIwU58ODnPBzXGv14sEq4BrwzKKL4sY++SGTz6PodcutN5x
92
IPvsFCa+K9CXMfS/cOL5OxesN0Wceygho0WAXVLwcUJBdDVDaqOAij4Rrz640XlXQmAxQ16PHU63
93
iqdvXbg4JOHLpILBUSdM7XZEVDDcfuZEbI2ASaYguUGAroSh97GMngcSeFFFerMdI+/dyGy1o+GW
94
Ax5FxfAbFwoviajuc+DCIwn+RTwGRmRIThXxdQJyu+z4/NUDYz2DKCsILuERWsoQfoQhqpLhyhMZ
95
XfcknBmU0NLvQArpTm0SsI5mqKqKuFoGc8cUcjrtqLohom1AgtujQnapmJJU+BbwCLIwhJXyiKlh
96
MB4TkFgvIK3JjrRmAefJm+77Eiqvi+SvCq/qJahQyWuVuEpcIa7QLh7Kbsourb9b66/pZdAd1voz
97
fCNfwsp46OnZQPojSX9UFcNy+mYJNDeJPHtJfqeR/nSaPTzmwlXar5dQ1adpd+B//I9/hi0xuCPQ
98
Nkvb5um37Wtc+auQXZsVxEVYD5hnCilxTaYYjsuxLlsxXUitzd2hs3GWHLM5UOM7Fy8t3xiat4fb
99
sneNxmNb/POO1pRXc7vnF2nc13Rq0cFWiyXkuHmzxuOtzUYfC7fEmK/3mx4QZd5u4E7XJWz6+dey
100
Za4tXHUiPyB8Vm781oaT+3fN6Y/eUFDfPkcNWetNxb+tlxEZsPqPdZMOzS4rxwJ8CDC+ABj1+Tu0
101
d+N0hqezcjblboJ3Bj8ARJilHX4FAAA=
102
EOF
103
    );
104
105
        $this->_conn->insert('stmt_long_blob', array(
106
            'contents' => $contents,
107
        ), array(\PDO::PARAM_LOB));
108
109
        $stmt = $this->_conn->prepare('SELECT contents FROM stmt_long_blob');
110
        $stmt->execute();
111
112
        $stream = Type::getType('blob')
113
            ->convertToPHPValue(
114
                $stmt->fetchColumn(),
115
                $this->_conn->getDatabasePlatform()
116
            );
117
118
        self::assertSame($contents, stream_get_contents($stream));
0 ignored issues
show
Bug introduced by
$stream of type false|string is incompatible with the type resource expected by parameter $handle of stream_get_contents(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

118
        self::assertSame($contents, stream_get_contents(/** @scrutinizer ignore-type */ $stream));
Loading history...
119
    }
120
121
    public function testIncompletelyFetchedStatementDoesNotBlockConnection()
122
    {
123
        $this->_conn->insert('stmt_test', array('id' => 1));
124
        $this->_conn->insert('stmt_test', array('id' => 2));
125
126
        $stmt1 = $this->_conn->prepare('SELECT id FROM stmt_test');
127
        $stmt1->execute();
128
        $stmt1->fetch();
129
        $stmt1->execute();
130
        // fetching only one record out of two
131
        $stmt1->fetch();
132
133
        $stmt2 = $this->_conn->prepare('SELECT id FROM stmt_test WHERE id = ?');
134
        $stmt2->execute(array(1));
135
        self::assertEquals(1, $stmt2->fetchColumn());
136
    }
137
138
    public function testReuseStatementAfterClosingCursor()
139
    {
140
        $this->_conn->insert('stmt_test', array('id' => 1));
141
        $this->_conn->insert('stmt_test', array('id' => 2));
142
143
        $stmt = $this->_conn->prepare('SELECT id FROM stmt_test WHERE id = ?');
144
145
        $stmt->execute(array(1));
146
        $id = $stmt->fetchColumn();
147
        self::assertEquals(1, $id);
148
149
        $stmt->closeCursor();
150
151
        $stmt->execute(array(2));
152
        $id = $stmt->fetchColumn();
153
        self::assertEquals(2, $id);
154
    }
155
156 View Code Duplication
    public function testReuseStatementWithParameterBoundByReference()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
157
    {
158
        $this->_conn->insert('stmt_test', array('id' => 1));
159
        $this->_conn->insert('stmt_test', array('id' => 2));
160
161
        $stmt = $this->_conn->prepare('SELECT id FROM stmt_test WHERE id = ?');
162
        $stmt->bindParam(1, $id);
163
164
        $id = 1;
0 ignored issues
show
Unused Code introduced by
The assignment to $id is dead and can be removed.
Loading history...
165
        $stmt->execute();
166
        self::assertEquals(1, $stmt->fetchColumn());
167
168
        $id = 2;
169
        $stmt->execute();
170
        self::assertEquals(2, $stmt->fetchColumn());
171
    }
172
173
    public function testReuseStatementWithReboundValue()
174
    {
175
        $this->_conn->insert('stmt_test', array('id' => 1));
176
        $this->_conn->insert('stmt_test', array('id' => 2));
177
178
        $stmt = $this->_conn->prepare('SELECT id FROM stmt_test WHERE id = ?');
179
180
        $stmt->bindValue(1, 1);
181
        $stmt->execute();
182
        self::assertEquals(1, $stmt->fetchColumn());
183
184
        $stmt->bindValue(1, 2);
185
        $stmt->execute();
186
        self::assertEquals(2, $stmt->fetchColumn());
187
    }
188
189 View Code Duplication
    public function testReuseStatementWithReboundParam()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
190
    {
191
        $this->_conn->insert('stmt_test', array('id' => 1));
192
        $this->_conn->insert('stmt_test', array('id' => 2));
193
194
        $stmt = $this->_conn->prepare('SELECT id FROM stmt_test WHERE id = ?');
195
196
        $x = 1;
197
        $stmt->bindParam(1, $x);
198
        $stmt->execute();
199
        self::assertEquals(1, $stmt->fetchColumn());
200
201
        $y = 2;
202
        $stmt->bindParam(1, $y);
203
        $stmt->execute();
204
        self::assertEquals(2, $stmt->fetchColumn());
205
    }
206
207
    /**
208
     * @dataProvider emptyFetchProvider
209
     */
210
    public function testFetchFromNonExecutedStatement(callable $fetch, $expected)
211
    {
212
        $stmt = $this->_conn->prepare('SELECT id FROM stmt_test');
213
214
        self::assertSame($expected, $fetch($stmt));
215
    }
216
217
    public function testCloseCursorOnNonExecutedStatement()
218
    {
219
        $stmt = $this->_conn->prepare('SELECT id FROM stmt_test');
220
221
        self::assertTrue($stmt->closeCursor());
222
    }
223
224
    /**
225
     * @group DBAL-2637
226
     */
227
    public function testCloseCursorAfterCursorEnd()
228
    {
229
        $stmt = $this->_conn->prepare('SELECT name FROM stmt_test');
230
231
        $stmt->execute();
232
        $stmt->fetch();
233
234
        self::assertTrue($stmt->closeCursor());
235
    }
236
237
    /**
238
     * @dataProvider emptyFetchProvider
239
     */
240
    public function testFetchFromNonExecutedStatementWithClosedCursor(callable $fetch, $expected)
241
    {
242
        $stmt = $this->_conn->prepare('SELECT id FROM stmt_test');
243
        $stmt->closeCursor();
244
245
        self::assertSame($expected, $fetch($stmt));
246
    }
247
248
    /**
249
     * @dataProvider emptyFetchProvider
250
     */
251
    public function testFetchFromExecutedStatementWithClosedCursor(callable $fetch, $expected)
252
    {
253
        $this->_conn->insert('stmt_test', array('id' => 1));
254
255
        $stmt = $this->_conn->prepare('SELECT id FROM stmt_test');
256
        $stmt->execute();
257
        $stmt->closeCursor();
258
259
        self::assertSame($expected, $fetch($stmt));
260
    }
261
262
    public static function emptyFetchProvider()
263
    {
264
        return array(
265
            'fetch' => array(
266
                function (Statement $stmt) {
267
                    return $stmt->fetch();
268
                },
269
                false,
270
            ),
271
            'fetch-column' => array(
272
                function (Statement $stmt) {
273
                    return $stmt->fetchColumn();
274
                },
275
                false,
276
            ),
277
            'fetch-all' => array(
278
                function (Statement $stmt) {
279
                    return $stmt->fetchAll();
280
                },
281
                array(),
282
            ),
283
        );
284
    }
285
}
286