ResultCacheTest.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. namespace Doctrine\Tests\DBAL\Functional;
  3. use Doctrine\DBAL\Types\Type;
  4. use Doctrine\DBAL\Cache\QueryCacheProfile;
  5. use PDO;
  6. require_once __DIR__ . '/../../TestInit.php';
  7. /**
  8. * @group DDC-217
  9. */
  10. class ResultCacheTest extends \Doctrine\Tests\DbalFunctionalTestCase
  11. {
  12. private $expectedResult = array(array('test_int' => 100, 'test_string' => 'foo'), array('test_int' => 200, 'test_string' => 'bar'), array('test_int' => 300, 'test_string' => 'baz'));
  13. private $sqlLogger;
  14. public function setUp()
  15. {
  16. parent::setUp();
  17. try {
  18. /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
  19. $table = new \Doctrine\DBAL\Schema\Table("caching");
  20. $table->addColumn('test_int', 'integer');
  21. $table->addColumn('test_string', 'string', array('notnull' => false));
  22. $table->setPrimaryKey(array('test_int'));
  23. $sm = $this->_conn->getSchemaManager();
  24. $sm->createTable($table);
  25. } catch(\Exception $e) {
  26. }
  27. $this->_conn->executeUpdate('DELETE FROM caching');
  28. foreach ($this->expectedResult AS $row) {
  29. $this->_conn->insert('caching', $row);
  30. }
  31. $config = $this->_conn->getConfiguration();
  32. $config->setSQLLogger($this->sqlLogger = new \Doctrine\DBAL\Logging\DebugStack);
  33. $cache = new \Doctrine\Common\Cache\ArrayCache;
  34. $config->setResultCacheImpl($cache);
  35. }
  36. public function testCacheFetchAssoc()
  37. {
  38. $this->assertCacheNonCacheSelectSameFetchModeAreEqual($this->expectedResult, \PDO::FETCH_ASSOC);
  39. }
  40. public function testFetchNum()
  41. {
  42. $expectedResult = array();
  43. foreach ($this->expectedResult AS $v) {
  44. $expectedResult[] = array_values($v);
  45. }
  46. $this->assertCacheNonCacheSelectSameFetchModeAreEqual($expectedResult, \PDO::FETCH_NUM);
  47. }
  48. public function testFetchBoth()
  49. {
  50. $expectedResult = array();
  51. foreach ($this->expectedResult AS $v) {
  52. $expectedResult[] = array_merge($v, array_values($v));
  53. }
  54. $this->assertCacheNonCacheSelectSameFetchModeAreEqual($expectedResult, \PDO::FETCH_BOTH);
  55. }
  56. public function testFetchColumn()
  57. {
  58. $expectedResult = array();
  59. foreach ($this->expectedResult AS $v) {
  60. $expectedResult[] = array_shift($v);
  61. }
  62. $this->assertCacheNonCacheSelectSameFetchModeAreEqual($expectedResult, \PDO::FETCH_COLUMN);
  63. }
  64. public function testMixingFetch()
  65. {
  66. $numExpectedResult = array();
  67. foreach ($this->expectedResult AS $v) {
  68. $numExpectedResult[] = array_values($v);
  69. }
  70. $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
  71. $data = $this->hydrateStmt($stmt, \PDO::FETCH_ASSOC);
  72. $this->assertEquals($this->expectedResult, $data);
  73. $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
  74. $data = $this->hydrateStmt($stmt, \PDO::FETCH_NUM);
  75. $this->assertEquals($numExpectedResult, $data);
  76. }
  77. public function testIteratorFetch()
  78. {
  79. $this->assertStandardAndIteratorFetchAreEqual(\PDO::FETCH_BOTH);
  80. $this->assertStandardAndIteratorFetchAreEqual(\PDO::FETCH_ASSOC);
  81. $this->assertStandardAndIteratorFetchAreEqual(\PDO::FETCH_NUM);
  82. }
  83. public function assertStandardAndIteratorFetchAreEqual($fetchMode)
  84. {
  85. $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
  86. $data = $this->hydrateStmt($stmt, $fetchMode);
  87. $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
  88. $data_iterator = $this->hydrateStmtIterator($stmt, $fetchMode);
  89. $this->assertEquals($data, $data_iterator);
  90. }
  91. public function testDontCloseNoCache()
  92. {
  93. $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
  94. $data = array();
  95. while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
  96. $data[] = $row;
  97. }
  98. $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
  99. $data = array();
  100. while ($row = $stmt->fetch(\PDO::FETCH_NUM)) {
  101. $data[] = $row;
  102. }
  103. $this->assertEquals(2, count($this->sqlLogger->queries));
  104. }
  105. public function testDontFinishNoCache()
  106. {
  107. $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
  108. $row = $stmt->fetch(\PDO::FETCH_ASSOC);
  109. $stmt->closeCursor();
  110. $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
  111. $data = $this->hydrateStmt($stmt, \PDO::FETCH_NUM);
  112. $this->assertEquals(2, count($this->sqlLogger->queries));
  113. }
  114. public function assertCacheNonCacheSelectSameFetchModeAreEqual($expectedResult, $fetchMode)
  115. {
  116. $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
  117. $this->assertEquals(2, $stmt->columnCount());
  118. $data = $this->hydrateStmt($stmt, $fetchMode);
  119. $this->assertEquals($expectedResult, $data);
  120. $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
  121. $this->assertEquals(2, $stmt->columnCount());
  122. $data = $this->hydrateStmt($stmt, $fetchMode);
  123. $this->assertEquals($expectedResult, $data);
  124. $this->assertEquals(1, count($this->sqlLogger->queries), "just one dbal hit");
  125. }
  126. public function testEmptyResultCache()
  127. {
  128. $stmt = $this->_conn->executeQuery("SELECT * FROM caching WHERE test_int > 500", array(), array(), new QueryCacheProfile(10, "emptycachekey"));
  129. $data = $this->hydrateStmt($stmt);
  130. $stmt = $this->_conn->executeQuery("SELECT * FROM caching WHERE test_int > 500", array(), array(), new QueryCacheProfile(10, "emptycachekey"));
  131. $data = $this->hydrateStmt($stmt);
  132. $this->assertEquals(1, count($this->sqlLogger->queries), "just one dbal hit");
  133. }
  134. public function testChangeCacheImpl()
  135. {
  136. $stmt = $this->_conn->executeQuery("SELECT * FROM caching WHERE test_int > 500", array(), array(), new QueryCacheProfile(10, "emptycachekey"));
  137. $data = $this->hydrateStmt($stmt);
  138. $secondCache = new \Doctrine\Common\Cache\ArrayCache;
  139. $stmt = $this->_conn->executeQuery("SELECT * FROM caching WHERE test_int > 500", array(), array(), new QueryCacheProfile(10, "emptycachekey", $secondCache));
  140. $data = $this->hydrateStmt($stmt);
  141. $this->assertEquals(2, count($this->sqlLogger->queries), "two hits");
  142. $this->assertEquals(1, count($secondCache->fetch("emptycachekey")));
  143. }
  144. private function hydrateStmt($stmt, $fetchMode = \PDO::FETCH_ASSOC)
  145. {
  146. $data = array();
  147. while ($row = $stmt->fetch($fetchMode)) {
  148. $data[] = is_array($row) ? array_change_key_case($row, CASE_LOWER) : $row;
  149. }
  150. $stmt->closeCursor();
  151. return $data;
  152. }
  153. private function hydrateStmtIterator($stmt, $fetchMode = \PDO::FETCH_ASSOC)
  154. {
  155. $data = array();
  156. $stmt->setFetchMode($fetchMode);
  157. foreach ($stmt as $row) {
  158. $data[] = is_array($row) ? array_change_key_case($row, CASE_LOWER) : $row;
  159. }
  160. $stmt->closeCursor();
  161. return $data;
  162. }
  163. }