ResultCacheTest.php 7.75 KB
Newer Older
1 2 3
<?php

namespace Doctrine\Tests\DBAL\Functional;
4
use Doctrine\DBAL\Cache\QueryCacheProfile;
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
use PDO;

/**
 * @group DDC-217
 */
class ResultCacheTest extends \Doctrine\Tests\DbalFunctionalTestCase
{
    private $expectedResult = array(array('test_int' => 100, 'test_string' => 'foo'), array('test_int' => 200, 'test_string' => 'bar'), array('test_int' => 300, 'test_string' => 'baz'));
    private $sqlLogger;

    public function setUp()
    {
        parent::setUp();

        try {
            /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
            $table = new \Doctrine\DBAL\Schema\Table("caching");
            $table->addColumn('test_int', 'integer');
            $table->addColumn('test_string', 'string', array('notnull' => false));
24
            $table->setPrimaryKey(array('test_int'));
25 26 27 28 29 30 31

            $sm = $this->_conn->getSchemaManager();
            $sm->createTable($table);
        } catch(\Exception $e) {

        }
        $this->_conn->executeUpdate('DELETE FROM caching');
jeroendedauw's avatar
jeroendedauw committed
32
        foreach ($this->expectedResult as $row) {
33 34 35 36 37
            $this->_conn->insert('caching', $row);
        }

        $config = $this->_conn->getConfiguration();
        $config->setSQLLogger($this->sqlLogger = new \Doctrine\DBAL\Logging\DebugStack);
38 39 40

        $cache = new \Doctrine\Common\Cache\ArrayCache;
        $config->setResultCacheImpl($cache);
41 42 43 44 45 46 47 48 49 50
    }

    public function testCacheFetchAssoc()
    {
        $this->assertCacheNonCacheSelectSameFetchModeAreEqual($this->expectedResult, \PDO::FETCH_ASSOC);
    }

    public function testFetchNum()
    {
        $expectedResult = array();
jeroendedauw's avatar
jeroendedauw committed
51
        foreach ($this->expectedResult as $v) {
52 53 54 55 56 57 58 59
            $expectedResult[] = array_values($v);
        }
        $this->assertCacheNonCacheSelectSameFetchModeAreEqual($expectedResult, \PDO::FETCH_NUM);
    }

    public function testFetchBoth()
    {
        $expectedResult = array();
jeroendedauw's avatar
jeroendedauw committed
60
        foreach ($this->expectedResult as $v) {
61 62 63 64
            $expectedResult[] = array_merge($v, array_values($v));
        }
        $this->assertCacheNonCacheSelectSameFetchModeAreEqual($expectedResult, \PDO::FETCH_BOTH);
    }
65

66 67 68
    public function testFetchColumn()
    {
        $expectedResult = array();
jeroendedauw's avatar
jeroendedauw committed
69
        foreach ($this->expectedResult as $v) {
70 71 72 73
            $expectedResult[] = array_shift($v);
        }
        $this->assertCacheNonCacheSelectSameFetchModeAreEqual($expectedResult, \PDO::FETCH_COLUMN);
    }
74 75 76 77

    public function testMixingFetch()
    {
        $numExpectedResult = array();
jeroendedauw's avatar
jeroendedauw committed
78
        foreach ($this->expectedResult as $v) {
79 80
            $numExpectedResult[] = array_values($v);
        }
81
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
82

83
        $data = $this->hydrateStmt($stmt, \PDO::FETCH_ASSOC);
84 85 86

        $this->assertEquals($this->expectedResult, $data);

87
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
88

89
        $data = $this->hydrateStmt($stmt, \PDO::FETCH_NUM);
90 91 92 93

        $this->assertEquals($numExpectedResult, $data);
    }

94 95 96 97 98 99 100
    public function testIteratorFetch()
    {
        $this->assertStandardAndIteratorFetchAreEqual(\PDO::FETCH_BOTH);
        $this->assertStandardAndIteratorFetchAreEqual(\PDO::FETCH_ASSOC);
        $this->assertStandardAndIteratorFetchAreEqual(\PDO::FETCH_NUM);
    }

101
    public function assertStandardAndIteratorFetchAreEqual($fetchMode)
102
    {
103
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
104
        $data = $this->hydrateStmt($stmt, $fetchMode);
105

106
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
107
        $data_iterator = $this->hydrateStmtIterator($stmt, $fetchMode);
108 109 110 111

        $this->assertEquals($data, $data_iterator);
    }

112 113
    public function testDontCloseNoCache()
    {
114
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
115 116 117 118 119 120

        $data = array();
        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
            $data[] = $row;
        }

121
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
122 123 124 125 126 127 128 129 130 131 132

        $data = array();
        while ($row = $stmt->fetch(\PDO::FETCH_NUM)) {
            $data[] = $row;
        }

        $this->assertEquals(2, count($this->sqlLogger->queries));
    }

    public function testDontFinishNoCache()
    {
133
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
134 135 136 137

        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
        $stmt->closeCursor();

138
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
139

140
        $data = $this->hydrateStmt($stmt, \PDO::FETCH_NUM);
141 142 143 144

        $this->assertEquals(2, count($this->sqlLogger->queries));
    }

145
    public function assertCacheNonCacheSelectSameFetchModeAreEqual($expectedResult, $fetchMode)
146
    {
147
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
148 149

        $this->assertEquals(2, $stmt->columnCount());
150
        $data = $this->hydrateStmt($stmt, $fetchMode);
151 152
        $this->assertEquals($expectedResult, $data);

153
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
154 155

        $this->assertEquals(2, $stmt->columnCount());
156
        $data = $this->hydrateStmt($stmt, $fetchMode);
157 158 159 160 161 162 163 164 165 166 167 168 169 170
        $this->assertEquals($expectedResult, $data);
        $this->assertEquals(1, count($this->sqlLogger->queries), "just one dbal hit");
    }

    public function testEmptyResultCache()
    {
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching WHERE test_int > 500", array(), array(), new QueryCacheProfile(10, "emptycachekey"));
        $data = $this->hydrateStmt($stmt);

        $stmt = $this->_conn->executeQuery("SELECT * FROM caching WHERE test_int > 500", array(), array(), new QueryCacheProfile(10, "emptycachekey"));
        $data = $this->hydrateStmt($stmt);

        $this->assertEquals(1, count($this->sqlLogger->queries), "just one dbal hit");
    }
171

172 173 174 175 176 177 178 179 180 181 182 183 184
    public function testChangeCacheImpl()
    {
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching WHERE test_int > 500", array(), array(), new QueryCacheProfile(10, "emptycachekey"));
        $data = $this->hydrateStmt($stmt);

        $secondCache = new \Doctrine\Common\Cache\ArrayCache;
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching WHERE test_int > 500", array(), array(), new QueryCacheProfile(10, "emptycachekey", $secondCache));
        $data = $this->hydrateStmt($stmt);

        $this->assertEquals(2, count($this->sqlLogger->queries), "two hits");
        $this->assertEquals(1, count($secondCache->fetch("emptycachekey")));
    }

185
    private function hydrateStmt($stmt, $fetchMode = \PDO::FETCH_ASSOC)
186
    {
187
        $data = array();
188
        while ($row = $stmt->fetch($fetchMode)) {
189
            $data[] = is_array($row) ? array_change_key_case($row, CASE_LOWER) : $row;
190 191
        }
        $stmt->closeCursor();
192
        return $data;
193
    }
194

195
    private function hydrateStmtIterator($stmt, $fetchMode = \PDO::FETCH_ASSOC)
196 197
    {
        $data = array();
198
        $stmt->setFetchMode($fetchMode);
199
        foreach ($stmt as $row) {
200
            $data[] = is_array($row) ? array_change_key_case($row, CASE_LOWER) : $row;
201 202 203 204
        }
        $stmt->closeCursor();
        return $data;
    }
205
}