ResultCacheTest.php 7.82 KB
Newer Older
1 2 3 4
<?php

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

require_once __DIR__ . '/../../TestInit.php';

/**
 * @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));
27
            $table->setPrimaryKey(array('test_int'));
28 29 30 31 32 33 34 35 36 37 38 39 40

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

        }
        $this->_conn->executeUpdate('DELETE FROM caching');
        foreach ($this->expectedResult AS $row) {
            $this->_conn->insert('caching', $row);
        }

        $config = $this->_conn->getConfiguration();
        $config->setSQLLogger($this->sqlLogger = new \Doctrine\DBAL\Logging\DebugStack);
41 42 43

        $cache = new \Doctrine\Common\Cache\ArrayCache;
        $config->setResultCacheImpl($cache);
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
    }

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

    public function testFetchNum()
    {
        $expectedResult = array();
        foreach ($this->expectedResult AS $v) {
            $expectedResult[] = array_values($v);
        }
        $this->assertCacheNonCacheSelectSameFetchModeAreEqual($expectedResult, \PDO::FETCH_NUM);
    }

    public function testFetchBoth()
    {
        $expectedResult = array();
        foreach ($this->expectedResult AS $v) {
            $expectedResult[] = array_merge($v, array_values($v));
        }
        $this->assertCacheNonCacheSelectSameFetchModeAreEqual($expectedResult, \PDO::FETCH_BOTH);
    }
68 69 70 71 72 73 74 75 76
	
    public function testFetchColumn()
    {
        $expectedResult = array();
        foreach ($this->expectedResult AS $v) {
            $expectedResult[] = array_shift($v);
        }
        $this->assertCacheNonCacheSelectSameFetchModeAreEqual($expectedResult, \PDO::FETCH_COLUMN);
    }
77 78 79 80 81 82 83

    public function testMixingFetch()
    {
        $numExpectedResult = array();
        foreach ($this->expectedResult AS $v) {
            $numExpectedResult[] = array_values($v);
        }
84
        $stmt = $this->_conn->executeQuery("SELECT * FROM caching ORDER BY test_int ASC", array(), array(), new QueryCacheProfile(10, "testcachekey"));
85

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

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

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

92
        $data = $this->hydrateStmt($stmt, \PDO::FETCH_NUM);
93 94 95 96

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

97 98 99 100 101 102 103
    public function testIteratorFetch()
    {
        $this->assertStandardAndIteratorFetchAreEqual(\PDO::FETCH_BOTH);
        $this->assertStandardAndIteratorFetchAreEqual(\PDO::FETCH_ASSOC);
        $this->assertStandardAndIteratorFetchAreEqual(\PDO::FETCH_NUM);
    }

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

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

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

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

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

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

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

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

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

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

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

143
        $data = $this->hydrateStmt($stmt, \PDO::FETCH_NUM);
144 145 146 147

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

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

        $this->assertEquals(2, $stmt->columnCount());
153
        $data = $this->hydrateStmt($stmt, $fetchMode);
154 155
        $this->assertEquals($expectedResult, $data);

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

        $this->assertEquals(2, $stmt->columnCount());
159
        $data = $this->hydrateStmt($stmt, $fetchMode);
160 161 162 163 164 165 166 167 168 169 170 171 172 173
        $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");
    }
174

175 176 177 178 179 180 181 182 183 184 185 186 187
    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")));
    }

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

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