1<?php
2// +----------------------------------------------------------------------+
3// | PHP versions 4 and 5                                                 |
4// +----------------------------------------------------------------------+
5// | Copyright (c) 1998-2006 Manuel Lemos, Paul Cooper                    |
6// | All rights reserved.                                                 |
7// +----------------------------------------------------------------------+
8// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB  |
9// | API as well as database abstraction for PHP applications.            |
10// | This LICENSE is in the BSD license style.                            |
11// |                                                                      |
12// | Redistribution and use in source and binary forms, with or without   |
13// | modification, are permitted provided that the following conditions   |
14// | are met:                                                             |
15// |                                                                      |
16// | Redistributions of source code must retain the above copyright       |
17// | notice, this list of conditions and the following disclaimer.        |
18// |                                                                      |
19// | Redistributions in binary form must reproduce the above copyright    |
20// | notice, this list of conditions and the following disclaimer in the  |
21// | documentation and/or other materials provided with the distribution. |
22// |                                                                      |
23// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
24// | Lukas Smith nor the names of his contributors may be used to endorse |
25// | or promote products derived from this software without specific prior|
26// | written permission.                                                  |
27// |                                                                      |
28// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
29// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
30// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
31// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
32// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
33// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
34// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
35// |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
36// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
37// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
38// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
39// | POSSIBILITY OF SUCH DAMAGE.                                          |
40// +----------------------------------------------------------------------+
41// | Author: Paul Cooper <pgc@ucecom.com>                                 |
42// +----------------------------------------------------------------------+
43//
44// $Id: BugsTest.php 328182 2012-10-29 15:10:30Z danielc $
45
46require_once dirname(__DIR__) . '/autoload.inc';
47
48class Standard_BugsTest extends Standard_Abstract {
49    /**
50     * @dataProvider provider
51     */
52    public function testFetchModeBug($ci) {
53        $this->manualSetUp($ci);
54
55        $data = array();
56
57        $stmt = $this->db->prepare('INSERT INTO ' . $this->table_users . ' (' . implode(', ', array_keys($this->fields)) . ') VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', array_values($this->fields), MDB2_PREPARE_MANIP);
58
59        $data['user_name'] = 'user_=';
60        $data['user_password'] = 'somepass';
61        $data['subscribed'] = true;
62        $data['user_id'] = 0;
63        $data['quota'] = sprintf("%.2f", strval(2/100));
64        $data['weight'] = sqrt(0);
65        $data['access_date'] = MDB2_Date::mdbToday();
66        $data['access_time'] = MDB2_Date::mdbTime();
67        $data['approved'] = MDB2_Date::mdbNow();
68
69        $result = $stmt->execute(array_values($data));
70
71        if (MDB2::isError($result)) {
72            $this->fail('Error executing prepared query '.$result->getMessage());
73        }
74
75        $stmt->free();
76
77        $query = 'SELECT ' . implode(', ', array_keys($this->fields)) . ' FROM ' . $this->table_users . ' ORDER BY user_name';
78        $result = $this->db->query($query);
79
80        if (MDB2::isError($result)) {
81            $this->fail('Error selecting from users: '.$result->getMessage());
82        }
83
84        $this->db->setFetchMode(MDB2_FETCHMODE_ASSOC);
85
86        $firstRow = $result->fetchRow();
87        $this->assertEquals($firstRow['user_name'], $data['user_name'], 'The data returned does not match that expected');
88
89        $result = $this->db->query('SELECT user_name, user_id, quota FROM ' . $this->table_users . ' ORDER BY user_name');
90        if (MDB2::isError($result)) {
91            $this->fail('Error selecting from users: '.$result->getMessage());
92        }
93        $this->db->setFetchMode(MDB2_FETCHMODE_ORDERED);
94
95        $value = $result->fetchOne();
96        $this->assertEquals($data['user_name'], $value, 'The data returned does not match that expected');
97        $result->free();
98    }
99
100    /**
101     * @see http://bugs.php.net/bug.php?id=22328
102     * @dataProvider provider
103     */
104    public function testBug22328($ci) {
105        $this->manualSetUp($ci);
106
107        $result = $this->db->query('SELECT * FROM ' . $this->table_users);
108        $this->db->pushErrorHandling(PEAR_ERROR_RETURN);
109        $result2 = $this->db->query('SELECT * FROM foo');
110
111        $data = $result->fetchRow();
112        $this->db->popErrorHandling();
113        $this->assertFalse(MDB2::isError($data), 'Error messages for a query affect result reading of other queries');
114    }
115
116    /**
117     * @see http://pear.php.net/bugs/bug.php?id=670
118     * @dataProvider provider
119     */
120    public function testBug670($ci) {
121        $this->manualSetUp($ci);
122
123        $data['user_name'] = null;
124        $data['user_password'] = 'somepass';
125        $data['subscribed'] = true;
126        $data['user_id'] = 1;
127        $data['quota'] = sprintf("%.2f",strval(3/100));
128        $data['weight'] = sqrt(1);
129        $data['access_date'] = MDB2_Date::mdbToday();
130        $data['access_time'] = MDB2_Date::mdbTime();
131        $data['approved'] = MDB2_Date::mdbNow();
132
133        $stmt = $this->db->prepare('INSERT INTO ' . $this->table_users . ' (' . implode(', ', array_keys($this->fields)) . ') VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', array_values($this->fields), MDB2_PREPARE_MANIP);
134        $result = $stmt->execute(array_values($data));
135
136        $result = $this->db->query('SELECT user_name FROM ' . $this->table_users);
137        $col = $result->fetchCol('user_name');
138        if (MDB2::isError($col)) {
139            $this->fail('Error when fetching column first first row as NULL: '.$col->getMessage());
140        }
141
142        $data['user_name'] = "user_1";
143        $data['user_id'] = 2;
144
145        $result = $stmt->execute(array_values($data));
146
147        $result = $this->db->query('SELECT user_name FROM ' . $this->table_users);
148        $col = $result->fetchCol('user_name');
149        if (MDB2::isError($col)) {
150            $this->fail('Error when fetching column: '.$col->getMessage());
151        }
152
153        $data['user_name'] = null;
154
155        $stmt->free();
156    }
157
158    /**
159     * @see http://pear.php.net/bugs/bug.php?id=681
160     * @dataProvider provider
161     */
162    public function testBug681($ci) {
163        $this->manualSetUp($ci);
164
165        $result = $this->db->query('SELECT * FROM ' . $this->table_users . ' WHERE 1=0');
166
167        $numrows = $result->numRows();
168        $this->assertEquals(0, $numrows, 'Numrows is not returning 0 for empty result sets');
169
170        $data = $this->getSampleData(1);
171
172        $stmt = $this->db->prepare('INSERT INTO ' . $this->table_users . ' (' . implode(', ', array_keys($this->fields)) . ') VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', array_values($this->fields), MDB2_PREPARE_MANIP);
173        $result = $stmt->execute(array_values($data));
174
175        $result = $this->db->query('SELECT * FROM ' . $this->table_users);
176        $numrows = $result->numRows();
177        $this->assertEquals(1, $numrows, 'Numrows is not returning proper value');
178
179        $stmt->free();
180    }
181
182    /**
183     * @see http://pear.php.net/bugs/bug.php?id=718
184     * @dataProvider provider
185     */
186    public function testBug718($ci) {
187        $this->manualSetUp($ci);
188
189        $data = $this->getSampleData(1);
190
191        $stmt = $this->db->prepare('INSERT INTO ' . $this->table_users . ' (' . implode(', ', array_keys($this->fields)) . ') VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', array_values($this->fields), MDB2_PREPARE_MANIP);
192        $result = $stmt->execute(array_values($data));
193
194        $row = $this->db->queryRow('SELECT a.user_id, b.user_id FROM ' . $this->table_users . ' a, ' . $this->table_users . ' b where a.user_id = b.user_id', array('integer', 'integer'), MDB2_FETCHMODE_ORDERED);
195        $this->assertEquals(2, count($row), "Columns with the same name get overwritten in ordered mode");
196
197        $stmt->free();
198    }
199
200    /**
201     * @see http://pear.php.net/bugs/bug.php?id=946
202     * @dataProvider provider
203     */
204    public function testBug946($ci) {
205        $this->manualSetUp($ci);
206
207        $data = array();
208        $total_rows = 5;
209
210        $stmt = $this->db->prepare('INSERT INTO ' . $this->table_users . ' (' . implode(', ', array_keys($this->fields)) . ') VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', array_values($this->fields), MDB2_PREPARE_MANIP);
211
212        for ($row = 0; $row < $total_rows; $row++) {
213            $data[$row] = $this->getSampleData($row);
214
215            $result = $stmt->execute(array_values($data[$row]));
216
217            if (MDB2::isError($result)) {
218                $this->fail('Error executing prepared query: '.$result->getMessage());
219            }
220        }
221        $stmt->free();
222
223        $query = 'SELECT ' . implode(', ', array_keys($this->fields)) . ' FROM ' . $this->table_users;
224
225        $this->db->setLimit(3, 1);
226        $result = $this->db->query($query);
227        $numrows = $result->numRows();
228        while ($row = $result->fetchRow()) {
229            if (MDB2::isError($row)) {
230                $this->fail('Error fetching a row: '.$row->getMessage());
231            }
232        }
233        $result->free();
234
235        $result = $this->db->query($query);
236        $numrows = $result->numRows();
237        while ($row = $result->fetchRow()) {
238            if (MDB2::isError($row)) {
239                $this->fail('Error fetching a row: '.$row->getMessage());
240            }
241        }
242        $result->free();
243    }
244
245    /**
246     * @see http://pear.php.net/bugs/bug.php?id=3146
247     * @dataProvider provider
248     */
249    public function testBug3146($ci) {
250        $this->manualSetUp($ci);
251
252        $data = array();
253        $total_rows = 5;
254
255        $query = 'INSERT INTO ' . $this->table_users . ' (' . implode(', ', array_keys($this->fields)) . ') VALUES ('.implode(', ', array_fill(0, count($this->fields), '?')).')';
256        $stmt = $this->db->prepare($query, array_values($this->fields), MDB2_PREPARE_MANIP);
257
258        for ($row = 0; $row < $total_rows; $row++) {
259            $data[$row] = $this->getSampleData($row);
260
261            $result = $stmt->execute(array_values($data[$row]));
262            if (MDB2::isError($result)) {
263                $this->fail('Error executing prepared query: '.$result->getMessage());
264            }
265        }
266        $stmt->free();
267
268        $query = 'SELECT ' . implode(', ', array_keys($this->fields)) . ' FROM ' . $this->table_users . ' ORDER BY user_id';
269        $result = $this->db->query($query, $this->fields);
270
271        $numrows = $result->numRows($result);
272
273        $this->verifyFetchedValues($result, 0, $data[0]);
274        $this->verifyFetchedValues($result, 2, $data[2]);
275        $this->verifyFetchedValues($result, null, $data[3]);
276        $this->verifyFetchedValues($result, 1, $data[1]);
277
278        $result->free();
279    }
280
281    /**
282     * Strong typing query result misbehaves when $n_columns > $n_types
283     * @see http://pear.php.net/bugs/bug.php?id=9502
284     * @dataProvider provider
285     */
286    public function testBug9502($ci) {
287        $this->manualSetUp($ci);
288
289        $row = 5;
290        $data = $this->getSampleData($row);
291        $stmt = $this->db->prepare('INSERT INTO ' . $this->table_users . ' (' . implode(', ', array_keys($this->fields)) . ') VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', array_values($this->fields), MDB2_PREPARE_MANIP);
292        $result = $stmt->execute(array_values($data));
293        $stmt->free();
294
295        //provide an incomplete and scrambled types array
296        $types = array();
297        $types['subscribed'] = $this->fields['subscribed'];
298        $types['user_name']  = $this->fields['user_name'];
299        $types['weight']     = $this->fields['weight'];
300
301        $query = 'SELECT weight, user_name, user_id, quota, subscribed FROM ' . $this->table_users . ' WHERE user_id = '.$row;
302        $result = $this->db->queryRow($query, $types, MDB2_FETCHMODE_ASSOC);
303        if (MDB2::isError($result)) {
304            $this->fail('Error executing query: '.$result->getMessage() .' - '. $result->getUserInfo());
305        } else {
306            $this->assertInternalType('boolean', $result['subscribed']);
307            $this->assertInternalType('numeric', $result['user_id']);
308            $this->assertInternalType('float', $result['weight']);
309            $this->assertInternalType('string', $result['user_name']);
310        }
311    }
312
313    /**
314     * Type introspection breaks with associative arrays if names are identical
315     * @see http://pear.php.net/bugs/bug.php?id=18203
316     * @dataProvider provider
317     */
318    public function testBug18203($ci) {
319        $this->manualSetUp($ci);
320
321        $res = $this->db->query("SELECT 1 as id, 2 as id, 'foo' as title", true);
322        if (MDB2::isError($res)) {
323            $this->fail($res->getMessage());
324        }
325        $record = $res->fetchRow(MDB2_FETCHMODE_ASSOC);
326        $expected = array(
327            'id'    => 2,
328            'title' => 'foo'
329        );
330        $this->assertSame($expected, $record);
331    }
332
333    /**
334     * Call to a member function seek() on a non-object
335     * @see https://pear.php.net/bugs/bug.php?id=18978
336     * @dataProvider provider
337     */
338    public function testBug18978($ci) {
339        $this->manualSetUp($ci);
340
341        $data = $this->populateUserData(3);
342        $this->db->setFetchMode(MDB2_FETCHMODE_ASSOC);
343        MDB2::loadFile('Iterator');
344
345        // This was test in bug.
346        $res = $this->db->query('SELECT * FROM ' . $this->table_users, true, true, 'MDB2_BufferedIterator');
347        if (MDB2::isError($res)) {
348            $this->fail($res->getUserInfo());
349        }
350        foreach($res as $key => $row) {
351            $this->assertEquals($data[$key - 1]['user_name'], $row['user_name']);
352        }
353        $res->free();
354
355        // Making sure direct instantiation works as well.
356        $res = $this->db->query('SELECT * FROM ' . $this->table_users);
357        $i = new MDB2_Iterator($res, MDB2_FETCHMODE_ASSOC);
358        $i->seek(1);
359        $row = $i->current();
360        $this->assertEquals($data[1]['user_name'], $row['user_name']);
361        unset($i);
362        $res->free();
363
364        // Make sure constructor type checking works.
365        $this->setExpectedException('PHPUnit_Framework_Error', 'must be an instance of MDB2_Result_Common');
366        $i = new MDB2_Iterator('foo');
367    }
368
369    /**
370     * Make setOption('result_wrap_class') work without convoluted query() calls
371     * @see https://pear.php.net/bugs/bug.php?id=16970
372     * @dataProvider provider
373     */
374    public function testRequest16970($ci) {
375        $this->manualSetUp($ci);
376
377        $data = $this->populateUserData(1);
378        $this->db->setFetchMode(MDB2_FETCHMODE_ASSOC);
379        MDB2::loadFile('Iterator');
380
381        switch ($this->db->phptype) {
382            case 'mysqli':
383                $expect = 'mysqli_result';
384                break;
385            default:
386                $expect = 'resource';
387        }
388
389        // Regular behavior.
390
391        $res = $this->db->query('SELECT * FROM ' . $this->table_users);
392        $this->assertInstanceOf('MDB2_Result_Common', $res);
393
394        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, true);
395        $this->assertInstanceOf('MDB2_Result_Common', $res);
396
397        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, false);
398        if ($expect == 'resource') {
399            $this->assertInternalType('resource', $res);
400        } else {
401            $this->assertInstanceOf($expect, $res);
402        }
403
404        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, true, true);
405        $this->assertInstanceOf('MDB2_Result_Common', $res);
406
407        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, true, false);
408        $this->assertInstanceOf('MDB2_Result_Common', $res);
409
410        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, true, 'MDB2_BufferedIterator');
411        $this->assertEquals('MDB2_BufferedIterator', get_class($res));
412
413        // Setting third parameter to false forces raw results to be returned.
414
415        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, false, true);
416        if ($expect == 'resource') {
417            $this->assertInternalType('resource', $res);
418        } else {
419            $this->assertInstanceOf($expect, $res);
420        }
421
422        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, false, false);
423        if ($expect == 'resource') {
424            $this->assertInternalType('resource', $res);
425        } else {
426            $this->assertInstanceOf($expect, $res);
427        }
428
429        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, false, 'MDB2_BufferedIterator');
430        if ($expect == 'resource') {
431            $this->assertInternalType('resource', $res);
432        } else {
433            $this->assertInstanceOf($expect, $res);
434        }
435
436
437        // Utilize a default result wrap class.
438
439        $this->db->setOption('result_wrap_class', 'MDB2_Iterator');
440
441        $res = $this->db->query('SELECT * FROM ' . $this->table_users);
442        $this->assertEquals('MDB2_Iterator', get_class($res));
443
444        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, true);
445        $this->assertEquals('MDB2_Iterator', get_class($res));
446
447        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, false);
448        if ($expect == 'resource') {
449            $this->assertInternalType('resource', $res);
450        } else {
451            $this->assertInstanceOf($expect, $res);
452        }
453
454        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, true, true);
455        $this->assertEquals('MDB2_Iterator', get_class($res));
456
457        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, true, false);
458        $this->assertInstanceOf('MDB2_Result_Common', $res);
459
460        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, true, 'MDB2_BufferedIterator');
461        $this->assertEquals('MDB2_BufferedIterator', get_class($res));
462
463        // Setting third parameter to false forces raw results to be returned.
464
465        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, false, true);
466        if ($expect == 'resource') {
467            $this->assertInternalType('resource', $res);
468        } else {
469            $this->assertInstanceOf($expect, $res);
470        }
471
472        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, false, false);
473        if ($expect == 'resource') {
474            $this->assertInternalType('resource', $res);
475        } else {
476            $this->assertInstanceOf($expect, $res);
477        }
478
479        $res = $this->db->query('SELECT * FROM ' . $this->table_users, null, false, 'MDB2_BufferedIterator');
480        if ($expect == 'resource') {
481            $this->assertInternalType('resource', $res);
482        } else {
483            $this->assertInstanceOf($expect, $res);
484        }
485    }
486
487    /**
488     * non-static functions called statically
489     * @see https://pear.php.net/bugs/bug.php?id=18398
490     */
491    public function testBug18398() {
492        $oer = error_reporting(error_reporting() | E_STRICT);
493        $dsn = array('phptype' => 'x');
494        $db = new MDB2;
495        $db->connect($dsn);
496        error_reporting($oer);
497    }
498
499    /**
500     * Multiple database handles seem to collide
501     * @see http://pear.php.net/bugs/bug.php?id=15232
502     * @dataProvider provider
503     */
504    public function testBug15232($ci) {
505        $this->manualSetUp($ci);
506
507        $data = $this->getSampleData(1);
508
509        $this->db->beginTransaction();
510        $stmt = $this->db->prepare('INSERT INTO ' . $this->table_users . ' (' . implode(', ', array_keys($this->fields)) . ') VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', array_values($this->fields), MDB2_PREPARE_MANIP);
511        $result = $stmt->execute(array_values($data));
512
513        $result = $this->db->query('SELECT * FROM ' . $this->table_users);
514        $numrows = $result->numRows();
515        $this->assertEquals(1, $numrows, 'First connection did not insert.');
516
517        $ci['dsn']['new_link'] = true;
518        $db2 = MDB2::factory($ci['dsn'], $ci['options']);
519        if (MDB2::isError($db2)) {
520            $this->markTestSkipped($db2->getMessage());
521        }
522        $database = $db2->getDatabase();
523        $db2->setDatabase($database);
524        $result = $db2->query('SELECT * FROM ' . $this->table_users);
525        $numrows = $result->numRows();
526        $this->assertEquals(0, $numrows, 'Second connection should get no results.');
527
528        $stmt->free();
529    }
530
531    /**
532     * compareDefinition() turns NULL defaults into empty strings for
533     * NOT NULL columns
534     * @see http://pear.php.net/bugs/bug.php?id=16280
535     * @dataProvider provider
536     */
537    public function testBug16280($ci) {
538        $this->manualSetUp($ci);
539
540        $previous = array(
541            'notnull' => true,
542            'nativetype' => 'varchar',
543            'length' => '50',
544            'fixed' => false,
545            'default' => '',
546            'type' => 'text',
547            'mdb2type' => 'text',
548            'was' => 'name'
549        );
550        $current = array(
551            'type' => 'text',
552            'length' => '50',
553            'notnull' => true,
554            'was' => 'name'
555        );
556        $result = $this->db->compareDefinition($current, $previous);
557        $this->assertEquals(array('default' => 1), $result);
558    }
559
560    /**
561     * _compareIntegerDefinition() ignores length change
562     * @see http://pear.php.net/bugs/bug.php?id=18494
563     * @dataProvider provider
564     */
565    public function testBug18494($ci) {
566        $this->manualSetUp($ci);
567
568        $previous = array(
569            'notnull' => true,
570            'nativetype' => 'int',
571            'length' => 4,
572            'unsigned' => 1,
573            'default' => 42,
574            'type' => 'integer',
575            'mdb2type' => 'integer',
576            'was' => 'foo',
577        );
578        $current = array(
579            'notnull' => true,
580            'nativetype' => 'int',
581            'length' => 8,
582            'unsigned' => 1,
583            'default' => 42,
584            'type' => 'integer',
585            'mdb2type' => 'integer',
586            'was' => 'foo',
587        );
588        $result = $this->db->compareDefinition($current, $previous);
589        $this->assertEquals(array('length' => 8), $result);
590    }
591
592    /**
593     * Turning empty columns incorrectly to NULL
594     * @see http://pear.php.net/bugs/bug.php?id=16314
595     * @dataProvider provider
596     */
597    public function testBug16314($ci) {
598        $this->manualSetUp($ci);
599
600        $t = 'test_16314';
601
602        $this->db->setOption('field_case', CASE_LOWER);
603        $this->db->setOption('portability', MDB2_PORTABILITY_FIX_CASE | MDB2_PORTABILITY_ERRORS | MDB2_PORTABILITY_FIX_ASSOC_FIELD_NAMES);
604
605        $result = $this->db->exec("CREATE TABLE $t (id varchar(1) NOT NULL)");
606        if (MDB2::isError($result)) {
607            $this->fail('Error creating table: ' . $result->getMessage());
608        }
609
610        $stmt = $this->db->prepare("INSERT INTO $t VALUES (?)", null, MDB2_PREPARE_MANIP);
611        if (MDB2::isError($stmt)) {
612            $result = $this->db->exec("DROP TABLE $t");
613            if (MDB2::isError($result)) {
614                $this->fail('Error dropping table: ' . $result->getMessage());
615            }
616            $this->fail('Prepare had problem: ' . $stmt->getMessage());
617        }
618
619        $result = $stmt->execute(array(''));
620        if (MDB2::isError($result)) {
621            $result = $this->db->exec("DROP TABLE $t");
622            if (MDB2::isError($result)) {
623                $this->fail('Error dropping table: ' . $result->getMessage());
624            }
625            $this->fail('Error executing prepared query '.$result->getMessage());
626        }
627
628        $result = $this->db->exec("DROP TABLE $t");
629        if (MDB2::isError($result)) {
630            $this->fail('Error dropping table: ' . $result->getMessage());
631        }
632        $stmt->free();
633    }
634
635    /**
636     * prepare(), execute() fail when statement combines placeholders and
637     * null values
638     * @see http://pear.php.net/bugs/bug.php?id=17270
639     * @dataProvider provider
640     */
641    public function testBug17270($ci) {
642        $this->manualSetUp($ci);
643
644        $data = array(
645            'name' => 'Abcd',
646        );
647        $types = array(
648            'text',
649        );
650
651        $stmt = $this->db->prepare('INSERT INTO ' . $this->table_users . ' (user_name, user_password) VALUES (:name, NULL)', $types, MDB2_PREPARE_MANIP);
652        if (MDB2::isError($stmt)) {
653            $this->fail('Error preparing query: ' . $stmt->getMessage());
654        }
655
656        $result = $stmt->execute($data);
657        if (MDB2::isError($result)) {
658            $this->fail('Error executing query: ' . $result->getMessage());
659        }
660
661        $stmt->free();
662    }
663
664    /**
665     * Memory Leak in MDB2_Error and/or PEAR_Error
666     * @see http://pear.php.net/bugs/bug.php?id=12038
667     */
668    public function testBug12038() {
669        $this->markTestSkipped("Bug still exists.");
670
671        $mem_init = memory_get_usage();
672        $mem_times = 2;
673        $mem_stop = $mem_init * $mem_times;
674
675        for ($row = 0; $row < 1000; $row++) {
676            $pear = new PEAR;
677            // Okay.
678            //$pear->raiseError(null, 1, 'mode', array(), 'hi');
679            //$pear->raiseError(null, 1, 'mode', array(), 'hi', 'StdClass', true);
680            // Leaks
681            $pear->raiseError(null, 1, 'mode', array(), 'hi', 'MDB2_Error', true);
682            $mem_current = memory_get_usage();
683            if ($mem_current > $mem_stop) {
684                $this->fail("Memory has gotten $mem_times times bigger.");
685            }
686        }
687    }
688}
689