Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
45.16% covered (danger)
45.16%
112 / 248
50.00% covered (danger)
50.00%
12 / 24
CRAP
0.00% covered (danger)
0.00%
0 / 1
phpbb_dbal_select_test
45.16% covered (danger)
45.16%
112 / 248
50.00% covered (danger)
50.00%
12 / 24
332.91
0.00% covered (danger)
0.00%
0 / 1
 getDataSet
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 return_on_error_select_data
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 test_return_on_error_select
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 fetchrow_data
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 test_fetchrow
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 test_fetchrowset
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 fetchfield_data
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 test_fetchfield
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 fetchfield_seek_data
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 test_fetchfield_seek
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 query_limit_data
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
2
 test_query_limit
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 like_expression_data
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 test_like_expression
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 not_like_expression_data
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
2
 test_not_like_expression
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 in_set_data
0.00% covered (danger)
0.00%
0 / 42
0.00% covered (danger)
0.00%
0 / 1
2
 test_in_set
80.00% covered (warning)
80.00%
8 / 10
0.00% covered (danger)
0.00%
0 / 1
3.07
 build_array_data
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 test_build_array
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
 test_nested_transactions
90.00% covered (success)
90.00%
9 / 10
0.00% covered (danger)
0.00%
0 / 1
2.00
 test_sql_fetchrow_returns_false_when_empty
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 test_get_row_count
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 test_get_estimated_row_count
87.50% covered (warning)
87.50%
7 / 8
0.00% covered (danger)
0.00%
0 / 1
4.03
1<?php
2/**
3*
4* This file is part of the phpBB Forum Software package.
5*
6* @copyright (c) phpBB Limited <https://www.phpbb.com>
7* @license GNU General Public License, version 2 (GPL-2.0)
8*
9* For full copyright and license information, please see
10* the docs/CREDITS.txt file.
11*
12*/
13
14class phpbb_dbal_select_test extends phpbb_database_test_case
15{
16    public function getDataSet()
17    {
18        return $this->createXMLDataSet(__DIR__.'/fixtures/three_users.xml');
19    }
20
21    public static function return_on_error_select_data()
22    {
23        return array(
24            array('phpbb_users', "username_clean = 'bertie'", array(array('username_clean' => 'bertie'))),
25            array('phpbb_users', 'username_clean syntax_error', false),
26        );
27    }
28
29    /**
30    * @dataProvider return_on_error_select_data
31    */
32    public function test_return_on_error_select($table, $where, $expected)
33    {
34        $db = $this->new_dbal();
35
36        $db->sql_return_on_error(true);
37
38        $result = $db->sql_query('SELECT username_clean
39            FROM ' . $table . '
40            WHERE ' . $where . '
41            ORDER BY user_id ASC');
42
43        $db->sql_return_on_error(false);
44
45        $this->assertEquals($expected, $db->sql_fetchrowset($result));
46    }
47
48    public static function fetchrow_data()
49    {
50        return array(
51            array('', array(array('username_clean' => 'barfoo'),
52                array('username_clean' => 'foobar'),
53                array('username_clean' => 'bertie'))),
54            array('user_id = 2', array(array('username_clean' => 'foobar'))),
55            array("username_clean = 'bertie'", array(array('username_clean' => 'bertie'))),
56            array("username_clean = 'phpBB'", array()),
57        );
58    }
59
60    /**
61    * @dataProvider fetchrow_data
62    */
63    public function test_fetchrow($where, $expected)
64    {
65        $db = $this->new_dbal();
66
67        $result = $db->sql_query('SELECT username_clean
68            FROM phpbb_users
69            ' . (($where) ? ' WHERE ' . $where : '') . '
70            ORDER BY user_id ASC');
71
72        $ary = array();
73        while ($row = $db->sql_fetchrow($result))
74        {
75            $ary[] = $row;
76        }
77        $db->sql_freeresult($result);
78
79        $this->assertEquals($expected, $ary);
80    }
81
82    /**
83    * @dataProvider fetchrow_data
84    */
85    public function test_fetchrowset($where, $expected)
86    {
87        $db = $this->new_dbal();
88
89        $result = $db->sql_query('SELECT username_clean
90            FROM phpbb_users
91            ' . (($where) ? ' WHERE ' . $where : '') . '
92            ORDER BY user_id ASC');
93
94        $this->assertEquals($expected, $db->sql_fetchrowset($result));
95
96        $db->sql_freeresult($result);
97    }
98
99    public static function fetchfield_data()
100    {
101        return array(
102            array('', array('barfoo', 'foobar', 'bertie')),
103            array('user_id = 2', array('foobar')),
104        );
105    }
106
107    /**
108    * @dataProvider fetchfield_data
109    */
110    public function test_fetchfield($where, $expected)
111    {
112        $db = $this->new_dbal();
113
114        $result = $db->sql_query('SELECT username_clean
115            FROM phpbb_users
116            ' . (($where) ? ' WHERE ' . $where : '') . '
117            ORDER BY user_id ASC');
118
119        $ary = array();
120        while ($row = $db->sql_fetchfield('username_clean'))
121        {
122            $ary[] = $row;
123        }
124        $db->sql_freeresult($result);
125
126        $this->assertEquals($expected, $ary);
127    }
128
129    public static function fetchfield_seek_data()
130    {
131        return array(
132            array(1, 'foobar'),
133            array(0, 'barfoo'),
134            array(2, 'bertie'),
135        );
136    }
137
138    /**
139    * @dataProvider fetchfield_seek_data
140    */
141    public function test_fetchfield_seek($rownum, $expected)
142    {
143        $db = $this->new_dbal();
144
145        $result = $db->sql_query('SELECT username_clean
146            FROM phpbb_users
147            ORDER BY user_id ASC');
148
149        $field = $db->sql_fetchfield('username_clean', $rownum, $result);
150        $db->sql_freeresult($result);
151
152        $this->assertEquals($expected, $field);
153    }
154
155    public static function query_limit_data()
156    {
157        return array(
158            array(0, 0, array(array('username_clean' => 'barfoo'),
159                array('username_clean' => 'foobar'),
160                array('username_clean' => 'bertie'))),
161            array(0, 1, array(array('username_clean' => 'foobar'),
162                array('username_clean' => 'bertie'))),
163            array(1, 0, array(array('username_clean' => 'barfoo'))),
164            array(1, 2, array(array('username_clean' => 'bertie'))),
165            array(2, 0, array(array('username_clean' => 'barfoo'),
166                array('username_clean' => 'foobar'))),
167            array(2, 2, array(array('username_clean' => 'bertie'))),
168            array(2, 5, array()),
169            array(10, 1, array(array('username_clean' => 'foobar'),
170                array('username_clean' => 'bertie'))),
171            array(10, 5, array()),
172        );
173    }
174
175    /**
176    * @dataProvider query_limit_data
177    */
178    public function test_query_limit($total, $offset, $expected)
179    {
180        $db = $this->new_dbal();
181
182        $result = $db->sql_query_limit('SELECT username_clean
183            FROM phpbb_users
184            ORDER BY user_id ASC', $total, $offset);
185
186        $ary = array();
187        while ($row = $db->sql_fetchrow($result))
188        {
189            $ary[] = $row;
190        }
191        $db->sql_freeresult($result);
192
193        $this->assertEquals($expected, $ary);
194    }
195
196    public static function like_expression_data()
197    {
198        // * = any_char; # = one_char
199        return array(
200            array('barfoo', array(array('username_clean' => 'barfoo'))),
201            array('bar', array()),
202            array('bar*', array(array('username_clean' => 'barfoo'))),
203            array('*bar*', array(array('username_clean' => 'barfoo'),
204                array('username_clean' => 'foobar'))),
205            array('b*r', array()),
206            array('b*e', array(array('username_clean' => 'bertie'))),
207            array('#b*e', array()),
208            array('b####e', array(array('username_clean' => 'bertie'))),
209        );
210    }
211
212    /**
213    * @dataProvider like_expression_data
214    */
215    public function test_like_expression($like_expression, $expected)
216    {
217        $db = $this->new_dbal();
218
219        $like_expression = str_replace('*', $db->get_any_char(), $like_expression);
220        $like_expression = str_replace('#', $db->get_one_char(), $like_expression);
221        $where = ($like_expression) ? 'username_clean ' . $db->sql_like_expression($like_expression) : '';
222
223        $result = $db->sql_query('SELECT username_clean
224            FROM phpbb_users
225            ' . (($where) ? ' WHERE ' . $where : '') . '
226            ORDER BY user_id ASC');
227
228        $this->assertEquals($expected, $db->sql_fetchrowset($result));
229
230        $db->sql_freeresult($result);
231    }
232
233    public static function not_like_expression_data()
234    {
235        // * = any_char; # = one_char
236        return array(
237            array('barfoo', array(
238                array('username_clean' => 'foobar'),
239                array('username_clean' => 'bertie')
240            )),
241            array('bar', array(
242                array('username_clean' => 'barfoo'),
243                array('username_clean' => 'foobar'),
244                array('username_clean' => 'bertie'),
245            )),
246            array('bar*', array(
247                array('username_clean' => 'foobar'),
248                array('username_clean' => 'bertie'))
249            ),
250            array('*bar*', array(array('username_clean' => 'bertie'))),
251            array('b*r', array(
252                array('username_clean' => 'barfoo'),
253                array('username_clean' => 'foobar'),
254                array('username_clean' => 'bertie')
255            )),
256            array('b*e', array(
257                array('username_clean' => 'barfoo'),
258                array('username_clean' => 'foobar')
259            )),
260            array('#b*e', array(
261                array('username_clean' => 'barfoo'),
262                array('username_clean' => 'foobar'),
263                array('username_clean' => 'bertie')
264            )),
265            array('b####e', array(
266                array('username_clean' => 'barfoo'),
267                array('username_clean' => 'foobar')
268            )),
269        );
270    }
271
272    /**
273    * @dataProvider not_like_expression_data
274    */
275    public function test_not_like_expression($like_expression, $expected)
276    {
277        $db = $this->new_dbal();
278
279        $like_expression = str_replace('*', $db->get_any_char(), $like_expression);
280        $like_expression = str_replace('#', $db->get_one_char(), $like_expression);
281        $where = ($like_expression) ? 'username_clean ' . $db->sql_not_like_expression($like_expression) : '';
282
283        $result = $db->sql_query('SELECT username_clean
284            FROM phpbb_users
285            ' . (($where) ? ' WHERE ' . $where : '') . '
286            ORDER BY user_id ASC');
287
288        $this->assertEquals($expected, $db->sql_fetchrowset($result));
289
290        $db->sql_freeresult($result);
291    }
292
293    public static function in_set_data()
294    {
295        return array(
296            array('user_id', 3, false, false, array(array('username_clean' => 'bertie'))),
297            array('user_id', 3, false, true, array(array('username_clean' => 'bertie'))),
298            array('user_id', 3, true, false, array(array('username_clean' => 'barfoo'),
299                array('username_clean' => 'foobar'))),
300            array('user_id', 3, true, true, array(array('username_clean' => 'barfoo'),
301                array('username_clean' => 'foobar'))),
302            array('username_clean', 'bertie', false, false, array(array('username_clean' => 'bertie'))),
303            array('username_clean', 'bertie', false, true, array(array('username_clean' => 'bertie'))),
304            array('username_clean', 'bertie', true, false, array(array('username_clean' => 'barfoo'),
305                array('username_clean' => 'foobar'))),
306            array('username_clean', 'bertie', true, true, array(array('username_clean' => 'barfoo'),
307                array('username_clean' => 'foobar'))),
308            array('user_id', array(3), false, false, array(array('username_clean' => 'bertie'))),
309            array('user_id', array(3), false, true, array(array('username_clean' => 'bertie'))),
310            array('user_id', array(3), true, false, array(array('username_clean' => 'barfoo'),
311                array('username_clean' => 'foobar'))),
312            array('user_id', array(3), true, true, array(array('username_clean' => 'barfoo'),
313                array('username_clean' => 'foobar'))),
314            array('user_id', array(1, 3), false, false, array(array('username_clean' => 'barfoo'),
315                array('username_clean' => 'bertie'))),
316            array('user_id', array(1, 3), false, true, array(array('username_clean' => 'barfoo'),
317                array('username_clean' => 'bertie'))),
318            array('user_id', array(1, 3), true, false, array(array('username_clean' => 'foobar'))),
319            array('user_id', array(1, 3), true, true, array(array('username_clean' => 'foobar'))),
320            array('username_clean', '', false, false, array()),
321            array('username_clean', '', false, true, array()),
322            array('username_clean', '', true, false, array(array('username_clean' => 'barfoo'),
323                array('username_clean' => 'foobar'),
324                array('username_clean' => 'bertie'))),
325            array('username_clean', '', true, true, array(array('username_clean' => 'barfoo'),
326                array('username_clean' => 'foobar'),
327                array('username_clean' => 'bertie'))),
328            array('user_id', array(), false, true, array()),
329            array('user_id', array(), true, true, array(array('username_clean' => 'barfoo'),
330                array('username_clean' => 'foobar'),
331                array('username_clean' => 'bertie'))),
332
333            // These here would throw errors and therefor $result should be false.
334            // Removing for now because SQLite accepts empty IN() syntax
335            /*array('user_id', array(), false, false, false, true),
336            array('user_id', array(), true, false, false, true),*/
337        );
338    }
339
340    /**
341    * @dataProvider in_set_data
342    */
343    public function test_in_set($field, $array, $negate, $allow_empty_set, $expected, $catch_error = false)
344    {
345        $db = $this->new_dbal();
346
347        if ($catch_error)
348        {
349            $db->sql_return_on_error(true);
350        }
351
352        $result = $db->sql_query('SELECT username_clean
353            FROM phpbb_users
354            WHERE ' . $db->sql_in_set($field, $array, $negate, $allow_empty_set) . '
355            ORDER BY user_id ASC');
356
357        if ($catch_error)
358        {
359            $db->sql_return_on_error(false);
360        }
361
362        $this->assertEquals($expected, $db->sql_fetchrowset($result));
363
364        $db->sql_freeresult($result);
365    }
366
367    public static function build_array_data()
368    {
369        return array(
370            array(array('username_clean' => 'barfoo'), array(array('username_clean' => 'barfoo'))),
371            array(array('username_clean' => 'barfoo', 'user_id' => 1), array(array('username_clean' => 'barfoo'))),
372            array(array('username_clean' => 'barfoo', 'user_id' => 2), array()),
373
374            // These here would throw errors and therefor $result should be false.
375            array(array(), false, true),
376            array('no_array', false, true),
377            array(0, false, true),
378        );
379    }
380
381    /**
382    * @dataProvider build_array_data
383    */
384    public function test_build_array($assoc_ary, $expected, $catch_error = false)
385    {
386        $db = $this->new_dbal();
387
388        if ($catch_error)
389        {
390            $db->sql_return_on_error(true);
391        }
392
393        $sql = 'SELECT username_clean
394            FROM phpbb_users
395            WHERE ' . $db->sql_build_array('SELECT', $assoc_ary) . '
396            ORDER BY user_id ASC';
397        $result = $db->sql_query($sql);
398
399        if ($catch_error)
400        {
401            $db->sql_return_on_error(false);
402        }
403
404        $this->assertEquals($expected, $db->sql_fetchrowset($result));
405
406        $db->sql_freeresult($result);
407    }
408
409    public function test_nested_transactions()
410    {
411        $db = $this->new_dbal();
412
413        // nested transactions should work on systems that do not require
414        // buffering of nested transactions, so ignore the ones that need
415        // buffering
416        if ($db->sql_buffer_nested_transactions())
417        {
418            return;
419        }
420
421        $sql = 'SELECT user_id FROM phpbb_users ORDER BY user_id ASC';
422        $result1 = $db->sql_query($sql);
423
424        $db->sql_transaction('begin');
425        $result2 = $db->sql_query($sql);
426        $row = $db->sql_fetchrow($result2);
427        $db->sql_transaction('commit');
428
429        $this->assertEquals('1', $row['user_id']);
430    }
431
432    /**
433     * fix for PHPBB3-10307
434     */
435    public function test_sql_fetchrow_returns_false_when_empty()
436    {
437        $db = $this->new_dbal();
438
439        $sql = 'SELECT user_id
440            FROM phpbb_users
441            WHERE 1 = 0';
442        $result = $db->sql_query($sql);
443
444        $row = $db->sql_fetchrow($result);
445        $db->sql_freeresult($result);
446
447        $this->assertSame(false, $row);
448    }
449
450    public function test_get_row_count()
451    {
452        $this->assertSame(
453            3,
454            (int) $this->new_dbal()->get_row_count('phpbb_users'),
455            "Failed asserting that user table has exactly 3 rows."
456        );
457    }
458
459    public function test_get_estimated_row_count()
460    {
461        $actual = $this->new_dbal()->get_estimated_row_count('phpbb_users');
462
463        if (is_string($actual) && isset($actual[0]) && $actual[0] === '~')
464        {
465            $actual = substr($actual, 1);
466        }
467
468        $this->assertGreaterThan(
469            1,
470            $actual,
471            "Failed asserting that estimated row count of user table is greater than 1."
472        );
473    }
474}