Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
232d5852
Commit
232d5852
authored
May 03, 2017
by
Marco Pivetta
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'fix/#713-prevent-result-cache-key-collisions'
Close #713 DBAL-1030
parents
1b3c36b4
c23d80a1
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
205 additions
and
13 deletions
+205
-13
QueryCacheProfile.php
lib/Doctrine/DBAL/Cache/QueryCacheProfile.php
+8
-3
Connection.php
lib/Doctrine/DBAL/Connection.php
+1
-1
QueryCacheProfileTest.php
tests/Doctrine/Tests/DBAL/Cache/QueryCacheProfileTest.php
+145
-0
ConnectionTest.php
tests/Doctrine/Tests/DBAL/ConnectionTest.php
+42
-0
DB2SchemaManagerTest.php
tests/Doctrine/Tests/DBAL/Schema/DB2SchemaManagerTest.php
+7
-7
pgsql.travis.xml
tests/travis/pgsql.travis.xml
+1
-1
sqlite.travis.xml
tests/travis/sqlite.travis.xml
+1
-1
No files found.
lib/Doctrine/DBAL/Cache/QueryCacheProfile.php
View file @
232d5852
...
...
@@ -88,17 +88,22 @@ class QueryCacheProfile
}
/**
* Generates the real cache key from query, params
and type
s.
* Generates the real cache key from query, params
, types and connection parameter
s.
*
* @param string $query
* @param array $params
* @param array $types
* @param array $connectionParams
*
* @return array
*/
public
function
generateCacheKeys
(
$query
,
$params
,
$types
)
public
function
generateCacheKeys
(
$query
,
$params
,
$types
,
array
$connectionParams
=
[]
)
{
$realCacheKey
=
$query
.
"-"
.
serialize
(
$params
)
.
"-"
.
serialize
(
$types
);
$realCacheKey
=
'query='
.
$query
.
'¶ms='
.
serialize
(
$params
)
.
'&types='
.
serialize
(
$types
)
.
'&connectionParams='
.
serialize
(
$connectionParams
);
// should the key be automatically generated using the inputs or is the cache key set?
if
(
$this
->
cacheKey
===
null
)
{
$cacheKey
=
sha1
(
$realCacheKey
);
...
...
lib/Doctrine/DBAL/Connection.php
View file @
232d5852
...
...
@@ -879,7 +879,7 @@ class Connection implements DriverConnection
throw
CacheException
::
noResultDriverConfigured
();
}
list
(
$cacheKey
,
$realKey
)
=
$qcp
->
generateCacheKeys
(
$query
,
$params
,
$types
);
list
(
$cacheKey
,
$realKey
)
=
$qcp
->
generateCacheKeys
(
$query
,
$params
,
$types
,
$this
->
getParams
()
);
// fetch the row pointers entry
if
(
$data
=
$resultCache
->
fetch
(
$cacheKey
))
{
...
...
tests/Doctrine/Tests/DBAL/Cache/QueryCacheProfileTest.php
0 → 100644
View file @
232d5852
<?php
namespace
Doctrine\Tests\DBAL\Cache
;
use
Doctrine\DBAL\Cache\QueryCacheProfile
;
use
Doctrine\Tests\DbalTestCase
;
use
PDO
;
class
QueryCacheProfileTest
extends
DbalTestCase
{
const
LIFETIME
=
3600
;
const
CACHE_KEY
=
'user_specified_cache_key'
;
/** @var QueryCacheProfile */
private
$queryCacheProfile
;
protected
function
setUp
()
{
$this
->
queryCacheProfile
=
new
QueryCacheProfile
(
self
::
LIFETIME
,
self
::
CACHE_KEY
);
}
public
function
testShouldUseTheGivenCacheKeyIfPresent
()
{
$query
=
'SELECT * FROM foo WHERE bar = ?'
;
$params
=
[
666
];
$types
=
[
PDO
::
PARAM_INT
];
$connectionParams
=
array
(
'dbname'
=>
'database_name'
,
'user'
=>
'database_user'
,
'password'
=>
'database_password'
,
'host'
=>
'database_host'
,
'driver'
=>
'database_driver'
);
list
(
$cacheKey
)
=
$this
->
queryCacheProfile
->
generateCacheKeys
(
$query
,
$params
,
$types
,
$connectionParams
);
$this
->
assertEquals
(
self
::
CACHE_KEY
,
$cacheKey
,
'The returned cache key should match the given one'
);
}
public
function
testShouldGenerateAnAutomaticKeyIfNoKeyHasBeenGiven
()
{
$query
=
'SELECT * FROM foo WHERE bar = ?'
;
$params
=
[
666
];
$types
=
[
PDO
::
PARAM_INT
];
$connectionParams
=
array
(
'dbname'
=>
'database_name'
,
'user'
=>
'database_user'
,
'password'
=>
'database_password'
,
'host'
=>
'database_host'
,
'driver'
=>
'database_driver'
);
$this
->
queryCacheProfile
=
$this
->
queryCacheProfile
->
setCacheKey
(
null
);
list
(
$cacheKey
)
=
$this
->
queryCacheProfile
->
generateCacheKeys
(
$query
,
$params
,
$types
,
$connectionParams
);
$this
->
assertNotEquals
(
self
::
CACHE_KEY
,
$cacheKey
,
'The returned cache key should be generated automatically'
);
$this
->
assertNotEmpty
(
$cacheKey
,
'The generated cache key should not be empty'
);
}
public
function
testShouldGenerateDifferentKeysForSameQueryAndParamsAndDifferentConnections
()
{
$query
=
'SELECT * FROM foo WHERE bar = ?'
;
$params
=
[
666
];
$types
=
[
PDO
::
PARAM_INT
];
$connectionParams
=
array
(
'dbname'
=>
'database_name'
,
'user'
=>
'database_user'
,
'password'
=>
'database_password'
,
'host'
=>
'database_host'
,
'driver'
=>
'database_driver'
);
$this
->
queryCacheProfile
=
$this
->
queryCacheProfile
->
setCacheKey
(
null
);
list
(
$firstCacheKey
)
=
$this
->
queryCacheProfile
->
generateCacheKeys
(
$query
,
$params
,
$types
,
$connectionParams
);
$connectionParams
[
'host'
]
=
'a_different_host'
;
list
(
$secondCacheKey
)
=
$this
->
queryCacheProfile
->
generateCacheKeys
(
$query
,
$params
,
$types
,
$connectionParams
);
$this
->
assertNotEquals
(
$firstCacheKey
,
$secondCacheKey
,
'Cache keys should be different'
);
}
public
function
testShouldGenerateSameKeysIfNoneOfTheParamsChanges
()
{
$query
=
'SELECT * FROM foo WHERE bar = ?'
;
$params
=
[
666
];
$types
=
[
PDO
::
PARAM_INT
];
$connectionParams
=
array
(
'dbname'
=>
'database_name'
,
'user'
=>
'database_user'
,
'password'
=>
'database_password'
,
'host'
=>
'database_host'
,
'driver'
=>
'database_driver'
);
$this
->
queryCacheProfile
=
$this
->
queryCacheProfile
->
setCacheKey
(
null
);
list
(
$firstCacheKey
)
=
$this
->
queryCacheProfile
->
generateCacheKeys
(
$query
,
$params
,
$types
,
$connectionParams
);
list
(
$secondCacheKey
)
=
$this
->
queryCacheProfile
->
generateCacheKeys
(
$query
,
$params
,
$types
,
$connectionParams
);
$this
->
assertEquals
(
$firstCacheKey
,
$secondCacheKey
,
'Cache keys should be the same'
);
}
}
tests/Doctrine/Tests/DBAL/ConnectionTest.php
View file @
232d5852
...
...
@@ -2,12 +2,16 @@
namespace
Doctrine\Tests\DBAL
;
use
Doctrine\Common\Cache\Cache
;
use
Doctrine\Common\EventManager
;
use
Doctrine\DBAL\Cache\QueryCacheProfile
;
use
Doctrine\DBAL\Configuration
;
use
Doctrine\DBAL\Connection
;
use
Doctrine\DBAL\Driver
;
use
Doctrine\DBAL\Events
;
use
Doctrine\Tests\Mocks\DriverConnectionMock
;
use
Doctrine\Tests\Mocks\DriverMock
;
use
Doctrine\DBAL\Cache\ArrayStatement
;
class
ConnectionTest
extends
\Doctrine\Tests\DbalTestCase
{
...
...
@@ -670,4 +674,42 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
$this
->
assertSame
(
$platformMock
,
$connection
->
getDatabasePlatform
());
}
public
function
testConnectionParamsArePassedToTheQueryCacheProfileInExecuteCacheQuery
()
{
$resultCacheDriverMock
=
$this
->
createMock
(
Cache
::
class
);
$resultCacheDriverMock
->
expects
(
$this
->
atLeastOnce
())
->
method
(
'fetch'
)
->
with
(
'cacheKey'
)
->
will
(
$this
->
returnValue
([
'realKey'
=>
[]]));
$query
=
'SELECT * FROM foo WHERE bar = ?'
;
$params
=
[
666
];
$types
=
[
\PDO
::
PARAM_INT
];
/* @var $queryCacheProfileMock QueryCacheProfile|\PHPUnit_Framework_MockObject_MockObject */
$queryCacheProfileMock
=
$this
->
createMock
(
QueryCacheProfile
::
class
);
$queryCacheProfileMock
->
expects
(
$this
->
any
())
->
method
(
'getResultCacheDriver'
)
->
will
(
$this
->
returnValue
(
$resultCacheDriverMock
));
// This is our main expectation
$queryCacheProfileMock
->
expects
(
$this
->
once
())
->
method
(
'generateCacheKeys'
)
->
with
(
$query
,
$params
,
$types
,
$this
->
params
)
->
will
(
$this
->
returnValue
([
'cacheKey'
,
'realKey'
]));
/* @var $driver Driver */
$driver
=
$this
->
createMock
(
Driver
::
class
);
$this
->
assertInstanceOf
(
ArrayStatement
::
class
,
(
new
Connection
(
$this
->
params
,
$driver
))
->
executeCacheQuery
(
$query
,
$params
,
$types
,
$queryCacheProfileMock
)
);
}
}
tests/Doctrine/Tests/DBAL/Schema/DB2SchemaManagerTest.php
View file @
232d5852
...
...
@@ -27,13 +27,13 @@ final class DB2SchemaManagerTest extends \PHPUnit_Framework_TestCase
protected
function
setUp
()
{
$eventManager
=
new
EventManager
();
$driverMock
=
$this
->
get
Mock
(
Driver
::
class
);
$platform
=
$this
->
get
Mock
(
DB2Platform
::
class
);
$this
->
conn
=
$this
->
getMock
(
Connection
::
class
,
[
'fetchAll'
],
[[
'platform'
=>
$platform
],
$driverMock
,
new
Configuration
(),
$eventManager
]
);
$driverMock
=
$this
->
create
Mock
(
Driver
::
class
);
$platform
=
$this
->
create
Mock
(
DB2Platform
::
class
);
$this
->
conn
=
$this
->
getMockBuilder
(
Connection
::
class
)
->
setMethods
([
'fetchAll'
])
->
setConstructorArgs
([[
'platform'
=>
$platform
],
$driverMock
,
new
Configuration
(),
$eventManager
])
->
getMock
(
);
$this
->
manager
=
new
DB2SchemaManager
(
$this
->
conn
);
}
...
...
tests/travis/pgsql.travis.xml
View file @
232d5852
...
...
@@ -34,4 +34,4 @@
<group>
locking_functional
</group>
</exclude>
</groups>
</phpunit>
\ No newline at end of file
</phpunit>
tests/travis/sqlite.travis.xml
View file @
232d5852
...
...
@@ -21,4 +21,4 @@
<group>
locking_functional
</group>
</exclude>
</groups>
</phpunit>
\ No newline at end of file
</phpunit>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment