--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_ASSOC
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'B')");
+$db->exec("INSERT INTO test VALUES(3, 'C')");
+
+$stmt = $db->prepare('SELECT * from test');
+$stmt->execute();
+
+var_dump($stmt->fetchAll(PDO_FETCH_ASSOC));
+?>
+--EXPECT--
+array(3) {
+ [0]=>
+ array(2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(2) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_NUM
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'B')");
+$db->exec("INSERT INTO test VALUES(3, 'C')");
+
+$stmt = $db->prepare('SELECT * from test');
+$stmt->execute();
+
+var_dump($stmt->fetchAll(PDO_FETCH_NUM));
+?>
+--EXPECT--
+array(3) {
+ [0]=>
+ array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(2) {
+ [0]=>
+ string(1) "2"
+ [1]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(2) {
+ [0]=>
+ string(1) "3"
+ [1]=>
+ string(1) "C"
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_BOTH
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'B')");
+$db->exec("INSERT INTO test VALUES(3, 'C')");
+
+$stmt = $db->prepare('SELECT * from test');
+$stmt->execute();
+
+var_dump($stmt->fetchAll(PDO_FETCH_BOTH));
+?>
+--EXPECT--
+array(3) {
+ [0]=>
+ array(4) {
+ ["id"]=>
+ string(1) "1"
+ [0]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ [1]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(4) {
+ ["id"]=>
+ string(1) "2"
+ [0]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ [1]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(4) {
+ ["id"]=>
+ string(1) "3"
+ [0]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ [1]=>
+ string(1) "C"
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_OBJ
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'B')");
+$db->exec("INSERT INTO test VALUES(3, 'C')");
+
+$stmt = $db->prepare('SELECT * from test');
+$stmt->execute();
+
+var_dump($stmt->fetchAll(PDO_FETCH_OBJ));
+?>
+--EXPECTF--
+array(3) {
+ [0]=>
+ object(stdClass)#%d (2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ }
+ [1]=>
+ object(stdClass)#%d (2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ [2]=>
+ object(stdClass)#%d (2) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_CLASS
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A', 'AA')");
+$db->exec("INSERT INTO test VALUES(2, 'B', 'BB')");
+$db->exec("INSERT INTO test VALUES(3, 'C', 'CC')");
+
+$stmt = $db->prepare('SELECT id, val, val2 from test');
+
+class TestBase
+{
+ public $id;
+ protected $val;
+ private $val2;
+}
+
+class TestDerived extends TestBase
+{
+ protected $row;
+
+ public function __construct(&$row)
+ {
+ echo __METHOD__ . "($row,{$this->id})\n";
+ $this->row = $row++;
+ }
+}
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_CLASS));
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_CLASS, 'TestBase'));
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_CLASS, 'TestDerived', array(0)));
+
+?>
+--EXPECTF--
+array(3) {
+ [0]=>
+ object(stdClass)#%d (3) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ ["val2"]=>
+ string(2) "AA"
+ }
+ [1]=>
+ object(stdClass)#%d (3) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ ["val2"]=>
+ string(2) "BB"
+ }
+ [2]=>
+ object(stdClass)#%d (3) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ ["val2"]=>
+ string(2) "CC"
+ }
+}
+array(3) {
+ [0]=>
+ object(TestBase)#%d (3) {
+ ["id"]=>
+ string(1) "1"
+ ["val:protected"]=>
+ string(1) "A"
+ ["val2:private"]=>
+ string(2) "AA"
+ }
+ [1]=>
+ object(TestBase)#%d (3) {
+ ["id"]=>
+ string(1) "2"
+ ["val:protected"]=>
+ string(1) "B"
+ ["val2:private"]=>
+ string(2) "BB"
+ }
+ [2]=>
+ object(TestBase)#%d (3) {
+ ["id"]=>
+ string(1) "3"
+ ["val:protected"]=>
+ string(1) "C"
+ ["val2:private"]=>
+ string(2) "CC"
+ }
+}
+TestDerived::__construct(0,1)
+TestDerived::__construct(1,2)
+TestDerived::__construct(2,3)
+array(3) {
+ [0]=>
+ object(TestDerived)#%d (5) {
+ ["row:protected"]=>
+ int(0)
+ ["id"]=>
+ string(1) "1"
+ ["val:protected"]=>
+ string(1) "A"
+ ["val2:private"]=>
+ NULL
+ ["val2"]=>
+ string(2) "AA"
+ }
+ [1]=>
+ object(TestDerived)#%d (5) {
+ ["row:protected"]=>
+ int(1)
+ ["id"]=>
+ string(1) "2"
+ ["val:protected"]=>
+ string(1) "B"
+ ["val2:private"]=>
+ NULL
+ ["val2"]=>
+ string(2) "BB"
+ }
+ [2]=>
+ object(TestDerived)#%d (5) {
+ ["row:protected"]=>
+ int(2)
+ ["id"]=>
+ string(1) "3"
+ ["val:protected"]=>
+ string(1) "C"
+ ["val2:private"]=>
+ NULL
+ ["val2"]=>
+ string(2) "CC"
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_GROUP
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'A')");
+$db->exec("INSERT INTO test VALUES(3, 'C')");
+
+$stmt = $db->prepare('SELECT val, id from test');
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_NUM|PDO_FETCH_GROUP));
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_ASSOC|PDO_FETCH_GROUP));
+
+?>
+--EXPECT--
+array(2) {
+ ["A"]=>
+ array(2) {
+ [0]=>
+ array(1) {
+ [0]=>
+ string(1) "1"
+ }
+ [1]=>
+ array(1) {
+ [0]=>
+ string(1) "2"
+ }
+ }
+ ["C"]=>
+ array(1) {
+ [0]=>
+ array(1) {
+ [0]=>
+ string(1) "3"
+ }
+ }
+}
+array(2) {
+ ["A"]=>
+ array(2) {
+ [0]=>
+ array(1) {
+ ["id"]=>
+ string(1) "1"
+ }
+ [1]=>
+ array(1) {
+ ["id"]=>
+ string(1) "2"
+ }
+ }
+ ["C"]=>
+ array(1) {
+ [0]=>
+ array(1) {
+ ["id"]=>
+ string(1) "3"
+ }
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_UNIQUE
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id CHAR(1) NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES('A', 'A')");
+$db->exec("INSERT INTO test VALUES('B', 'A')");
+$db->exec("INSERT INTO test VALUES('C', 'C')");
+
+$stmt = $db->prepare('SELECT id, val from test');
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_NUM|PDO_FETCH_UNIQUE));
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_ASSOC|PDO_FETCH_UNIQUE));
+
+?>
+--EXPECT--
+array(3) {
+ ["A"]=>
+ array(1) {
+ [0]=>
+ string(1) "A"
+ }
+ ["B"]=>
+ array(1) {
+ [0]=>
+ string(1) "A"
+ }
+ ["C"]=>
+ array(1) {
+ [0]=>
+ string(1) "C"
+ }
+}
+array(3) {
+ ["A"]=>
+ array(1) {
+ ["val"]=>
+ string(1) "A"
+ }
+ ["B"]=>
+ array(1) {
+ ["val"]=>
+ string(1) "A"
+ }
+ ["C"]=>
+ array(1) {
+ ["val"]=>
+ string(1) "C"
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_UNIQUE conflict
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id CHAR(1) NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES('A', 'A')");
+$db->exec("INSERT INTO test VALUES('B', 'A')");
+$db->exec("INSERT INTO test VALUES('C', 'C')");
+
+$stmt = $db->prepare('SELECT val, id from test');
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_NUM|PDO_FETCH_UNIQUE));
+
+?>
+--EXPECT--
+array(2) {
+ ["A"]=>
+ array(1) {
+ [0]=>
+ string(1) "B"
+ }
+ ["C"]=>
+ array(1) {
+ [0]=>
+ string(1) "C"
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_CLASSTYPE
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE classtypes(id int NOT NULL PRIMARY KEY, name VARCHAR(10) UNIQUE)');
+$db->exec('INSERT INTO classtypes VALUES(0, \'stdClass\')');
+$db->exec('INSERT INTO classtypes VALUES(1, \'Test1\')');
+$db->exec('INSERT INTO classtypes VALUES(2, \'Test2\')');
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, classtype int, val VARCHAR(10))');
+$db->exec('INSERT INTO test VALUES(1, 0, \'A\')');
+$db->exec('INSERT INTO test VALUES(2, 1, \'B\')');
+$db->exec('INSERT INTO test VALUES(3, 2, \'C\')');
+$db->exec('INSERT INTO test VALUES(4, 3, \'D\')');
+
+$stmt = $db->prepare('SELECT classtypes.name, test.id AS id, test.val AS val FROM test LEFT JOIN classtypes ON test.classtype=classtypes.id');
+
+class Test1
+{
+ public function __construct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+class Test2
+{
+ public function __construct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+class Test3
+{
+ public function __construct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_NUM));
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_CLASS|PDO_FETCH_CLASSTYPE, 'Test3'));
+
+?>
+--EXPECTF--
+array(4) {
+ [0]=>
+ array(3) {
+ [0]=>
+ string(8) "stdClass"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(3) {
+ [0]=>
+ string(5) "Test1"
+ [1]=>
+ string(1) "2"
+ [2]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(3) {
+ [0]=>
+ string(5) "Test2"
+ [1]=>
+ string(1) "3"
+ [2]=>
+ string(1) "C"
+ }
+ [3]=>
+ array(3) {
+ [0]=>
+ NULL
+ [1]=>
+ string(1) "4"
+ [2]=>
+ string(1) "D"
+ }
+}
+Test1::__construct()
+Test2::__construct()
+Test3::__construct()
+array(4) {
+ [0]=>
+ object(stdClass)#%d (2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ }
+ [1]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ [2]=>
+ object(Test2)#%d (2) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ }
+ [3]=>
+ object(Test3)#%d (2) {
+ ["id"]=>
+ string(1) "4"
+ ["val"]=>
+ string(1) "D"
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_CLASSTYPE and GROUP/UNIQUE
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE classtypes(id int NOT NULL PRIMARY KEY, name VARCHAR(10) UNIQUE)');
+$db->exec('INSERT INTO classtypes VALUES(0, \'stdClass\')');
+$db->exec('INSERT INTO classtypes VALUES(1, \'Test1\')');
+$db->exec('INSERT INTO classtypes VALUES(2, \'Test2\')');
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, classtype int, val VARCHAR(10), grp VARCHAR(10))');
+$db->exec('INSERT INTO test VALUES(1, 0, \'A\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(2, 1, \'B\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(3, 2, \'C\', \'Group2\')');
+$db->exec('INSERT INTO test VALUES(4, 3, \'D\', \'Group2\')');
+
+$stmt = $db->prepare('SELECT classtypes.name, test.grp AS grp, test.id AS id, test.val AS val FROM test LEFT JOIN classtypes ON test.classtype=classtypes.id');
+
+class Test1
+{
+ public function __construct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+class Test2
+{
+ public function __construct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+class Test3
+{
+ public function __construct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_CLASS|PDO_FETCH_CLASSTYPE|PDO_FETCH_GROUP, 'Test3'));
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_CLASS|PDO_FETCH_CLASSTYPE|PDO_FETCH_UNIQUE, 'Test3'));
+
+?>
+--EXPECTF--
+Test1::__construct()
+Test2::__construct()
+Test3::__construct()
+array(2) {
+ ["Group1"]=>
+ array(2) {
+ [0]=>
+ object(stdClass)#%d (2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ }
+ [1]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ }
+ ["Group2"]=>
+ array(2) {
+ [0]=>
+ object(Test2)#%d (2) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ }
+ [1]=>
+ object(Test3)#%d (2) {
+ ["id"]=>
+ string(1) "4"
+ ["val"]=>
+ string(1) "D"
+ }
+ }
+}
+Test1::__construct()
+Test2::__construct()
+Test3::__construct()
+array(2) {
+ ["Group1"]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ ["Group2"]=>
+ object(Test3)#%d (2) {
+ ["id"]=>
+ string(1) "4"
+ ["val"]=>
+ string(1) "D"
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_FUNC and statement overloading
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10), grp VARCHAR(10))');
+$db->exec('INSERT INTO test VALUES(1, \'A\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(2, \'B\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(3, \'C\', \'Group2\')');
+$db->exec('INSERT INTO test VALUES(4, \'D\', \'Group2\')');
+
+class DerivedStatement extends PDOStatement
+{
+ private function __construct($name, $db)
+ {
+ $this->name = $name;
+ echo __METHOD__ . "($name)\n";
+ }
+
+ function retrieve($id, $val) {
+ echo __METHOD__ . "($id,$val)\n";
+ return array($id=>$val);
+ }
+}
+
+$select1 = $db->prepare('SELECT grp, id FROM test');
+$select2 = $db->prepare('SELECT id, val FROM test');
+$derived = $db->prepare('SELECT id, val FROM test', array(PDO_ATTR_STATEMENT_CLASS=>array('DerivedStatement', array('Overloaded', $db))));
+
+class Test1
+{
+ public function __construct($id, $val)
+ {
+ echo __METHOD__ . "($id,$val)\n";
+ $this->id = $id;
+ $this->val = $val;
+ }
+
+ static public function factory($id, $val)
+ {
+ echo __METHOD__ . "($id,$val)\n";
+ return new self($id, $val);
+ }
+}
+
+function test($id,$val='N/A')
+{
+ echo __METHOD__ . "($id,$val)\n";
+ return array($id=>$val);
+}
+
+$f = new Test1(0,0);
+
+$select1->execute();
+var_dump($select1->fetchAll(PDO_FETCH_FUNC|PDO_FETCH_GROUP, 'test'));
+
+$select2->execute();
+var_dump($select2->fetchAll(PDO_FETCH_FUNC, 'test'));
+
+$select2->execute();
+var_dump($select2->fetchAll(PDO_FETCH_FUNC, array('Test1','factory')));
+
+$select2->execute();
+var_dump($select2->fetchAll(PDO_FETCH_FUNC, array($f, 'factory')));
+
+var_dump(get_class($derived));
+$derived->execute();
+var_dump($derived->fetchAll(PDO_FETCH_FUNC, array($derived, 'retrieve')));
+
+?>
+--EXPECTF--
+DerivedStatement::__construct(Overloaded)
+Test1::__construct(0,0)
+test(1,N/A)
+test(2,N/A)
+test(3,N/A)
+test(4,N/A)
+array(2) {
+ ["Group1"]=>
+ array(2) {
+ [0]=>
+ array(1) {
+ [1]=>
+ string(3) "N/A"
+ }
+ [1]=>
+ array(1) {
+ [2]=>
+ string(3) "N/A"
+ }
+ }
+ ["Group2"]=>
+ array(2) {
+ [0]=>
+ array(1) {
+ [3]=>
+ string(3) "N/A"
+ }
+ [1]=>
+ array(1) {
+ [4]=>
+ string(3) "N/A"
+ }
+ }
+}
+test(1,A)
+test(2,B)
+test(3,C)
+test(4,D)
+array(4) {
+ [0]=>
+ array(1) {
+ [1]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(1) {
+ [2]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(1) {
+ [3]=>
+ string(1) "C"
+ }
+ [3]=>
+ array(1) {
+ [4]=>
+ string(1) "D"
+ }
+}
+Test1::factory(1,A)
+Test1::__construct(1,A)
+Test1::factory(2,B)
+Test1::__construct(2,B)
+Test1::factory(3,C)
+Test1::__construct(3,C)
+Test1::factory(4,D)
+Test1::__construct(4,D)
+array(4) {
+ [0]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ }
+ [1]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ [2]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ }
+ [3]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "4"
+ ["val"]=>
+ string(1) "D"
+ }
+}
+Test1::factory(1,A)
+Test1::__construct(1,A)
+Test1::factory(2,B)
+Test1::__construct(2,B)
+Test1::factory(3,C)
+Test1::__construct(3,C)
+Test1::factory(4,D)
+Test1::__construct(4,D)
+array(4) {
+ [0]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ }
+ [1]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ [2]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ }
+ [3]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "4"
+ ["val"]=>
+ string(1) "D"
+ }
+}
+string(16) "DerivedStatement"
+DerivedStatement::retrieve(1,A)
+DerivedStatement::retrieve(2,B)
+DerivedStatement::retrieve(3,C)
+DerivedStatement::retrieve(4,D)
+array(4) {
+ [0]=>
+ array(1) {
+ [1]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(1) {
+ [2]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(1) {
+ [3]=>
+ string(1) "C"
+ }
+ [3]=>
+ array(1) {
+ [4]=>
+ string(1) "D"
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: PDOStatement::setFetchMode
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10), grp VARCHAR(10))');
+$db->exec('INSERT INTO test VALUES(1, \'A\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(2, \'B\', \'Group2\')');
+
+$SELECT = 'SELECT val, grp FROM test';
+
+$stmt = $db->query($SELECT, PDO_FETCH_NUM);
+var_dump($stmt->fetchAll());
+
+class Test
+{
+ function __construct($name = 'N/A')
+ {
+ echo __METHOD__ . "($name)\n";
+ }
+}
+
+$stmt = $db->query($SELECT, PDO_FETCH_CLASS, 'Test');
+var_dump($stmt->fetchAll());
+
+$stmt = $db->query($SELECT, PDO_FETCH_NUM);
+$stmt->setFetchMode(PDO_FETCH_CLASS, 'Test', array('Changed'));
+var_dump($stmt->fetchAll());
+
+?>
+--EXPECTF--
+array(2) {
+ [0]=>
+ array(2) {
+ [0]=>
+ string(1) "A"
+ [1]=>
+ string(6) "Group1"
+ }
+ [1]=>
+ array(2) {
+ [0]=>
+ string(1) "B"
+ [1]=>
+ string(6) "Group2"
+ }
+}
+Test::__construct(N/A)
+Test::__construct(N/A)
+array(2) {
+ [0]=>
+ object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "A"
+ ["grp"]=>
+ string(6) "Group1"
+ }
+ [1]=>
+ object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "B"
+ ["grp"]=>
+ string(6) "Group2"
+ }
+}
+Test::__construct(Changed)
+Test::__construct(Changed)
+array(2) {
+ [0]=>
+ object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "A"
+ ["grp"]=>
+ string(6) "Group1"
+ }
+ [1]=>
+ object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "B"
+ ["grp"]=>
+ string(6) "Group2"
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: PDOStatement iterator
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10), grp VARCHAR(10))');
+$db->exec('INSERT INTO test VALUES(1, \'A\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(2, \'B\', \'Group2\')');
+
+$SELECT = 'SELECT val, grp FROM test';
+
+$stmt = $db->prepare($SELECT);
+
+$stmt->execute();
+$stmt->setFetchMode(PDO_FETCH_NUM);
+foreach ($stmt as $data)
+{
+ var_dump($data);
+}
+
+class Test
+{
+ function __construct($name = 'N/A')
+ {
+ echo __METHOD__ . "($name)\n";
+ }
+}
+
+foreach ($db->query($SELECT, PDO_FETCH_CLASS, 'Test') as $data)
+{
+ var_dump($data);
+}
+
+$stmt = $db->query($SELECT, PDO_FETCH_CLASS, 'Test', array('WOW'));
+
+foreach($stmt as $data)
+{
+ var_dump($data);
+}
+?>
+--EXPECTF--
+array(2) {
+ [0]=>
+ string(1) "A"
+ [1]=>
+ string(6) "Group1"
+}
+array(2) {
+ [0]=>
+ string(1) "B"
+ [1]=>
+ string(6) "Group2"
+}
+Test::__construct(N/A)
+object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "A"
+ ["grp"]=>
+ string(6) "Group1"
+}
+Test::__construct(N/A)
+object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "B"
+ ["grp"]=>
+ string(6) "Group2"
+}
+Test::__construct(WOW)
+object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "A"
+ ["grp"]=>
+ string(6) "Group1"
+}
+Test::__construct(WOW)
+object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "B"
+ ["grp"]=>
+ string(6) "Group2"
+}
--- /dev/null
+--TEST--
+PDO Common: PDOStatement SPL iterator
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver';
+if (!extension_loaded('SPL')) print 'skip SPL not available';
+if (!class_exists('IteratorIterator')) print 'skip IteratorIterator class not present';
+?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10), grp VARCHAR(10))');
+$db->exec('INSERT INTO test VALUES(1, \'A\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(2, \'B\', \'Group2\')');
+$SELECT = 'SELECT val, grp FROM test';
+
+class Test
+{
+ function __construct($name = 'N/A')
+ {
+ echo __METHOD__ . "($name)\n";
+ }
+}
+
+$stmt = $db->query($SELECT, PDO_FETCH_CLASS, 'Test', array('WOW'));
+
+$it = new IteratorIterator($stmt); /* check if we can convert that thing */
+
+/*** HINT: If YOU plan to do so remember not to call rewind() -> see below ***/
+
+foreach($it as $data)
+{
+ var_dump($data);
+}
+
+$it->next(); /* must be allowed */
+var_dump($it->current()); /* must return NULL */
+var_dump($it->valid()); /* must return false */
+
+class PDOStatementAggregate extends PDOStatement implements IteratorAggregate
+{
+ private function __construct()
+ {
+ echo __METHOD__ . "\n";
+ $this->setFetchMode(PDO_FETCH_NUM);
+ /* default fetch mode is BOTH, so we see if the ctor can overwrite that */
+ }
+
+ function getIterator()
+ {
+ echo __METHOD__ . "\n";
+ $this->execute();
+ return new IteratorIterator($this, 'PDOStatement');
+ }
+}
+
+$stmt = $db->prepare($SELECT, array(PDO_ATTR_STATEMENT_CLASS=>array('PDOStatementAggregate')));
+
+foreach($stmt as $data)
+{
+ var_dump($data);
+}
+
+?>
+--EXPECTF--
+Test::__construct(WOW)
+object(Test)#4 (2) {
+ ["val"]=>
+ string(1) "A"
+ ["grp"]=>
+ string(6) "Group1"
+}
+Test::__construct(WOW)
+object(Test)#6 (2) {
+ ["val"]=>
+ string(1) "B"
+ ["grp"]=>
+ string(6) "Group2"
+}
+NULL
+bool(false)
+PDOStatementAggregate::__construct
+PDOStatementAggregate::getIterator
+array(2) {
+ [0]=>
+ string(1) "A"
+ [1]=>
+ string(6) "Group1"
+}
+array(2) {
+ [0]=>
+ string(1) "B"
+ [1]=>
+ string(6) "Group2"
+}
--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_COLUMN
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(20))');
+$db->exec('INSERT INTO test VALUES(1, \'A\', \'A2\')');
+$db->exec('INSERT INTO test VALUES(2, \'A\', \'B2\')');
+
+$select1 = $db->prepare('SELECT id, val, val2 FROM test');
+$select2 = $db->prepare('SELECT val, val2 FROM test');
+
+$select1->execute();
+var_dump($select1->fetchAll(PDO_FETCH_COLUMN));
+$select1->execute();
+var_dump($select1->fetchAll(PDO_FETCH_COLUMN, 2));
+$select1->execute();
+var_dump($select1->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_GROUP));
+$select1->execute();
+var_dump($select1->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_UNIQUE));
+$select1->execute();
+var_dump($select1->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_UNIQUE, 0));
+$select1->execute();
+var_dump($select1->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_UNIQUE, 1));
+$select1->execute();
+var_dump($select1->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_UNIQUE, 2));
+
+$select2->execute();
+var_dump($select2->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_GROUP));
+
+?>
+--EXPECT--
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "2"
+}
+array(2) {
+ [0]=>
+ string(2) "A2"
+ [1]=>
+ string(2) "B2"
+}
+array(2) {
+ [1]=>
+ array(1) {
+ [0]=>
+ string(1) "A"
+ }
+ [2]=>
+ array(1) {
+ [0]=>
+ string(1) "A"
+ }
+}
+array(2) {
+ [1]=>
+ string(1) "A"
+ [2]=>
+ string(1) "A"
+}
+array(2) {
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "2"
+}
+array(2) {
+ [1]=>
+ string(1) "A"
+ [2]=>
+ string(1) "A"
+}
+array(2) {
+ [1]=>
+ string(2) "A2"
+ [2]=>
+ string(2) "B2"
+}
+array(1) {
+ ["A"]=>
+ array(2) {
+ [0]=>
+ string(2) "A2"
+ [1]=>
+ string(2) "B2"
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_BOUND
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver'; ?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(idx int NOT NULL PRIMARY KEY, txt VARCHAR(20))');
+$db->exec('INSERT INTO test VALUES(0, \'String0\')');
+$db->exec('INSERT INTO test VALUES(1, \'String1\')');
+$db->exec('INSERT INTO test VALUES(2, \'String2\')');
+$stmt1 = $db->prepare('SELECT COUNT(idx) FROM test');
+$stmt2 = $db->prepare('SELECT idx, txt FROM test ORDER by idx');
+
+$stmt1->execute();
+var_dump($stmt1->fetchColumn());
+
+$stmt2->execute();
+$cont = $stmt2->fetchAll();
+var_dump($cont);
+
+$stmt2->execute();
+$cont = $stmt2->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_UNIQUE);
+var_dump($cont);
+
+echo "===WHILE===\n";
+
+$stmt2->bindColumn('idx', $idx);
+$stmt2->bindColumn('txt', $txt);
+$stmt2->execute();
+
+while($stmt2->fetch(PDO_FETCH_BOUND)) {
+ var_dump(array($idx=>$txt));
+}
+
+echo "===ALONE===\n";
+
+$stmt3 = $db->prepare('SELECT txt FROM test WHERE idx=:inp');
+$stmt3->bindParam(':inp', $idx); /* by foreign name */
+
+$stmt4 = $db->prepare('SELECT idx FROM test WHERE txt=:txt');
+$stmt4->bindParam(':txt', $txt); /* using same name */
+
+foreach($cont as $idx => $txt)
+{
+ var_dump(array($idx=>$txt));
+ var_dump($stmt3->execute());
+
+ if ($idx == 0) {
+ /* portability-wise, you may only bindColumn()s
+ * after execute() has been called at least once */
+ $stmt3->bindColumn('txt', $col1);
+ }
+ var_dump($stmt3->fetch(PDO_FETCH_BOUND));
+
+ var_dump($stmt4->execute());
+ if ($idx == 0) {
+ /* portability-wise, you may only bindColumn()s
+ * after execute() has been called at least once */
+ $stmt4->bindColumn('idx', $col2);
+ }
+ var_dump($stmt4->fetch(PDO_FETCH_BOUND));
+ var_dump(array($col2=>$col1));
+}
+
+echo "===REBIND/SAME===\n";
+
+$stmt4->bindColumn('idx', $col1);
+
+foreach($cont as $idx => $txt)
+{
+ var_dump(array($idx=>$txt));
+ var_dump($stmt3->execute());
+ var_dump($stmt3->fetch(PDO_FETCH_BOUND));
+ var_dump($col1);
+ var_dump($stmt4->execute());
+ var_dump($stmt4->fetch(PDO_FETCH_BOUND));
+ var_dump($col1);
+}
+
+echo "===REBIND/CONFLICT===\n";
+
+$stmt2->bindColumn('idx', $col1);
+$stmt2->bindColumn('txt', $col1);
+$stmt2->execute();
+
+while($stmt2->fetch(PDO_FETCH_BOUND))
+{
+ var_dump($col1);
+}
+
+
+?>
+--EXPECT--
+string(1) "3"
+array(3) {
+ [0]=>
+ string(7) "String0"
+ [1]=>
+ string(7) "String1"
+ [2]=>
+ string(7) "String2"
+}
+===WHILE===
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+===ALONE===
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+===REBIND/SAME===
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+bool(true)
+bool(true)
+string(7) "String0"
+bool(true)
+bool(true)
+string(1) "0"
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+bool(true)
+bool(true)
+string(7) "String1"
+bool(true)
+bool(true)
+string(1) "1"
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+bool(true)
+bool(true)
+string(7) "String2"
+bool(true)
+bool(true)
+string(1) "2"
+===REBIND/CONFLICT===
+string(7) "String0"
+string(7) "String1"
+string(7) "String2"
--- /dev/null
+--TEST--
+PDO Common: transactions
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver';
+/* TODO:
+$db = PDOTest::factory();
+try {
+ $db->beginTransaction();
+} catch (PDOException $e) {
+ # check sqlstate to see if transactions
+ # are not implemented; if so, skip
+}
+*/
+?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'B')");
+$db->exec("INSERT INTO test VALUES(3, 'C')");
+$delete = $db->prepare('DELETE FROM test');
+
+function countRows($action) {
+ global $db;
+ $select = $db->prepare('SELECT COUNT(*) FROM test');
+ $select->execute();
+ $res = $select->fetchColumn();
+ return "Counted $res rows after $action.\n";
+}
+
+echo countRows('insert');
+
+$db->beginTransaction();
+$delete->execute();
+echo countRows('delete');
+$db->rollBack();
+
+echo countRows('rollback');
+
+?>
+--EXPECT--
+Counted 3 rows after insert.
+Counted 0 rows after delete.
+Counted 3 rows after rollback.
--- /dev/null
+--TEST--
+PDO Common: serializing
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver';
+if (!interface_exists('Serializable')) print 'skip no Serializable interface';
+?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+class TestBase implements Serializable
+{
+ public $BasePub = 'Public';
+ protected $BasePro = 'Protected';
+ private $BasePri = 'Private';
+
+ function serialize()
+ {
+ $serialized = array();
+ foreach($this as $prop => $val) {
+ $serialized[$prop] = $val;
+ }
+ $serialized = serialize($serialized);
+ echo __METHOD__ . "() = '$serialized'\n";
+ return $serialized;
+ }
+
+ function unserialize($serialized)
+ {
+ echo __METHOD__ . "($serialized)\n";
+ foreach(unserialize($serialized) as $prop => $val) {
+ $this->$prop = '#'.$val;
+ }
+ return true;
+ }
+}
+
+class TestDerived extends TestBase
+{
+ public $BasePub = 'DerivedPublic';
+ protected $BasePro = 'DerivdeProtected';
+ public $DerivedPub = 'Public';
+ protected $DerivedPro = 'Protected';
+ private $DerivedPri = 'Private';
+
+ function serialize()
+ {
+ echo __METHOD__ . "()\n";
+ return TestBase::serialize();
+ }
+
+ function unserialize($serialized)
+ {
+ echo __METHOD__ . "()\n";
+ return TestBase::unserialize($serialized);
+ }
+}
+
+class TestLeaf extends TestDerived
+{
+}
+
+$db->exec('CREATE TABLE classtypes(id int NOT NULL PRIMARY KEY, name VARCHAR(20) UNIQUE)');
+$db->exec('INSERT INTO classtypes VALUES(0, \'stdClass\')');
+$db->exec('INSERT INTO classtypes VALUES(1, \'TestBase\')');
+$db->exec('INSERT INTO classtypes VALUES(2, \'TestDerived\')');
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, classtype int, val VARCHAR(255))');
+
+$db->setAttribute(PDO_ATTR_ERRMODE, PDO_ERRMODE_EXCEPTION);
+
+var_dump($db->query('SELECT COUNT(*) FROM classtypes')->fetchColumn());
+var_dump($db->query('SELECT id, name FROM classtypes ORDER by id')->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_UNIQUE));
+
+$objs = array();
+$objs[0] = new stdClass;
+$objs[1] = new TestBase;
+$objs[2] = new TestDerived;
+$objs[3] = new TestLeaf;
+
+$stmt = $db->prepare('SELECT id FROM classtypes WHERE name=:cname');
+$stmt->bindParam(':cname', $cname);
+$stmt->bindColumn('id', $ctype);
+
+$ctypes = array();
+
+foreach($objs as $obj)
+{
+ $cname = get_class($obj);
+ $ctype = NULL; /* set default for non stored class name */
+ $stmt->execute();
+ $stmt->fetch(PDO_FETCH_BOUND);
+ $ctypes[$cname] = $ctype;
+}
+
+echo "===TYPES===\n";
+var_dump($ctypes);
+
+echo "===INSERT===\n";
+$stmt = $db->prepare('INSERT INTO test VALUES(:id, :classtype, :val)');
+$stmt->bindParam(':id', $idx);
+$stmt->bindParam(':classtype', $ctype);
+$stmt->bindParam(':val', $val);
+
+foreach($objs as $idx => $obj)
+{
+ $ctype = $ctypes[get_class($obj)];
+ if (method_exists($obj, 'serialize'))
+ {
+ $val = $obj->serialize();
+ }
+ else
+ {
+ $val = NULL;
+ }
+ $stmt->execute();
+}
+
+echo "===DATA===\n";
+var_dump($db->query('SELECT test.val FROM test')->fetchAll(PDO_FETCH_COLUMN));
+
+echo "===FAILURE===\n";
+try
+{
+ $db->query('SELECT classtypes.name AS name, test.val AS val FROM test LEFT JOIN classtypes ON test.classtype=classtypes.id')->fetchAll(PDO_FETCH_CLASS|PDO_FETCH_CLASSTYPE|PDO_FETCH_SERIALIZE, 'TestLeaf', array());
+}
+catch (PDOException $e)
+{
+ echo 'Exception:';
+ echo $e->getMessage()."\n";
+}
+
+echo "===COUNT===\n";
+var_dump($db->query('SELECT COUNT(*) FROM test LEFT JOIN classtypes ON test.classtype=classtypes.id WHERE (classtypes.id IS NULL OR classtypes.id > 0)')->fetchColumn());
+
+echo "===DATABASE===\n";
+$stmt = $db->prepare('SELECT classtypes.name AS name, test.val AS val FROM test LEFT JOIN classtypes ON test.classtype=classtypes.id WHERE (classtypes.id IS NULL OR classtypes.id > 0)');
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_ASSOC));
+
+echo "===FETCHCLASS===\n";
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO_FETCH_CLASS|PDO_FETCH_CLASSTYPE|PDO_FETCH_SERIALIZE, 'TestLeaf'));
+
+
+?>
+--EXPECTF--
+string(1) "3"
+array(3) {
+ [0]=>
+ string(8) "stdClass"
+ [1]=>
+ string(8) "TestBase"
+ [2]=>
+ string(11) "TestDerived"
+}
+===TYPES===
+array(4) {
+ ["stdClass"]=>
+ string(1) "0"
+ ["TestBase"]=>
+ string(1) "1"
+ ["TestDerived"]=>
+ string(1) "2"
+ ["TestLeaf"]=>
+ NULL
+}
+===INSERT===
+TestBase::serialize() = 'a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}'
+TestDerived::serialize()
+TestBase::serialize() = 'a:4:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";}'
+TestDerived::serialize()
+TestBase::serialize() = 'a:4:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";}'
+===DATA===
+array(4) {
+ [0]=>
+ NULL
+ [1]=>
+ string(91) "a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}"
+ [2]=>
+ string(144) "a:4:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";}"
+ [3]=>
+ string(144) "a:4:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";}"
+}
+===FAILURE===
+Exception:SQLSTATE[HY000]: General error: cannot unserialize class
+===COUNT===
+string(1) "3"
+===DATABASE===
+array(3) {
+ [0]=>
+ array(2) {
+ ["name"]=>
+ string(8) "TestBase"
+ ["val"]=>
+ string(91) "a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}"
+ }
+ [1]=>
+ array(2) {
+ ["name"]=>
+ string(11) "TestDerived"
+ ["val"]=>
+ string(144) "a:4:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";}"
+ }
+ [2]=>
+ array(2) {
+ ["name"]=>
+ NULL
+ ["val"]=>
+ string(144) "a:4:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";}"
+ }
+}
+===FETCHCLASS===
+TestBase::unserialize(a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";})
+TestDerived::unserialize()
+TestBase::unserialize(a:4:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";})
+TestDerived::unserialize()
+TestBase::unserialize(a:4:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";})
+array(3) {
+ [0]=>
+ object(TestBase)#%d (3) {
+ ["BasePub"]=>
+ string(7) "#Public"
+ ["BasePro:protected"]=>
+ string(10) "#Protected"
+ ["BasePri:private"]=>
+ string(8) "#Private"
+ }
+ [1]=>
+ object(TestDerived)#%d (6) {
+ ["BasePub"]=>
+ string(14) "#DerivedPublic"
+ ["BasePro:protected"]=>
+ string(17) "#DerivdeProtected"
+ ["DerivedPub"]=>
+ string(7) "#Public"
+ ["DerivedPro:protected"]=>
+ string(10) "#Protected"
+ ["DerivedPri:private"]=>
+ string(7) "Private"
+ ["BasePri:private"]=>
+ string(7) "Private"
+ }
+ [2]=>
+ object(TestLeaf)#%d (6) {
+ ["BasePub"]=>
+ string(14) "#DerivedPublic"
+ ["BasePro:protected"]=>
+ string(17) "#DerivdeProtected"
+ ["DerivedPub"]=>
+ string(7) "#Public"
+ ["DerivedPro:protected"]=>
+ string(10) "#Protected"
+ ["DerivedPri:private"]=>
+ string(7) "Private"
+ ["BasePri:private"]=>
+ string(7) "Private"
+ }
+}
--- /dev/null
+--TEST--
+PDO Common: fetch() and while()
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver';
+?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(idx int NOT NULL PRIMARY KEY, txt VARCHAR(20))');
+$db->exec('INSERT INTO test VALUES(0, \'String0\')');
+$db->exec('INSERT INTO test VALUES(1, \'String1\')');
+$db->exec('INSERT INTO test VALUES(2, \'String2\')');
+$db->exec('INSERT INTO test VALUES(3, \'String3\')');
+
+
+var_dump($db->query('SELECT COUNT(*) FROM test')->fetchColumn());
+
+$stmt = $db->prepare('SELECT idx, txt FROM test ORDER by idx');
+
+$stmt->execute();
+$cont = $stmt->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_UNIQUE);
+var_dump($cont);
+
+echo "===WHILE===\n";
+
+$stmt->bindColumn('idx', $idx);
+$stmt->bindColumn('txt', $txt);
+$stmt->execute();
+
+while($stmt->fetch(PDO_FETCH_BOUND)) {
+ var_dump(array($idx=>$txt));
+}
+
+?>
+--EXPECT--
+string(1) "4"
+array(4) {
+ [0]=>
+ string(7) "String0"
+ [1]=>
+ string(7) "String1"
+ [2]=>
+ string(7) "String2"
+ [3]=>
+ string(7) "String3"
+}
+===WHILE===
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+array(1) {
+ [3]=>
+ string(7) "String3"
+}
--- /dev/null
+--TEST--
+PDO Common: PDOStatement::columnCount
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver';
+?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
+$db->exec("INSERT INTO test VALUES(1, 'A', 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'B', 'B')");
+$db->exec("INSERT INTO test VALUES(3, 'C', 'C')");
+
+foreach (array('SELECT id, val FROM test', 'SELECT id, val, val2 FROM test', 'SELECT COUNT(*) FROM test') as $sql) {
+
+ $stmt = $db->query($sql);
+ $res = $stmt->columnCount();
+ echo "Counted $res columns after $sql.\n";
+ $stmt = null;
+}
+
+?>
+--EXPECT--
+Counted 2 columns after SELECT id, val FROM test.
+Counted 3 columns after SELECT id, val, val2 FROM test.
+Counted 1 columns after SELECT COUNT(*) FROM test.
--- /dev/null
+--TEST--
+PDO Common: PDOStatement::execute with parameters
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver';
+?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
+
+$select = $db->prepare('SELECT COUNT(*) FROM test');
+
+$data = array(
+ array('10', 'Abc', 'zxy'),
+ array('20', 'Def', 'wvu'),
+ array('30', 'Ghi', 'tsr'),
+ array('40', 'Jkl', 'qpo'),
+ array('50', 'Mno', 'nml'),
+ array('60', 'Pqr', 'kji'),
+);
+
+
+// Insert using question mark placeholders
+$stmt = $db->prepare("INSERT INTO test VALUES(?, ?, ?)");
+foreach ($data as $row) {
+ $stmt->execute($row);
+}
+
+$select->execute();
+$num = $select->fetchColumn();
+echo 'There are ' . $num . " rows in the table.\n";
+
+// Insert using named parameters
+$stmt2 = $db->prepare("INSERT INTO test VALUES(:first, :second, :third)");
+foreach ($data as $row) {
+ $stmt2->execute(array(':first'=>($row[0] + 5), ':second'=>$row[1],
+ ':third'=>$row[2]));
+}
+
+$select->execute();
+$num = $select->fetchColumn();
+echo 'There are ' . $num . " rows in the table.\n";
+
+
+?>
+--EXPECT--
+There are 6 rows in the table.
+There are 12 rows in the table.
--- /dev/null
+--TEST--
+PDO Common: PDOStatement::getColumnMeta
+--SKIPIF--
+<?php # vim:ft=php
+die('skip this feature is not yet finalized, no test makes sense');
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver';
+/*
+ * Note well: meta information is a nightmare to handle portably.
+ * it's not really PDOs job.
+ * We've not yet defined exactly what makes sense for getColumnMeta,
+ * so no tests make any sense to anyone. When they do, we can enable
+ * this test file.
+ * TODO: filter out driver dependent components from this common core
+ * test file.
+ */
+?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
+$db->exec('insert2', "INSERT INTO test VALUES(:first, :second, :third)");
+
+$data = array(
+ array('10', 'Abc', 'zxy'),
+ array('20', 'Def', 'wvu'),
+ array('30', 'Ghi', 'tsr'),
+ array('40', 'Jkl', 'qpo'),
+ array('50', 'Mno', 'nml'),
+ array('60', 'Pqr', 'kji'),
+);
+
+
+// Insert using question mark placeholders
+$stmt = $db->prepare("INSERT INTO test VALUES(?, ?, ?)");
+foreach ($data as $row) {
+ $stmt->execute($row);
+}
+
+// Retrieve column metadata for a result set returned by explicit SELECT
+$select = $db->query('SELECT id, val, val2 FROM test');
+$meta = $select->getColumnMeta(0);
+var_dump($meta);
+$meta = $select->getColumnMeta(1);
+var_dump($meta);
+$meta = $select->getColumnMeta(2);
+var_dump($meta);
+
+// Retrieve column metadata for a result set returned by a function
+$select = $db->query('SELECT COUNT(*) FROM test');
+$meta = $select->getColumnMeta(0);
+var_dump($meta);
+
+?>
+--EXPECT--
+The unexpected!
--- /dev/null
+--TEST--
+PDO Common: extending PDO
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver';
+?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+
+class PDOStatementX extends PDOStatement
+{
+ public $test1 = 1;
+
+ protected function __construct()
+ {
+ $this->test2 = 2;
+ $this->test2 = 22;
+ echo __METHOD__ . "()\n";
+ }
+
+ function __destruct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+class PDODatabaseX extends PDO
+{
+ public $test1 = 1;
+
+ function __destruct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+
+ function test()
+ {
+ $this->test2 = 2;
+ var_dump($this->test1);
+ var_dump($this->test2);
+ $this->test2 = 22;
+ }
+
+ function query($sql)
+ {
+ echo __METHOD__ . "()\n";
+ $stmt = parent::prepare($sql, array(PDO_ATTR_STATEMENT_CLASS=>array('PDOStatementx')));
+ $stmt->execute();
+ return $stmt;
+ }
+}
+
+$db = PDOTest::factory('PDODatabaseX');
+$db->test();
+var_dump($db);
+
+$db->query('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->query('INSERT INTO test VALUES(0, \'A\')');
+$db->query('INSERT INTO test VALUES(1, \'B\')');
+
+
+$stmt = $db->query('SELECT val, id FROM test');
+var_dump($stmt);
+var_dump($stmt->fetchAll(PDO_FETCH_COLUMN|PDO_FETCH_UNIQUE));
+
+$stmt = NULL;
+$db = NULL;
+
+
+?>
+--EXPECTF--
+int(1)
+int(2)
+object(PDODatabaseX)#%d (2) {
+ ["test1"]=>
+ int(1)
+ ["test2"]=>
+ int(22)
+}
+PDODatabaseX::query()
+PDOStatementX::__construct()
+PDOStatementX::__destruct()
+PDODatabaseX::query()
+PDOStatementX::__construct()
+PDOStatementX::__destruct()
+PDODatabaseX::query()
+PDOStatementX::__construct()
+PDOStatementX::__destruct()
+PDODatabaseX::query()
+PDOStatementX::__construct()
+object(PDOStatementX)#%d (3) {
+ ["test1"]=>
+ int(1)
+ ["queryString"]=>
+ string(24) "SELECT val, id FROM test"
+ ["test2"]=>
+ int(22)
+}
+array(2) {
+ ["A"]=>
+ string(1) "0"
+ ["B"]=>
+ string(1) "1"
+}
+PDOStatementX::__destruct()
+PDODatabaseX::__destruct()
--- /dev/null
+--TEST--
+PDO Common: assert that bindParam does not modify parameter
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver';
+?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('create table test (id int, name varchar(10))');
+
+$stmt = $db->prepare('insert into test (id, name) values(0, :name)');
+$name = NULL;
+$before_bind = $name;
+$stmt->bindParam(':name', $name);
+if ($name !== $before_bind) {
+ echo "bind: fail\n";
+} else {
+ echo "bind: success\n";
+}
+var_dump($stmt->execute());
+var_dump($db->query('select name from test where id=0')->fetchColumn());
+
+?>
+--EXPECT--
+bind: success
+bool(true)
+NULL
--- /dev/null
+--TEST--
+PDO Common: PDO_FETCH_INTO
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver';
+?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
+
+$data = array(
+ array('10', 'Abc', 'zxy'),
+ array('20', 'Def', 'wvu'),
+ array('30', 'Ghi', 'tsr'),
+ array('40', 'Jkl', 'qpo'),
+ array('50', 'Mno', 'nml'),
+ array('60', 'Pqr', 'kji'),
+);
+
+
+// Insert using question mark placeholders
+$stmt = $db->prepare("INSERT INTO test VALUES(?, ?, ?)");
+foreach ($data as $row) {
+ $stmt->execute($row);
+}
+
+class Test {
+ public $id, $val, $val2;
+}
+
+$stmt = $db->prepare('SELECT * FROM test');
+$stmt->setFetchMode(PDO_FETCH_INTO, new Test);
+$stmt->execute();
+
+foreach($stmt as $obj) {
+ var_dump($obj);
+}
+
+echo "===FAIL===\n";
+
+class Fail {
+ protected $id;
+ public $val, $val2;
+}
+
+$stmt->setFetchMode(PDO_FETCH_INTO, new Fail);
+$stmt->execute();
+
+foreach($stmt as $obj) {
+ var_dump($obj);
+}
+
+?>
+--EXPECTF--
+object(Test)#%d (3) {
+ ["id"]=>
+ string(2) "10"
+ ["val"]=>
+ string(3) "Abc"
+ ["val2"]=>
+ string(3) "zxy"
+}
+object(Test)#%d (3) {
+ ["id"]=>
+ string(2) "20"
+ ["val"]=>
+ string(3) "Def"
+ ["val2"]=>
+ string(3) "wvu"
+}
+object(Test)#%d (3) {
+ ["id"]=>
+ string(2) "30"
+ ["val"]=>
+ string(3) "Ghi"
+ ["val2"]=>
+ string(3) "tsr"
+}
+object(Test)#%d (3) {
+ ["id"]=>
+ string(2) "40"
+ ["val"]=>
+ string(3) "Jkl"
+ ["val2"]=>
+ string(3) "qpo"
+}
+object(Test)#%d (3) {
+ ["id"]=>
+ string(2) "50"
+ ["val"]=>
+ string(3) "Mno"
+ ["val2"]=>
+ string(3) "nml"
+}
+object(Test)#%d (3) {
+ ["id"]=>
+ string(2) "60"
+ ["val"]=>
+ string(3) "Pqr"
+ ["val2"]=>
+ string(3) "kji"
+}
+===FAIL===
+
+Fatal error: Cannot access protected property Fail::$id in %spdo_025.php on line %d
--- /dev/null
+--TEST--
+PDO Common: extending PDO (2)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) print 'skip';
+if (false == getenv('REDIR_TEST_DIR')) print 'skip no driver';
+?>
+--FILE--
+<?php
+require getenv('REDIR_TEST_DIR') . 'pdo_test.php';
+
+$data = array(
+ array('10', 'Abc', 'zxy'),
+ array('20', 'Def', 'wvu'),
+ array('30', 'Ghi', 'tsr'),
+);
+
+class PDOStatementX extends PDOStatement
+{
+ public $dbh;
+
+ protected function __construct($dbh)
+ {
+ $this->dbh = $dbh;
+ echo __METHOD__ . "()\n";
+ }
+
+ function __destruct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+class PDODatabase extends PDO
+{
+ function __destruct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+
+ function query($sql)
+ {
+ echo __METHOD__ . "()\n";
+ $stmt = $this->prepare($sql, array(PDO_ATTR_STATEMENT_CLASS=>array('PDOStatementx', array($this))));
+ $stmt->setFetchMode(PDO_FETCH_ASSOC);
+ $stmt->execute();
+ return $stmt;
+ }
+}
+
+$db = PDOTest::factory('PDODatabase');
+var_dump(get_class($db));
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
+
+$stmt = $db->prepare("INSERT INTO test VALUES(?, ?, ?)");
+var_dump(get_class($stmt));
+foreach ($data as $row) {
+ $stmt->execute($row);
+}
+
+$stmt = $db->query('SELECT * FROM test');
+var_dump(get_class($stmt));
+var_dump(get_class($stmt->dbh));
+
+foreach($stmt as $obj) {
+ var_dump($obj);
+}
+
+echo "===DONE===\n";
+?>
+--EXPECT--
+string(11) "PDODatabase"
+string(12) "PDOStatement"
+PDODatabase::query()
+PDOStatementX::__construct()
+string(13) "PDOStatementX"
+string(11) "PDODatabase"
+array(3) {
+ ["id"]=>
+ string(2) "10"
+ ["val"]=>
+ string(3) "Abc"
+ ["val2"]=>
+ string(3) "zxy"
+}
+array(3) {
+ ["id"]=>
+ string(2) "20"
+ ["val"]=>
+ string(3) "Def"
+ ["val2"]=>
+ string(3) "wvu"
+}
+array(3) {
+ ["id"]=>
+ string(2) "30"
+ ["val"]=>
+ string(3) "Ghi"
+ ["val2"]=>
+ string(3) "tsr"
+}
+===DONE===
+PDODatabase::__destruct()
+PDOStatementX::__destruct()