function try_buffer_size($offset, $buffer_size)
{
    try {
        $dsn = MySQLPDOTest::getDSN();
        $user = PDO_MYSQL_TEST_USER;
        $pass = PDO_MYSQL_TEST_PASS;
        /* unsigned overflow possible ? */
        $db = new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_MAX_BUFFER_SIZE => $buffer_size, PDO::MYSQL_ATTR_DIRECT_QUERY => 0, PDO::ATTR_EMULATE_PREPARES => 0));
        $db->exec('DROP TABLE IF EXISTS test');
        $db->exec(sprintf('CREATE TABLE test(id INT, val LONGBLOB) ENGINE = %s', PDO_MYSQL_TEST_ENGINE));
        // 10 * (10 * 1024) = 10 * (10 * 1k) = 100k
        $db->exec('INSERT INTO test(id, val) VALUES (1, REPEAT("01234567890", 10240))');
        $stmt = $db->prepare('SELECT id, val FROM test');
        $stmt->execute();
        $id = $val = NULL;
        $stmt->bindColumn(1, $id);
        $stmt->bindColumn(2, $val);
        while ($row = $stmt->fetch(PDO::FETCH_BOUND)) {
            printf("[%03d] id = %d, val = %s... (length: %d)\n", $offset, $id, substr($val, 0, 10), strlen($val));
        }
        $db->exec('DROP TABLE IF EXISTS test');
    } catch (PDOException $e) {
        printf("[%03d] %s, [%s] %s\n", $offset, $e->getMessage(), is_object($db) ? $db->errorCode() : 'n/a', is_object($db) ? implode(' ', $db->errorInfo()) : 'n/a');
    }
}
Example #2
0
function test_type(&$db, $offset, $sql_type, $value, $ret_value = NULL, $pattern = NULL, $alternative_type = NULL)
{
    $db->exec('DROP TABLE IF EXISTS test');
    $sql = sprintf('CREATE TABLE test(id INT, label %s) ENGINE=%s', $sql_type, MySQLPDOTest::getTableEngine());
    @$db->exec($sql);
    if ($db->errorCode() != 0) {
        // not all MySQL Server versions and/or engines might support the type
        return true;
    }
    $stmt = $db->prepare('INSERT INTO test(id, label) VALUES (?, ?)');
    $stmt->bindValue(1, $offset);
    $stmt->bindValue(2, $value);
    if (!$stmt->execute()) {
        printf("[%03d + 1] INSERT failed, %s\n", $offset, var_export($stmt->errorInfo(), true));
        return false;
    }
    $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
    $stmt = $db->query('SELECT  id, label FROM test');
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    $stmt->closeCursor();
    if (!isset($row['id']) || !isset($row['label'])) {
        printf("[%03d + 2] Fetched result seems wrong, dumping result: %s\n", $offset, var_export($row, true));
        return false;
    }
    if ($row['id'] != $offset) {
        printf("[%03d + 3] Expecting %s got %s\n", $offset, $row['id']);
        return false;
    }
    if (!is_null($pattern)) {
        if (!preg_match($pattern, $row['label'])) {
            printf("[%03d + 5] Value seems wrong, accepting pattern %s got %s, check manually\n", $offset, $pattern, var_export($row['label'], true));
            return false;
        }
    } else {
        $exp = $value;
        if (!is_null($ret_value)) {
            // we expect a different return value than our input value
            // typically the difference is only the type
            $exp = $ret_value;
        }
        if ($row['label'] !== $exp && !is_null($alternative_type) && gettype($row['label']) != $alternative_type) {
            printf("[%03d + 4] %s - input = %s/%s, output = %s/%s (alternative type: %s)\n", $offset, $sql_type, var_export($exp, true), gettype($exp), var_export($row['label'], true), gettype($row['label']), $alternative_type);
            return false;
        }
    }
    $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
    $stmt = $db->query('SELECT id, label FROM test');
    $row_string = $stmt->fetch(PDO::FETCH_ASSOC);
    $stmt->closeCursor();
    if (is_null($pattern) && $row['label'] != $row_string['label']) {
        printf("%s - STRINGIGY = %s, NATIVE = %s\n", $sql_type, var_export($row_string['label'], true), var_export($row['label'], true));
        return false;
    } else {
        if (!is_null($pattern) && !preg_match($pattern, $row_string['label'])) {
            printf("%s - STRINGIGY = %s, NATIVE = %s, pattern '%s'\n", $sql_type, var_export($row_string['label'], true), var_export($row['label'], true), $pattern);
            return false;
        }
    }
    return true;
}
function pdo_mysql_stmt_bindparam_types_do($db, $offset, $native, $sql_type, $value)
{
    if ($native) {
        $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
    } else {
        $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1);
    }
    $db->exec('DROP TABLE IF EXISTS test');
    $sql = sprintf('CREATE TABLE test(id INT, label %s) ENGINE=%s', $sql_type, MySQLPDOTest::getTableEngine());
    if (!($stmt = @$db->prepare($sql)) || !@$stmt->execute()) {
        // Server might not support column type - skip it
        return true;
    }
    $stmt = $db->prepare('INSERT INTO test(id, label) VALUES (1, ?)');
    if (!$stmt->bindParam(1, $value)) {
        printf("[%03d/%s + 1] %s\n", $offset, $native ? 'native' : 'emulated', var_export($stmt->errorInfo(), true));
        return false;
    }
    if (!$stmt->execute()) {
        printf("[%03d/%s + 2] %s\n", $offset, $native ? 'native' : 'emulated', var_export($stmt->errorInfo(), true));
        return false;
    }
    $stmt = $db->query('SELECT id, label FROM test');
    $id = $label = null;
    if (!$stmt->bindColumn(1, $id)) {
        printf("[%03d/%s + 3] %s\n", $offset, $native ? 'native' : 'emulated', var_export($stmt->errorInfo(), true));
        return false;
    }
    if (!$stmt->bindColumn(2, $label)) {
        printf("[%03d/%s + 4] %s\n", $offset, $native ? 'native' : 'emulated', var_export($stmt->errorInfo(), true));
        return false;
    }
    if (!$stmt->fetch(PDO::FETCH_BOUND)) {
        printf("[%03d/%s + 5] %s\n", $offset, $native ? 'native' : 'emulated', var_export($stmt->errorInfo(), true));
        return false;
    }
    $stmt->closeCursor();
    if ($label != $value) {
        printf("[%03d/%s + 6] Got %s expecting %s - plase check manually\n", $offset, $native ? 'native' : 'emulated', var_export($label, true), var_export($value, true));
        // fall through
    }
    $stmt->execute();
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    if (empty($row)) {
        printf("[%03d/%s + 7] %s\n", $offset, $native ? 'native' : 'emulated', var_export($stmt->errorInfo(), true));
        return false;
    }
    if ($row['label'] != $value) {
        printf("[%03d/%s + 8] Got %s expecting %s - plase check manually\n", $offset, $native ? 'native' : 'emulated', var_export($row['label'], true), var_export($value, true));
        return false;
    }
    if ($row['label'] != $label) {
        printf("[%03d/%s + 9] Got %s from FETCH_ASSOC and %s from FETCH_BOUND- plase check manually\n", $offset, $native ? 'native' : 'emulated', var_export($row['label'], true), var_export($value, true));
        return false;
    }
    $db->exec('DROP TABLE IF EXISTS test');
    return true;
}
 function test_meta(&$db, $offset, $sql_type, $value, $native_type, $pdo_type)
 {
     $db->exec('DROP TABLE IF EXISTS test');
     $sql = sprintf('CREATE TABLE test(id INT, label %s) ENGINE=%s', $sql_type, MySQLPDOTest::getTableEngine());
     if (!($stmt = @$db->prepare($sql)) || !@$stmt->execute()) {
         // Some engines and/or MySQL server versions might not support the data type
         return true;
     }
     if (!$db->exec(sprintf("INSERT INTO test(id, label) VALUES (1, '%s')", $value))) {
         printf("[%03d] + 1] Insert failed, %d - %s\n", $offset, $db->errorCode(), var_export($db->errorInfo(), true));
         return false;
     }
     $stmt = $db->prepare('SELECT id, label FROM test');
     $stmt->execute();
     $meta = $stmt->getColumnMeta(1);
     $row = $stmt->fetch(PDO::FETCH_ASSOC);
     if (empty($meta)) {
         printf("[%03d + 2] getColumnMeta() failed, %d - %s\n", $offset, $stmt->errorCode(), var_export($stmt->errorInfo(), true));
         return false;
     }
     $elements = array('flags', 'table', 'name', 'len', 'precision', 'pdo_type');
     foreach ($elements as $k => $element) {
         if (!isset($meta[$element])) {
             printf("[%03d + 3] Element %s missing, %s\n", $offset, $element, var_export($meta, true));
             return false;
         }
     }
     if ($meta['table'] != 'test' || $meta['name'] != 'label') {
         printf("[%03d + 4] Table or field name is wrong, %s\n", $offset, var_export($meta, true));
         return false;
     }
     if (!is_null($native_type)) {
         if (!isset($meta['native_type'])) {
             printf("[%03d + 5] Element native_type missing, %s\n", $offset, var_export($meta, true));
             return false;
         }
         if (!is_array($native_type)) {
             $native_type = array($native_type);
         }
         $found = false;
         foreach ($native_type as $k => $type) {
             if ($meta['native_type'] == $type) {
                 $found = true;
                 break;
             }
         }
         if (!$found) {
             printf("[%03d + 6] Expecting native type %s, %s\n", $offset, var_export($native_type, true), var_export($meta, true));
             return false;
         }
     }
     if (!is_null($pdo_type) && $meta['pdo_type'] != $pdo_type) {
         printf("[%03d + 6] Expecting PDO type %s got %s (%s)\n", $offset, $pdo_type, var_export($meta, true), var_export($meta['native_type']));
         return false;
     }
     return true;
 }
function set_option_and_check($offset, $option, $value, $option_desc, $ignore_diff = false)
{
    $dsn = MySQLPDOTest::getDSN();
    $user = PDO_MYSQL_TEST_USER;
    $pass = PDO_MYSQL_TEST_PASS;
    try {
        $db = new PDO($dsn, $user, $pass, array($option => $value));
        if (!is_object($db) || !$ignore_diff && $value !== ($tmp = @$db->getAttribute($option))) {
            printf("[%03d] Execting '%s'/%s got '%s'/%s' for options '%s'\n", $offset, $value, gettype($value), $tmp, gettype($tmp), $option_desc);
        }
    } catch (PDOException $e) {
        printf("[%03d] %s\n", $offset, $e->getMessage());
    }
}
Example #6
0
function pdo_mysql_errorinfo($db, $offset)
{
    try {
        /*
        If you create a PDOStatement object through PDO->prepare()
        or PDO->query() and invoke an error on the statement handle,
        PDO->errorCode() will not reflect that error. You must call
        PDOStatement->errorCode() to return the error code for an
        operation performed on a particular statement handle.
        */
        $code = $db->errorCode();
        check_error($offset + 2, $db);
        $stmt = $db->query('SELECT id, label FROM test');
        $stmt2 =& $stmt;
        check_error($offset + 3, $db);
        check_error($offset + 4, $stmt);
        $db->exec('DROP TABLE IF EXISTS test');
        @$stmt->execute();
        check_error($offset + 5, $db);
        check_error($offset + 6, $stmt, '42S02');
        check_error($offset + 7, $stmt2, '42S02');
        @($stmt = $db->query('SELECT id, label FROM unknown'));
        check_error($offset + 8, $db, '42S02');
        MySQLPDOTest::createTestTable($db);
        $stmt = $db->query('SELECT id, label FROM test');
        check_error($offset + 9, $db);
        check_error($offset + 10, $stmt);
        $db2 =& $db;
        $db->exec('DROP TABLE IF EXISTS unknown');
        @$db->query('SELECT id, label FROM unknown');
        check_error($offset + 11, $db, '42S02');
        check_error($offset + 12, $db2, '42S02');
        check_error($offset + 13, $stmt);
        check_error($offset + 14, $stmt2);
        // lets hope this is an invalid attribute code
        $invalid_attr = -1 * PHP_INT_MAX + 3;
        $tmp = @$db->getAttribute($invalid_attr);
        check_error($offset + 15, $db, 'IM001');
        check_error($offset + 16, $db2, 'IM001');
        check_error($offset + 17, $stmt);
        check_error($offset + 18, $stmt2);
    } catch (PDOException $e) {
        printf("[%03d] %s [%s] %s\n", $offset + 19, $e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
    }
}
Example #7
0
function test_type(&$db, $offset, $sql_type, $value, $ret_value = NULL, $pattern = NULL)
{
    $db->exec('DROP TABLE IF EXISTS test');
    $sql = sprintf('CREATE TABLE test(id INT, label %s) ENGINE=%s', $sql_type, MySQLPDOTest::getTableEngine());
    @$db->exec($sql);
    if ($db->errorCode() != 0) {
        // not all MySQL Server versions and/or engines might support the type
        return true;
    }
    $stmt = $db->prepare('INSERT INTO test(id, label) VALUES (?, ?)');
    $stmt->bindValue(1, $offset);
    $stmt->bindValue(2, $value);
    if (!$stmt->execute()) {
        printf("[%03d + 1] INSERT failed, %s\n", $offset, var_export($stmt->errorInfo(), true));
        return false;
    }
    $stmt = $db->query('SELECT  id, label FROM test');
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    var_dump($row);
    var_dump($value);
    return true;
}
<?php

require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
/* Connect to mysql to determine the current charset so we can diffinate it */
$link = MySQLPDOTest::factory();
$charset = $link->query("SHOW VARIABLES LIKE 'character_set_connection'")->fetchObject()->value;
/* Make sure that we don't attempt to set the current character set to make this case useful */
$new_charset = $charset == 'latin1' ? 'ascii' : 'latin1';
/* Done with the original connection, create a second link to test the character set being defined */
unset($link);
$link = MySQLPDOTest::factory('PDO', false, null, array('charset' => $new_charset));
$conn_charset = $link->query("SHOW VARIABLES LIKE 'character_set_connection'")->fetchObject()->value;
if ($charset !== $conn_charset) {
    echo "done!\n";
} else {
    echo "failed!\n";
}
	set_and_get(6, $db, PDO::MYSQL_ATTR_LOCAL_INFILE, 0);
	set_and_get(7, $db, PDO::MYSQL_ATTR_LOCAL_INFILE, -1);
	$tmp = array();
	set_and_get(8, $db, PDO::MYSQL_ATTR_LOCAL_INFILE, $tmp);
	set_and_get(9, $db, PPDO::MYSQL_ATTR_INIT_COMMAND, '');
	set_and_get(10, $db, PPDO::MYSQL_ATTR_INIT_COMMAND, 'SOME SQL');
	set_and_get(11, $db, PPDO::MYSQL_ATTR_INIT_COMMAND, -1);
*/
/*
PDO::MYSQL_ATTR_READ_DEFAULT_FILE (integer)

    Read options from the named option file instead of from my.cnf.
PDO::MYSQL_ATTR_READ_DEFAULT_GROUP (integer)

    Read options from the named group from my.cnf or the file specified with MYSQL_READ_DEFAULT_FILE.
PDO::MYSQL_ATTR_MAX_BUFFER_SIZE (integer)

    Maximum buffer size. Defaults to 1 MiB.
PDO::MYSQL_ATTR_DIRECT_QUERY (integer)

    Perform direct queries, don't use prepared statements.
*/
/*
TODO - read only
PDO::ATTR_CONNECTION_STATUS
PDO::ATTR_SERVER_INFO
*/
print "done!";
require dirname(__FILE__) . '/mysql_pdo_test.inc';
MySQLPDOTest::dropTestTable();
<?php

require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
$db = MySQLPDOTest::factory();
MySQLPDOTest::createTestTable($db);
printf("Testing native PS...\n");
try {
    $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
    if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) {
        printf("[002] Unable to turn off emulated prepared statements\n");
    }
    printf("Binding variable...\n");
    $stmt = $db->prepare('SELECT id, label FROM test WHERE id > ? ORDER BY id ASC LIMIT 2');
    $in = 0;
    if (!$stmt->bindValue(1, $in)) {
        printf("[003] Cannot bind value, %s %s\n", $stmt->errorCode(), var_export($stmt->errorInfo(), true));
    }
    $stmt->execute();
    $id = $label = null;
    if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT)) {
        printf("[004] Cannot bind integer column, %s %s\n", $stmt->errorCode(), var_export($stmt->errorInfo(), true));
    }
    if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR)) {
        printf("[005] Cannot bind string column, %s %s\n", $stmt->errorCode(), var_export($stmt->errorInfo(), true));
    }
    while ($stmt->fetch(PDO::FETCH_BOUND)) {
        printf("in = %d -> id = %s (%s) / label = %s (%s)\n", $in, var_export($id, true), gettype($id), var_export($label, true), gettype($label));
    }
    printf("Binding value and not variable...\n");
    if (!$stmt->bindValue(1, 0)) {
        printf("[006] Cannot bind value, %s %s\n", $stmt->errorCode(), var_export($stmt->errorInfo(), true));
     if (count(($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC))) != 2)
     	printf("[074] Expecting two rows, got %d rows\n", $tmp);
     */
 }
 prepex(57, $db, 'DELETE FROM test');
 prepex(58, $db, 'INSERT INTO test(id, label) VALUES (1, ?), (2, ?)', array('row1', 'row2'));
 /*
 TODO enable after fix
 $stmt = prepex(37, $db, 'SELECT id, label FROM \'test WHERE MATCH label AGAINST (:placeholder)',
 	array(':placeholder' => 'row'),
 	array('execute' => array('sqlstate' => '42000', 'mysql' => 1064)));
 */
 $stmt = prepex(59, $db, 'SELECT id, label AS "label" FROM test WHERE label = ?', array('row1'));
 $tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
 $exp = array(0 => array("id" => "1", "label" => "row1"));
 if (MySQLPDOTest::isPDOMySQLnd()) {
     // mysqlnd returns native types
     $exp[0]['id'] = 1;
 }
 if ($tmp !== $exp) {
     printf("[065] Results seem wrong. Please check dumps manually.\n");
     var_dump($exp);
     var_dump($tmp);
 }
 $sql = sprintf("SELECT id, label FROM test WHERE (label LIKE %s) AND (id = ?)", $db->quote('%ro%'));
 $stmt = prepex(60, $db, $sql, array(-1));
 if (count($tmp = $stmt->fetchAll(PDO::FETCH_ASSOC)) != 0) {
     printf("[061] Expecting zero rows, got %d rows\n", $tmp);
 }
 $sql = sprintf("SELECT id, label FROM test WHERE  (id = ?) OR (label LIKE %s)", $db->quote('%ro%'));
 $stmt = prepex(61, $db, $sql, array(1));
if (!$db->query('SET autocommit = 0')) {
    printf("[007] Cannot turn off server autocommit mode, %s\n", var_export($db->errorInfo(), true));
}
if (!$db->setAttribute(PDO::ATTR_AUTOCOMMIT, 1)) {
    printf("[008] Cannot turn on autocommit\n");
}
$row = $db->query('SELECT @@autocommit AS _autocommit')->fetch(PDO::FETCH_ASSOC);
if (!$row['_autocommit']) {
    printf("[009] Server autocommit mode should be on, got '%s'\n", var_export($row['_autocommit']));
}
if (1 !== ($tmp = $db->getAttribute(PDO::ATTR_AUTOCOMMIT))) {
    printf("[010] Expecting int/1 got %s\n", var_export($tmp, true));
}
if (MySQLPDOTest::detect_transactional_mysql_engine($db)) {
    // nice, we have a transactional engine to play with
    MySQLPDOTest::createTestTable($db, MySQLPDOTest::detect_transactional_mysql_engine($db));
    $row = $db->query('SELECT COUNT(*) AS _num FROM test')->fetch(PDO::FETCH_ASSOC);
    $num = $row['_num'];
    $db->query("INSERT INTO test(id, label) VALUES (100, 'z')");
    $num++;
    $row = $db->query('SELECT COUNT(*) AS _num FROM test')->fetch(PDO::FETCH_ASSOC);
    if ($row['_num'] != $num) {
        printf("[011] Insert has failed, test will fail\n");
    }
    // autocommit is on, no rollback possible
    $db->query('ROLLBACK');
    $row = $db->query('SELECT COUNT(*) AS _num FROM test')->fetch(PDO::FETCH_ASSOC);
    if ($row['_num'] != $num) {
        printf("[012] ROLLBACK should not have undone anything\n");
    }
    if (!$db->setAttribute(PDO::ATTR_AUTOCOMMIT, 0)) {
function pdo_mysql_stmt_closecursor($db)
{
    // This one should fail. I let it fail to prove that closeCursor() makes a difference.
    // If no error messages gets printed do not know if proper usage of closeCursor() makes any
    // difference or not. That's why we need to cause an error here.
    $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
    $stmt1 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
    // query() shall fail!
    $stmt2 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
    $stmt1->closeCursor();
    // This is proper usage of closeCursor(). It shall prevent any further error messages.
    if (MySQLPDOTest::isPDOMySQLnd()) {
        $stmt1 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
    } else {
        // see pdo_mysql_stmt_unbuffered_2050.phpt for an explanation
        unset($stmt1);
        $stmt1 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
    }
    // fetch only the first rows and let closeCursor() clean up
    $row1 = $stmt1->fetch(PDO::FETCH_ASSOC);
    $stmt1->closeCursor();
    $stmt2 = $db->prepare('UPDATE test SET label = ? WHERE id = ?');
    $stmt2->bindValue(1, "z");
    $stmt2->bindValue(2, $row1['id']);
    $stmt2->execute();
    $stmt2->closeCursor();
    $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
    // check if changing the fetch mode from unbuffered to buffered will
    // cause any harm to a statement created prior to the change
    $stmt1->execute();
    $row2 = $stmt1->fetch(PDO::FETCH_ASSOC);
    $stmt1->closeCursor();
    if (!isset($row2['label']) || 'z' !== $row2['label']) {
        printf("Expecting array(id => 1, label => z) got %s\n", var_export($row2, true));
    }
    unset($stmt1);
    $stmt1 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
    // should work
    $stmt2 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
    $stmt1->closeCursor();
    $stmt1 = $db->query('SELECT id, label FROM test ORDER BY id ASC');
    // fetch only the first rows and let closeCursor() clean up
    $row3 = $stmt1->fetch(PDO::FETCH_ASSOC);
    $stmt1->closeCursor();
    assert($row3 == $row2);
    $stmt2 = $db->prepare('UPDATE test SET label = ? WHERE id = ?');
    $stmt2->bindValue(1, "a");
    $stmt2->bindValue(2, $row1['id']);
    $stmt2->execute();
    $stmt2->closeCursor();
    $stmt1->execute();
    $row4 = $stmt1->fetch(PDO::FETCH_ASSOC);
    $stmt1->closeCursor();
    assert($row4 == $row1);
    $offset = 0;
    $stmt = $db->prepare('SELECT id, label FROM test WHERE id > ? ORDER BY id ASC LIMIT 2');
    $in = 0;
    if (!$stmt->bindParam(1, $in)) {
        printf("[%03d + 1] Cannot bind parameter, %s %s\n", $offset, $stmt->errorCode(), var_export($stmt->errorInfo(), true));
    }
    $stmt->execute();
    $id = $label = null;
    if (!$stmt->bindColumn(1, $id, PDO::PARAM_INT)) {
        printf("[%03d + 2] Cannot bind integer column, %s %s\n", $offset, $stmt->errorCode(), var_export($stmt->errorInfo(), true));
    }
    if (!$stmt->bindColumn(2, $label, PDO::PARAM_STR)) {
        printf("[%03d + 3] Cannot bind string column, %s %s\n", $offset, $stmt->errorCode(), var_export($stmt->errorInfo(), true));
    }
    while ($stmt->fetch(PDO::FETCH_BOUND)) {
        printf("in = %d -> id = %s (%s) / label = %s (%s)\n", $in, var_export($id, true), gettype($id), var_export($label, true), gettype($label));
    }
    $stmt->closeCursor();
    $stmt->execute();
}
     public function serialize()
     {
         printf("%s()\n", __METHOD__);
         return 'Data from serialize';
     }
     public function unserialize($data)
     {
         printf("%s(%s)\n", __METHOD__, var_export($data, true));
     }
 }
 $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0);
 if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) {
     printf("[002] Unable to turn off emulated prepared statements\n");
 }
 $db->exec('DROP TABLE IF EXISTS test');
 $db->exec(sprintf('CREATE TABLE test(id INT, myobj BLOB) ENGINE=%s', MySQLPDOTest::getTableEngine()));
 printf("Creating an object, serializing it and writing it to DB...\n");
 $id = 1;
 $obj = myclass::singleton('Creating object');
 $myobj = serialize($obj);
 $stmt = $db->prepare('INSERT INTO test(id, myobj) VALUES (?, ?)');
 $stmt->bindValue(1, $id);
 $stmt->bindValue(2, $myobj);
 $stmt->execute();
 printf("\nUnserializing the previously serialized object...\n");
 var_dump(unserialize($myobj));
 printf("\nUsing PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE to fetch the object from DB and unserialize it...\n");
 $stmt = $db->prepare('SELECT myobj FROM test');
 $stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_SERIALIZE, 'myclass', array('PDO shall not call __construct()'));
 $stmt->execute();
 var_dump($stmt->fetch());
Example #15
0
<?php

if (getenv('REDIR_TEST_DIR') === false) {
    putenv('REDIR_TEST_DIR=' . dirname(__FILE__) . '/../../pdo/tests/');
}
require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
$db = PDOTest::factory();
if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
    require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
    $suf = ' ENGINE=' . MySQLPDOTest::detect_transactional_mysql_engine($db);
} else {
    $suf = '';
}
$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10))' . $suf);
$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();
if (1 === $db->getAttribute(PDO::ATTR_AUTOCOMMIT)) {
    printf("[028] I'm confused, how can autocommit be on? Didn't I say I want to manually control transactions?\n");
}
if (!$db->beginTransaction()) {
    printf("[029] Cannot start a transaction, [%d] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
}
try {
    if (false !== $db->beginTransaction()) {
        printf("[030] No false and no exception - that's wrong.\n");
    }
} catch (PDOException $e) {
    assert($e->getMessage() != '');
}
// TODO: What about an engine that does not support transactions?
$db = MySQLPDOTest::factory();
MySQLPDOTest::createTestTable($db, 'MyISAM');
if (false == $db->beginTransaction()) {
    printf("[031] Cannot start a transaction, [%s] [%s]\n", $db->errorCode(), implode(' ', $db->errorInfo()));
}
if (1 !== $db->getAttribute(PDO::ATTR_AUTOCOMMIT)) {
    printf("[032] Autocommit should be on my default, beginTransaction() should not change that\n");
}
if (0 == $db->exec('DELETE FROM test')) {
    printf("[033] No rows deleted, can't be true.\n");
}
if (!$db->commit()) {
    printf("[034] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
}
if (false == $db->beginTransaction()) {
    printf("[035] Cannot start a transaction, [%s] [%s]\n", $db->errorCode(), implode(' ', $db->errorInfo()));
}
<?php

require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
$found = false;
$values = ini_get_all();
foreach ($values as $name => $dsn) {
    if ('pdo.dsn.mysql' == $name) {
        printf("pdo.dsn.mysql=%s\n", $dsn);
        $found = true;
        break;
    }
}
if (!$found) {
    $dsn = ini_get('pdo.dsn.mysql');
    $found = $dsn !== false;
}
if (!$found) {
    printf("pdo.dsn.mysql cannot be accessed through ini_get_all()/ini_get()\n");
}
if (MySQLPDOTest::getDSN() == $dsn) {
    // we are lucky, we can run the test
    try {
        $user = PDO_MYSQL_TEST_USER;
        $pass = PDO_MYSQL_TEST_PASS;
        $db = new PDO('mysql', $user, $pass);
    } catch (PDOException $e) {
        printf("[001] %s, [%s] %s\n", $e->getMessage(), is_object($db) ? $db->errorCode() : 'n/a', is_object($db) ? implode(' ', $db->errorInfo()) : 'n/a');
    }
}
print "done!";
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
$expected = array('MYSQL_ATTR_USE_BUFFERED_QUERY' => true, 'MYSQL_ATTR_LOCAL_INFILE' => true, 'MYSQL_ATTR_DIRECT_QUERY' => true, 'MYSQL_ATTR_FOUND_ROWS' => true, 'MYSQL_ATTR_IGNORE_SPACE' => true, 'MYSQL_ATTR_INIT_COMMAND' => true, "MYSQL_ATTR_SSL_KEY" => true, "MYSQL_ATTR_SSL_CERT" => true, "MYSQL_ATTR_SSL_CA" => true, "MYSQL_ATTR_SSL_CAPATH" => true, "MYSQL_ATTR_SSL_CIPHER" => true, "MYSQL_ATTR_COMPRESS" => true);
if (!MySQLPDOTest::isPDOMySQLnd()) {
    $expected['MYSQL_ATTR_MAX_BUFFER_SIZE'] = true;
    $expected['MYSQL_ATTR_READ_DEFAULT_FILE'] = true;
    $expected['MYSQL_ATTR_READ_DEFAULT_GROUP'] = true;
}
if (extension_loaded('mysqlnd')) {
    $expected['MYSQL_ATTR_SERVER_PUBLIC_KEY'] = true;
} else {
    if (extension_loaded('mysqli')) {
        if (mysqli_get_client_version() > 50605) {
            $expected['MYSQL_ATTR_SERVER_PUBLIC_KEY'] = true;
        }
    } else {
        if (MySQLPDOTest::getClientVersion(MySQLPDOTest::factory()) > 50605) {
            /* XXX the MySQL client library version isn't exposed with any 
            		constants, the single possibility is to use the PDO::getAttribute().
            		This however will fail with no connection. */
            $expected['MYSQL_ATTR_SERVER_PUBLIC_KEY'] = true;
        }
    }
}
/*
TODO

	MYSQLI_OPT_CONNECT_TIMEOUT != PDO::ATTR_TIMEOUT  (integer)
    Sets the timeout value in seconds for communications with the database.
	^  Potential BUG, PDO::ATTR_TIMEOUT is used in pdo_mysql_handle_factory

	MYSQLI_SET_CHARSET_NAME -> DSN/charset=<charset_name>
<?php

require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
$pdo = MySQLPDOTest::factory();
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$attrs = array(PDO::ATTR_EMULATE_PREPARES => array(null, 1, 0), PDO::MYSQL_ATTR_DIRECT_QUERY => array(null, 0, 1), PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => array(null, 0, 1), PDO::ATTR_AUTOCOMMIT => array(null), PDO::ATTR_PREFETCH => array(null), PDO::ATTR_TIMEOUT => array(null), PDO::ATTR_ERRMODE => array(null), PDO::ATTR_SERVER_VERSION => array(null), PDO::ATTR_CLIENT_VERSION => array(null), PDO::ATTR_SERVER_INFO => array(null), PDO::ATTR_CONNECTION_STATUS => array(null), PDO::ATTR_CASE => array(null), PDO::ATTR_CURSOR_NAME => array(null), PDO::ATTR_CURSOR => array(null), PDO::ATTR_ORACLE_NULLS => array(null), PDO::ATTR_PERSISTENT => array(null), PDO::ATTR_STATEMENT_CLASS => array(null), PDO::ATTR_FETCH_TABLE_NAMES => array(null), PDO::ATTR_FETCH_CATALOG_NAMES => array(null), PDO::ATTR_DRIVER_NAME => array(null), PDO::ATTR_STRINGIFY_FETCHES => array(null), PDO::ATTR_MAX_COLUMN_LEN => array(null), PDO::ATTR_DEFAULT_FETCH_MODE => array(null));
foreach ($attrs as $a => $vals) {
    foreach ($vals as $v) {
        try {
            if (!isset($v)) {
                var_dump($pdo->getAttribute($a));
            } else {
                $pdo->setAttribute($a, $v);
                if ($pdo->getAttribute($a) === $v) {
                    echo "OK\n";
                } else {
                    throw new \Exception('KO');
                }
            }
        } catch (\Exception $e) {
            if ($e->getCode() == 'IM001') {
                echo "ERR\n";
            } else {
                echo "ERR {$e->getMessage()}\n";
            }
        }
    }
}
    }
    $stmt2 = $db->query('SELECT id, label FROM test WHERE id = 1');
    $row = $stmt2->fetch(PDO::FETCH_ASSOC);
    if ($row['label'] != $blob) {
        printf("[%03d + 10] INSERT and/or SELECT has failed, dumping data.\n", $offset);
        var_dump($row);
        var_dump($blob);
        return false;
    }
    return true;
}
$db = MySQLPDOTest::factory();
$blob = 'I am a mighty BLOB!' . chr(0) . "I am a binary thingie!";
$tmp = MySQLPDOTest::getTempDir();
$file = $tmp . DIRECTORY_SEPARATOR . 'pdoblob.tst';
try {
    printf("Emulated PS...\n");
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
    blob_from_stream(10, $db, $file, $blob);
    printf("Native PS...\n");
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
    blob_from_stream(30, $db, $file, $blob);
} catch (PDOException $e) {
    printf("[001] %s [%s] %s\n", $e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
}
print "done!";
require dirname(__FILE__) . '/mysql_pdo_test.inc';
$db = MySQLPDOTest::factory();
$db->exec('DROP TABLE IF EXISTS test');
@unlink(MySQLPDOTest::getTempDir() . DIRECTORY_SEPARATOR . 'pdoblob.tst');
Example #21
0
    if (!isset($rows[0]['label']) || $rows[0]['label'] != 'z') {
        printf("[006] Record data is strange, dumping rows\n");
        var_dump($rows);
    }
    // Ok, lets check MyISAM resp. any other non-transactional engine
    // pdo_mysql_begin_transaction has more on this, quick check only
    $db = MySQLPDOTest::factory();
    MySQLPDOTest::createTestTable($db, 'MyISAM');
    if (true !== ($tmp = $db->beginTransaction())) {
        printf("[007] Expecting true, got %s/%s\n", gettype($tmp), $tmp);
    }
    $db->exec("INSERT INTO test(id, label) VALUES (100, 'z')");
    if (true !== ($tmp = $db->commit())) {
        printf("[008] No commit allowed? [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
    }
    // a weak test without unicode etc. - lets leave that to dedicated tests
    $stmt = $db->query('SELECT id, label FROM test WHERE id = 100');
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    if (!isset($rows[0]['label']) || $rows[0]['label'] != 'z') {
        printf("[009] Record data is strange, dumping rows\n");
        var_dump($rows);
    }
} catch (PDOException $e) {
    printf("[002] %s, [%s] %s\n", $e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
}
print "done!";
require dirname(__FILE__) . '/mysql_pdo_test.inc';
$db = MySQLPDOTest::factory();
$db->exec('DROP TABLE IF EXISTS test_commit');
MySQLPDOTest::dropTestTable($db);
    exec_and_count(11, $db, "REPLACE INTO test(id, col1) VALUES (6, 'g')", 1);
    exec_and_count(12, $db, 'DELETE FROM test WHERE id > 2', 4);
    exec_and_count(13, $db, 'DROP TABLE test', 0);
    exec_and_count(14, $db, 'SET @myvar = 1', 0);
    exec_and_count(15, $db, 'THIS IS NOT VALID SQL, I HOPE', false);
    printf("[016] [%s] %s\n", $db->errorCode(), implode(' ', $db->errorInfo()));
    exec_and_count(36, $db, sprintf('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, col1 CHAR(10)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE), 0);
    exec_and_count(37, $db, "INSERT INTO test(id, col1) VALUES (1, 'a')", 1);
    // Results may vary. Typically you will get 1. But the MySQL 5.1 manual states: Truncation operations do not return the number of deleted rows.
    // Don't rely on any return value!
    exec_and_count(38, $db, 'TRUNCATE TABLE test', NULL);
} catch (PDOException $e) {
    printf("[001] %s, [%s] %s\n", $e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
}
/* CREATE, DROP, CALL SP and SF */
if (MySQLPDOTest::getServerVersion($db) > 50000) {
    // let's try to play with stored procedures
    try {
        $ignore_exception = true;
        exec_and_count(18, $db, 'DROP PROCEDURE IF EXISTS p', 0);
        exec_and_count(19, $db, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(255)) BEGIN SELECT VERSION() INTO ver_param; END;', 0);
        // we got this far without problems. If there's an issue from now on, its a failure
        $ignore_exception = false;
        exec_and_count(20, $db, 'CALL p(@version)', 0);
        $stmt = $db->query('SELECT @version AS p_version');
        $tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
        if (count($tmp) > 1 || !isset($tmp[0]['p_version'])) {
            printf("[022] Data seems wrong, dumping\n");
            var_dump($tmp);
        } else {
            $p_version = $tmp[0]['p_version'];
    }
    return true;
}
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
putenv('PDOTEST_ATTR=' . serialize([PDO::MYSQL_ATTR_LOCAL_INFILE => true]));
$db = MySQLPDOTest::factory();
MySQLPDOTest::createTestTable($db, MySQLPDOTest::detect_transactional_mysql_engine($db));
/* affected rows related */
try {
    exec_and_count(2, $db, 'DROP TABLE IF EXISTS test', 0);
    exec_and_count(3, $db, sprintf('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, col1 CHAR(10)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE), 0);
    $stmt = $db->query("SHOW VARIABLES LIKE 'secure_file_priv'");
    if (($row = $stmt->fetch(PDO::FETCH_ASSOC)) && $row['value'] != '') {
        $filename = $row['value'] . DIRECTORY_SEPARATOR . "pdo_mysql_exec_load_data.csv";
    } else {
        $filename = MySQLPDOTest::getTempDir() . DIRECTORY_SEPARATOR . "pdo_mysql_exec_load_data.csv";
    }
    $fp = fopen($filename, "w");
    fwrite($fp, "1;foo\n");
    fwrite($fp, "2;bar");
    fclose($fp);
    $sql = sprintf("LOAD DATA LOCAL INFILE %s INTO TABLE test FIELDS TERMINATED BY ';' LINES TERMINATED  BY '\n'", $db->quote($filename));
    if (exec_and_count(4, $db, $sql, 2)) {
        $stmt = $db->query('SELECT id, col1 FROM test ORDER BY id ASC');
        $expected = array(array("id" => 1, "col1" => "foo"), array("id" => 2, "col1" => "bar"));
        $ret = $stmt->fetchAll(PDO::FETCH_ASSOC);
        foreach ($expected as $offset => $exp) {
            foreach ($exp as $key => $value) {
                if ($ret[$offset][$key] != $value) {
                    printf("Results seem wrong, check manually\n");
                    var_dump($ret);
<?php

require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
$dsn = MySQLPDOTest::getDSN();
$user = PDO_MYSQL_TEST_USER;
$pass = PDO_MYSQL_TEST_PASS;
$table = sprintf("test_%s", md5(mt_rand(0, PHP_INT_MAX)));
$db = new PDO($dsn, $user, $pass);
$db->exec(sprintf('DROP TABLE IF EXISTS %s', $table));
$create = sprintf('CREATE TABLE %s(id INT)', $table);
var_dump($create);
$db = new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => $create));
$info = $db->errorInfo();
var_dump($info[0]);
$db->exec(sprintf('INSERT INTO %s(id) VALUES (1)', $table));
$stmt = $db->query(sprintf('SELECT id FROM %s', $table));
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
$db->exec(sprintf('DROP TABLE IF EXISTS %s', $table));
print "done!";
Example #25
0
        $have_latin2 = empty($tmp) ? false : true;
        if ($have_latin1 && $have_latin2) {
            // very likely we do have both of them...
            try {
                $dsn = MySQLPDOTest::getDSN(array('charset' => 'latin1'));
                $db = new PDO($dsn, $user, $pass);
                $stmt = $db->query('SELECT @@character_set_connection AS _charset');
                $tmp = $stmt->fetch(PDO::FETCH_ASSOC);
                if ($tmp['_charset'] != 'latin1') {
                    printf("[031] DSN = %s, Character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", $dsn, $tmp['_charset'], 'latin1');
                }
            } catch (PDOException $e) {
                printf("[032] %s\n", $e->getMessage());
            }
            try {
                $dsn = MySQLPDOTest::getDSN(array('charset' => 'latin2'));
                $db = new PDO($dsn, $user, $pass);
                $stmt = $db->query('SELECT @@character_set_connection AS _charset');
                $tmp = $stmt->fetch(PDO::FETCH_ASSOC);
                if ($tmp['_charset'] != 'latin2') {
                    printf("[033] DSN = %s, character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", $dsn, $tmp['_charset'], 'latin2');
                }
            } catch (PDOException $e) {
                printf("[034] %s\n", $e->getMessage());
            }
        }
    }
} catch (PDOException $e) {
    printf("[001] %s, [%s] %s\n", $e->getMessage(), is_object($db) ? $db->errorCode() : 'n/a', is_object($db) ? implode(' ', $db->errorInfo()) : 'n/a');
}
print "done!";
Example #26
0
<?php

require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
$db = MySQLPDOTest::factory();
function fetch($offset, &$db, $query, $expect = null)
{
    try {
        $stmt = $db->query('SELECT 1');
        $num = $stmt->fetch(PDO::FETCH_NUM);
        $stmt = $db->query('SELECT 1');
        $assoc = $stmt->fetch(PDO::FETCH_ASSOC);
        $stmt = $db->query('SELECT 1');
        $both = $stmt->fetch(PDO::FETCH_BOTH);
        $computed_both = array_merge($num, $assoc);
        if ($computed_both != $both) {
            printf("[%03d] Suspicious FETCH_BOTH result, dumping\n", $offset);
            var_dump($computed_both);
            var_dump($both);
        }
        if (!is_null($expect) && $expect != $both) {
            printf("[%03d] Expected differs from returned data, dumping\n", $offset);
            var_dump($expect);
            var_dump($both);
        }
    } catch (PDOException $e) {
        printf("[%03d] %s, [%s] %s\n", $offset, $e->getMessage(), $db->errroCode(), implode(' ', $db->errorInfo()));
    }
}
try {
    fetch(2, $db, 'SELECT 1', array(0 => '1', '1' => '1'));
} catch (PDOException $e) {
    $stmt = $db->prepare('INSERT INTO test(id, label) VALUES (?, ?)');
    $stmt->bindParam(1, $id);
    $stmt->bindParam(2, $blob);
    if (true !== $stmt->execute()) {
        printf("[%03d + 9] %s\n", $offset, var_export($stmt->errorInfo(), true));
    }
    $stmt2 = $db->query('SELECT id, label FROM test WHERE id = 1');
    $row = $stmt2->fetch(PDO::FETCH_ASSOC);
    if ($row['label'] != $blob) {
        printf("[%03d + 10] INSERT and/or SELECT has failed, dumping data.\n", $offset);
        var_dump($row);
        var_dump($blob);
        return false;
    }
    return true;
}
$db = MySQLPDOTest::factory();
$blob = 'I am a mighty BLOB!' . chr(0) . "I am a binary thingie!";
$tmp = MySQLPDOTest::getTempDir();
$file = $tmp . DIRECTORY_SEPARATOR . 'pdoblob.tst';
try {
    printf("Emulated PS...\n");
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
    blob_from_stream(10, $db, $file, $blob);
    printf("Native PS...\n");
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
    blob_from_stream(30, $db, $file, $blob);
} catch (PDOException $e) {
    printf("[001] %s [%s] %s\n", $e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
}
print "done!";