Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #775 from thedave80/DebugPDO-fix

DebugPDO executedQueryString - quoting
  • Loading branch information...
commit ae7bb7548e469e6da8b30020143ef7a0b3b9edad 2 parents 4dde6da + 067dad2
William Durand willdurand authored
14 runtime/lib/connection/DebugPDOStatement.php
View
@@ -74,7 +74,14 @@ public function getExecutedQueryString(array $values = array())
$size = count($matches[1]);
for ($i = $size - 1; $i >= 0; $i--) {
$pos = $matches[1][$i];
- $sql = str_replace($pos, $boundValues[$pos], $sql);
+
+ // trimming extra quotes, making sure value is properly quoted afterwards
+ $boundValue = $boundValues[$pos];
+ if (is_string($boundValue)) { // quoting only needed for string values
+ $boundValue = trim($boundValue, "'");
+ $boundValue = $this->pdo->quote($boundValue);
+ }
+ $sql = str_replace($pos, $boundValue, $sql);
}
}
@@ -120,7 +127,7 @@ public function bindValue($pos, $value, $type = PDO::PARAM_STR)
$valuestr = $type == PDO::PARAM_LOB ? '[LOB value]' : var_export($value, true);
$msg = sprintf('Binding %s at position %s w/ PDO type %s', $valuestr, $pos, $typestr);
- $this->boundValues[$pos] = $valuestr;
+ $this->boundValues[$pos] = $value;
$this->pdo->log($msg, null, __METHOD__, $debug);
@@ -143,13 +150,14 @@ public function bindValue($pos, $value, $type = PDO::PARAM_STR)
*/
public function bindParam($pos, &$value, $type = PDO::PARAM_STR, $length = 0, $driver_options = null)
{
+ $originalValue = $value;
$debug = $this->pdo->getDebugSnapshot();
$typestr = isset(self::$typeMap[$type]) ? self::$typeMap[$type] : '(default)';
$return = parent::bindParam($pos, $value, $type, $length, $driver_options);
$valuestr = $length > 100 ? '[Large value]' : var_export($value, true);
$msg = sprintf('Binding %s at position %s w/ PDO type %s', $valuestr, $pos, $typestr);
- $this->boundValues[$pos] = $valuestr;
+ $this->boundValues[$pos] = $originalValue;
$this->pdo->log($msg, null, __METHOD__, $debug);
200 test/testsuite/runtime/connection/PropelPDOTest.php
View
@@ -457,6 +457,206 @@ public function testDebugLog()
$con->setLogger($logger);
$config->setParameter("debugpdo.logging.methods", array('PropelPDO::exec', 'PropelPDO::query', 'DebugPDOStatement::execute'));
}
+
+ /**
+ * Testing if string values will be quoted correctly by DebugPDOStatement::getExecutedQueryString
+ */
+ public function testDebugExecutedQueryStringValue()
+ {
+
+ /**
+ * @var DebugPDO $con
+ */
+ $con = Propel::getConnection(BookPeer::DATABASE_NAME);
+
+ // different method must all result in this given querystring, using a string value
+ $bindParamStringValue = "%Harry%";
+ $expectedQuery = "SELECT book.id FROM `book` WHERE book.title LIKE '{$bindParamStringValue}'";
+
+ // simple statement without params
+ $prepStmt = $con->prepare($expectedQuery);
+ $prepStmt->execute();
+ $this->assertEquals($expectedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ // statement with named placeholder
+ $prepStmt = $con->prepare("SELECT book.id FROM `book` WHERE book.title LIKE :p1");
+ $prepStmt->bindValue(':p1', '%Harry%'); // bind value variant
+ $prepStmt->execute();
+ $this->assertEquals($expectedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ $prepStmt->bindParam(':p1', $bindParamStringValue); // bind param variant
+ $prepStmt->execute();
+ $this->assertEquals($expectedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ // passing params directly
+ $prepStmt->execute(array(':p1' => '%Harry%'));
+ $this->assertEquals($expectedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+
+ // statement with named placeholder, this one won't get substituted
+ $expectedNotSubstitutedQuery = "SELECT book.id FROM `book` WHERE book.title LIKE :name";
+ $prepStmt = $con->prepare($expectedNotSubstitutedQuery);
+ $prepStmt->bindValue(':name', '%Harry%'); // bind value variant
+ $prepStmt->execute();
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ $prepStmt->bindParam(':name', $bindParamStringValue); // bind param variant
+ $prepStmt->execute();
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ // passing params directly
+ $prepStmt->execute(array(':name' => '%Harry%'));
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+
+ // statement with positional placeholder, this one won't get substituted either
+ $expectedNotSubstitutedQuery = "SELECT book.id FROM `book` WHERE book.title LIKE ?";
+ $prepStmt = $con->prepare($expectedNotSubstitutedQuery);
+ $prepStmt->bindValue(1, '%Harry%');
+ $prepStmt->execute();
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ $prepStmt->bindParam(1, $bindParamStringValue);
+ $prepStmt->execute();
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ // passing params directly
+ $prepStmt->execute(array('%Harry%'));
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+ }
+
+ /**
+ * Testing if integer values will be quoted correctly by DebugPDOStatement::getExecutedQueryString
+ */
+ public function testDebugExecutedQueryIntegerValue() {
+
+ /**
+ * @var DebugPDO $con
+ */
+ $con = Propel::getConnection(BookPeer::DATABASE_NAME);
+
+ // different method must all result in this given querystring, using an integer value
+ $bindParamIntegerValue = 123;
+ $expectedQuery = "SELECT book.title FROM `book` WHERE book.id = {$bindParamIntegerValue}";
+
+ // simple statement without params
+ $prepStmt = $con->prepare($expectedQuery);
+ $prepStmt->execute();
+ $this->assertEquals($expectedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ // statement with named placeholder
+ $prepStmt = $con->prepare("SELECT book.title FROM `book` WHERE book.id = :p1");
+ $prepStmt->bindValue(':p1', 123); // bind value variant
+ $prepStmt->execute();
+ $this->assertEquals($expectedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ $prepStmt->bindParam(':p1', $bindParamIntegerValue); // bind param variant
+ $prepStmt->execute();
+ $this->assertEquals($expectedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ // passing params directly
+ $prepStmt->execute(array(':p1' => 123));
+ $this->assertEquals($expectedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+
+ // statement with named placeholder, this one won't get substituted
+ $expectedNotSubstitutedQuery = "SELECT book.title FROM `book` WHERE book.id = :name";
+ $prepStmt = $con->prepare($expectedNotSubstitutedQuery);
+ $prepStmt->bindValue(':name', 123); // bind value variant
+ $prepStmt->execute();
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ $prepStmt->bindParam(':name', $bindParamIntegerValue); // bind param variant
+ $prepStmt->execute();
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ // passing params directly
+ $prepStmt->execute(array(':name' => 123));
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+
+ // statement with positional placeholder, this one won't get substituted either
+ $expectedNotSubstitutedQuery = "SELECT book.title FROM `book` WHERE book.id = ?";
+ $prepStmt = $con->prepare($expectedNotSubstitutedQuery);
+ $prepStmt->bindValue(1, 123);
+ $prepStmt->execute();
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ $prepStmt->bindParam(1, $bindParamIntegerValue);
+ $prepStmt->execute();
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ // passing params directly
+ $prepStmt->execute(array(123));
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+ }
+
+ /**
+ * Testing if numeric values will be quoted correctly by DebugPDOStatement::getExecutedQueryString
+ * Numeric values sometimes will get handled differently, since there are numeric values which are non-integer
+ */
+ public function testDebugExecutedQueryNumericValue() {
+
+ /**
+ * @var DebugPDO $con
+ */
+ $con = Propel::getConnection(BookPeer::DATABASE_NAME);
+
+ // different method must all result in this given querystring, using an integer value
+ $bindParamNumericValue = 0002000;
+ $expectedQuery = "SELECT book.title FROM `book` WHERE book.id = {$bindParamNumericValue}";
+
+ // simple statement without params
+ $prepStmt = $con->prepare($expectedQuery);
+ $prepStmt->execute();
+ $this->assertEquals($expectedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ // statement with named placeholder
+ $prepStmt = $con->prepare("SELECT book.title FROM `book` WHERE book.id = :p1");
+ $prepStmt->bindValue(':p1', 0002000); // bind value variant
+ $prepStmt->execute();
+ $this->assertEquals($expectedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ $prepStmt->bindParam(':p1', $bindParamNumericValue); // bind param variant
+ $prepStmt->execute();
+ $this->assertEquals($expectedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ // passing params directly
+ $prepStmt->execute(array(':p1' => 0002000));
+ $this->assertEquals($expectedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+
+ // statement with named placeholder, this one won't get substituted
+ $expectedNotSubstitutedQuery = "SELECT book.title FROM `book` WHERE book.id = :name";
+ $prepStmt = $con->prepare($expectedNotSubstitutedQuery);
+ $prepStmt->bindValue(':name', 0002000); // bind value variant
+ $prepStmt->execute();
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ $prepStmt->bindParam(':name', $bindParamNumericValue); // bind param variant
+ $prepStmt->execute();
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ // passing params directly
+ $prepStmt->execute(array(':name' => 0002000));
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+
+ // statement with positional placeholder, this one won't get substituted either
+ $expectedNotSubstitutedQuery = "SELECT book.title FROM `book` WHERE book.id = ?";
+ $prepStmt = $con->prepare($expectedNotSubstitutedQuery);
+ $prepStmt->bindValue(1, 0002000);
+ $prepStmt->execute();
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ $prepStmt->bindParam(1, $bindParamNumericValue);
+ $prepStmt->execute();
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+
+ // passing params directly
+ $prepStmt->execute(array(0002000));
+ $this->assertEquals($expectedNotSubstitutedQuery, $con->getLastExecutedQuery(), 'DebugPDO failed to quote prepared statement on execute properly');
+ }
}
class myLogger
2  test/testsuite/runtime/query/ModelCriteriaTest.php
View
@@ -326,7 +326,7 @@ public function testWhereTypeValue()
);
$this->assertCriteriaTranslation($c, $sql, $params, 'where() accepts a complex calculation');
$c->find($this->con);
- $expected = "SELECT book.id, book.title, book.isbn, book.price, book.publisher_id, book.author_id FROM `book` WHERE LOCATE('foo', book.title) = true";
+ $expected = "SELECT book.id, book.title, book.isbn, book.price, book.publisher_id, book.author_id FROM `book` WHERE LOCATE('foo', book.title) = 1";
$this->assertEquals($expected, $this->con->getLastExecutedQuery());
}

2 comments on commit ae7bb75

Markus Staab
Collaborator

hmm looks like you lost the original author information?

Markus Staab
Collaborator

@willdurand nevermind. this is only the merge commit. everything fine!

Please sign in to comment.
Something went wrong with that request. Please try again.