ResultCacheTest.php 7.61 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
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;

15
    protected function setUp()
16 17 18
    {
        parent::setUp();

19 20 21 22
        $table = new \Doctrine\DBAL\Schema\Table("caching");
        $table->addColumn('test_int', 'integer');
        $table->addColumn('test_string', 'string', array('notnull' => false));
        $table->setPrimaryKey(array('test_int'));
23

24 25
        $sm = $this->_conn->getSchemaManager();
        $sm->createTable($table);
26

jeroendedauw's avatar
jeroendedauw committed
27
        foreach ($this->expectedResult as $row) {
28 29 30 31 32
            $this->_conn->insert('caching', $row);
        }

        $config = $this->_conn->getConfiguration();
        $config->setSQLLogger($this->sqlLogger = new \Doctrine\DBAL\Logging\DebugStack);
33 34 35

        $cache = new \Doctrine\Common\Cache\ArrayCache;
        $config->setResultCacheImpl($cache);
36 37
    }

38 39 40 41 42 43 44
    protected function tearDown()
    {
        $this->_conn->getSchemaManager()->dropTable('caching');

        parent::tearDown();
    }

45 46
    public function testCacheFetchAssoc()
    {
47
        self::assertCacheNonCacheSelectSameFetchModeAreEqual($this->expectedResult, \PDO::FETCH_ASSOC);
48 49 50 51 52
    }

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

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

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

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

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

87
        self::assertEquals($this->expectedResult, $data);
88

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

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

93
        self::assertEquals($numExpectedResult, $data);
94 95
    }

96 97
    public function testIteratorFetch()
    {
98 99 100
        self::assertStandardAndIteratorFetchAreEqual(\PDO::FETCH_BOTH);
        self::assertStandardAndIteratorFetchAreEqual(\PDO::FETCH_ASSOC);
        self::assertStandardAndIteratorFetchAreEqual(\PDO::FETCH_NUM);
101 102
    }

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

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

111
        self::assertEquals($data, $data_iterator);
112 113
    }

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

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

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

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

Gabriel Caruso's avatar
Gabriel Caruso committed
130
        self::assertCount(2, $this->sqlLogger->queries);
131 132 133 134
    }

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

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

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

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

Gabriel Caruso's avatar
Gabriel Caruso committed
144
        self::assertCount(2, $this->sqlLogger->queries);
145 146
    }

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

151
        self::assertEquals(2, $stmt->columnCount());
152
        $data = $this->hydrateStmt($stmt, $fetchMode);
153
        self::assertEquals($expectedResult, $data);
154

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

157
        self::assertEquals(2, $stmt->columnCount());
158
        $data = $this->hydrateStmt($stmt, $fetchMode);
159
        self::assertEquals($expectedResult, $data);
Gabriel Caruso's avatar
Gabriel Caruso committed
160
        self::assertCount(1, $this->sqlLogger->queries, "just one dbal hit");
161 162 163 164 165 166 167 168 169 170
    }

    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);

Gabriel Caruso's avatar
Gabriel Caruso committed
171
        self::assertCount(1, $this->sqlLogger->queries, "just one dbal hit");
172
    }
173

174 175 176 177 178 179 180 181 182
    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);

Gabriel Caruso's avatar
Gabriel Caruso committed
183 184
        self::assertCount(2, $this->sqlLogger->queries, "two hits");
        self::assertCount(1, $secondCache->fetch("emptycachekey"));
185 186
    }

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

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