diff --git a/src/Pseudo/ParsedQuery.php b/src/Pseudo/ParsedQuery.php index 1c7ce92..91561cd 100644 --- a/src/Pseudo/ParsedQuery.php +++ b/src/Pseudo/ParsedQuery.php @@ -6,22 +6,28 @@ class ParsedQuery private $parsedQuery; private $rawQuery; private $hash; + private $params; /** * @param string $query */ - public function __construct($query) + public function __construct($query, $params = null) { $parser = new \PHPSQLParser(); $this->parsedQuery = $parser->parse($query); $this->rawQuery = $query; - $this->hash = sha1(serialize($this->parsedQuery)); + $this->params = $params; + $serializedParams = ""; + if ($this->params != null) { + $serializedParams = serialize($this->params); + } + $this->hash = sha1(serialize($this->parsedQuery) . $serializedParams); } - public function isEqualTo($query) + public function isEqualTo($query, $params = null) { if (!($query instanceof self)) { - $query = new self($query); + $query = new self($query, $params); } return $this->hash === $query->getHash(); } diff --git a/src/Pseudo/Pdo.php b/src/Pseudo/Pdo.php index fda93c3..c1a9a87 100644 --- a/src/Pseudo/Pdo.php +++ b/src/Pseudo/Pdo.php @@ -9,8 +9,7 @@ class Pdo extends \PDO public function prepare($statement, $driver_options = null) { - $result = $this->mockedQueries->getResult($statement); - return new PdoStatement($result, $this->queryLog, $statement); + return new PdoStatement($this->mockedQueries, $this->queryLog, $statement); } public function beginTransaction() @@ -71,7 +70,7 @@ public function query($statement) $result = $this->mockedQueries->getResult($statement); if ($result) { $this->queryLog->addQuery($statement); - $statement = new PdoStatement(); + $statement = new PdoStatement($this->mockedQueries); $statement->setResult($result); return $statement; } @@ -124,7 +123,7 @@ public function quote($string, $parameter_type = PDO::PARAM_STR) /** * @param ResultCollection $collection */ - public function __construct(ResultCollection $collection = null) + public function __construct(ResultCollection $collection = null) { $this->mockedQueries = $collection ?: new ResultCollection(); $this->queryLog = new QueryLog(); diff --git a/src/Pseudo/PdoStatement.php b/src/Pseudo/PdoStatement.php index 0b31c70..35e6653 100644 --- a/src/Pseudo/PdoStatement.php +++ b/src/Pseudo/PdoStatement.php @@ -7,6 +7,7 @@ class PdoStatement extends \PDOStatement /** * @var Result; */ + private $mockedQueries; private $result; private $fetchMode = \PDO::FETCH_BOTH; //DEFAULT FETCHMODE private $boundParams = []; @@ -27,12 +28,9 @@ class PdoStatement extends \PDOStatement * @param string $statement * @param Result|null $result */ - public function __construct($result = null, QueryLog $queryLog = null, $statement = null) + public function __construct($mockedQueries = null, QueryLog $queryLog = null, $statement = null) { - if (!($result instanceof Result)) { - $result = new Result(); - } - $this->result = $result; + $this->mockedQueries = $mockedQueries; if (!($queryLog instanceof QueryLog)) { $queryLog = new QueryLog(); } @@ -52,6 +50,7 @@ public function setResult(Result $result) public function execute($input_parameters = null) { $input_parameters = array_merge((array)$input_parameters, $this->boundParams); + $this->result = $this->mockedQueries->getResult($this->statement, $input_parameters); try { $this->result->setParams($input_parameters, !empty($this->boundParams)); $success = (bool) $this->result->getRows($input_parameters ?: []); @@ -62,7 +61,7 @@ public function execute($input_parameters = null) } } - public function fetch($fetch_style = null, $cursor_orientation = PDO::FETCH_ORI_NEXT, $cursor_offset = 0) + public function fetch($fetch_style = null, $cursor_orientation = \PDO::FETCH_ORI_NEXT, $cursor_offset = 0) { // scrolling cursors not implemented $row = $this->result->nextRow(); diff --git a/src/Pseudo/QueryLog.php b/src/Pseudo/QueryLog.php index 8fbcff0..80720af 100644 --- a/src/Pseudo/QueryLog.php +++ b/src/Pseudo/QueryLog.php @@ -35,9 +35,9 @@ public function offsetUnset($offset) unset($this->queries[$offset]); } - public function addQuery($sql) + public function addQuery($sql, $params = null) { - $this->queries[] = new ParsedQuery($sql); + $this->queries[] = new ParsedQuery($sql, $params); } public function getQueries() diff --git a/src/Pseudo/ResultCollection.php b/src/Pseudo/ResultCollection.php index 6e80126..f6b253f 100644 --- a/src/Pseudo/ResultCollection.php +++ b/src/Pseudo/ResultCollection.php @@ -4,7 +4,7 @@ class ResultCollection implements \Countable { private $queries = []; - + public function count() { return count($this->queries); @@ -12,7 +12,7 @@ public function count() public function addQuery($sql, $results, $params = null) { - $query = new ParsedQuery($sql); + $query = new ParsedQuery($sql, $params); if (is_array($results)) { $storedResults = new Result($results, $params); @@ -25,16 +25,16 @@ public function addQuery($sql, $results, $params = null) $this->queries[$query->getHash()] = $storedResults; } - public function exists($sql) + public function exists($sql, $params = null) { - $query = new ParsedQuery($sql); + $query = new ParsedQuery($sql, $params); return isset($this->queries[$query->getHash()]); } - public function getResult($query) + public function getResult($query, $params = null) { if (!($query instanceof ParsedQuery)) { - $query = new ParsedQuery($query); + $query = new ParsedQuery($query, $params); } $result = (isset($this->queries[$query->getHash()])) ? $this->queries[$query->getHash()] : null; if ($result instanceof Result) { diff --git a/tests/ParsedQueryTest.php b/tests/ParsedQueryTest.php index c23be5c..921b406 100644 --- a/tests/ParsedQueryTest.php +++ b/tests/ParsedQueryTest.php @@ -11,6 +11,17 @@ public function testQueryHashing() $this->assertEquals($hashed, $q->getHash()); } + public function testQueryHashingWithParams() + { + $sql = "SELECT foo FROM bar WHERE baz = ?"; + $params = ["foo"]; + $q = new \Pseudo\ParsedQuery($sql, $params); + $p = new \PHPSQLParser(); + $parsed = $p->parse($sql); + $hashed = sha1(serialize($parsed) . serialize($params)); + $this->assertEquals($hashed, $q->getHash()); + } + public function testIsEquals() { $sql = "SELECT foo FROM bar WHERE baz"; diff --git a/tests/PdoStatementTest.php b/tests/PdoStatementTest.php index 898e701..f52dd71 100644 --- a/tests/PdoStatementTest.php +++ b/tests/PdoStatementTest.php @@ -87,7 +87,8 @@ public function testErrorCode() { $r = new Pseudo\Result(); $r->setErrorCode("HY000"); - $p = new Pseudo\PdoStatement($r); + $p = new Pseudo\PdoStatement(); + $p->setResult($r); $this->assertEquals("HY000", $p->errorCode()); } @@ -95,7 +96,8 @@ public function testErrorInfo() { $r = new Pseudo\Result(); $r->setErrorInfo("Storage engine error"); - $p = new Pseudo\PdoStatement($r); + $p = new Pseudo\PdoStatement(); + $p->setResult($r); $this->assertEquals("Storage engine error", $p->errorInfo()); } @@ -108,7 +110,8 @@ public function testColumnCount() 'foo' => 'bar' ] ); - $p = new Pseudo\PdoStatement($r); + $p = new Pseudo\PdoStatement(); + $p->setResult($r); $this->assertEquals(2, $p->columnCount()); } @@ -133,7 +136,8 @@ public function testFetch() ]; $r = new Pseudo\Result(); - $p = new Pseudo\PdoStatement($r); + $p = new Pseudo\PdoStatement(); + $p->setResult($r); $data = $p->fetch(); $this->assertEquals(false, $data); @@ -161,7 +165,8 @@ public function testFetchCol() ]; $r = new Pseudo\Result(); - $p = new Pseudo\PdoStatement($r); + $p = new Pseudo\PdoStatement(); + $p->setResult($r); $r->addRow($row1); $r->addRow($row2); @@ -179,14 +184,16 @@ public function testFetchWithBoundColumns() ]; $r = new Pseudo\Result(); $r->addRow($row1); - $p = new Pseudo\PdoStatement($r); + $p = new Pseudo\PdoStatement(); + $p->setResult($r); $p->bindColumn(2, $test); $p->fetch(PDO::FETCH_BOUND); $this->assertEquals('bar', $test); unset($test); $r->reset(); - $p = new Pseudo\PdoStatement($r); + $p = new Pseudo\PdoStatement(); + $p->setResult($r); $p->bindColumn('foo', $test); $p->fetch(PDO::FETCH_BOUND); $this->assertEquals('bar', $test); @@ -202,7 +209,8 @@ public function testFetchObject() $testObject = (object) $row1; $r = new Pseudo\Result(); $r->addRow($row1); - $s = new Pseudo\PdoStatement($r); + $s = new Pseudo\PdoStatement(); + $s->setResult($r); $this->assertEquals($testObject, $s->fetchObject()); } @@ -216,13 +224,58 @@ public function testExecute() 'bar' ]; + $p = new Pseudo\Pdo(); + $p->mock('SELECT * FROM test where foo = ?', $row1, $params1); + $queries = $p->getMockedQueries(); + $r = new Pseudo\Result(); $r->addRow($row1, $params1); $queryLog = new Pseudo\QueryLog(); - $s = new Pseudo\PdoStatement($r, $queryLog, 'SELECT * FROM test'); + $s = new Pseudo\PdoStatement($queries, $queryLog, 'SELECT * FROM test where foo = ?'); $this->assertEquals(true, $s->execute($params1)); - $this->assertEquals(false, $s->execute()); + + // this should no longer just return since we're now mocking with params + $caughtException = false; + try { + $this->assertEquals(false, $s->execute()); + } catch(\Exception $e) { + $this->assertEquals('Attempting an operation on an un-mocked query is not allowed, the raw query: SELECT * FROM test where foo = ?', $e->getMessage()); + $caughtException = true; + } + $this->assertTrue($caughtException); + } + + public function testExecuteWithSameQueryDifferentParams() + { + $row1 = [ + 'id' => 1, + 'foo' => 'bar', + ]; + $params1 = [ + 'bar' + ]; + + $row2 = [ + 'id' => 2, + 'foo' => 'bar2', + ]; + $params2 = [ + 'bar2' + ]; + + $p = new Pseudo\Pdo(); + $p->mock('SELECT * FROM test where foo = ?', $row1, $params1); + $p->mock('SELECT * FROM test where foo = ?', $row2, $params2); + $queries = $p->getMockedQueries(); + + $r = new Pseudo\Result(); + $r->addRow($row1, $params1); + $queryLog = new Pseudo\QueryLog(); + $s = new Pseudo\PdoStatement($queries, $queryLog, 'SELECT * FROM test where foo = ?'); + + $this->assertEquals(true, $s->execute($params1)); + $this->assertEquals(true, $s->execute($params2)); } public function testBindParam() @@ -252,7 +305,8 @@ public function testFetchColumn() $r = new Pseudo\Result(); $r->addRow($row1); - $s = new Pseudo\PdoStatement($r); + $s = new Pseudo\PdoStatement(); + $s->setResult($r); $this->assertEquals('bar', $s->fetchColumn(1)); $this->assertEquals(false, $s->fetchColumn(0)); diff --git a/tests/PdoTest.php b/tests/PdoTest.php index df50fa4..ab4fb92 100644 --- a/tests/PdoTest.php +++ b/tests/PdoTest.php @@ -34,7 +34,7 @@ public function testMock() $p->mock($sql3, $result1, $params3); $p->mock($sql3, $result2, $params4); - $this->assertEquals(3, count($p->getMockedQueries())); + $this->assertEquals(4, count($p->getMockedQueries())); } @@ -174,13 +174,14 @@ public function testSave() $this->assertEquals($r, $queries); unlink('testsave'); } - + public function testDebuggingRawQueries() { $message = null; $p = new Pseudo\Pdo(); try { - $p->prepare('SELECT 123'); + $sth = $p->prepare('SELECT 123'); + $sth->execute(); } catch (Exception $e) { $message = $e->getMessage(); } diff --git a/tests/QueryLogTest.php b/tests/QueryLogTest.php index a01b87c..829ad8c 100644 --- a/tests/QueryLogTest.php +++ b/tests/QueryLogTest.php @@ -10,4 +10,15 @@ public function testAddQuery() $this->assertEquals(1, count($queries)); $this->assertTrue($queries[0]->isEqualTo($sql)); } + + public function testAddQueryWithParams() + { + $sql = "SELECT foo FROM ?"; + $params = ["bar"]; + $queryLog = new \Pseudo\QueryLog(); + $queryLog->addQuery($sql, $params); + $queries = $queryLog->getQueries(); + $this->assertEquals(1, count($queries)); + $this->assertTrue($queries[0]->isEqualTo($sql, $params)); + } } \ No newline at end of file