Completed
Push — master ( 8575c2...a53269 )
by Marco
02:31 queued 01:15
created

StatementTest::testFetchInColumnMode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
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
    public function testReuseStatementWithParameterBoundByReference()
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
    public function testReuseStatementWithReboundParam()
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
    public function testFetchInColumnMode() : void
287
    {
288
        $platform = $this->_conn->getDatabasePlatform();
289
        $query    = $platform->getDummySelectSQL();
290
        $result   = $this->_conn->executeQuery($query)->fetch(\PDO::FETCH_COLUMN);
291
292
        self::assertEquals(1, $result);
293
    }
294
}
295