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
bf1da42d
Commit
bf1da42d
authored
Oct 22, 2011
by
Benjamin Eberlei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
DDC-217 - Add Result Cache feature
parent
f14cab2a
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
637 additions
and
83 deletions
+637
-83
ArrayStatement.php
lib/Doctrine/DBAL/Cache/ArrayStatement.php
+82
-0
RowCacheStatement.php
lib/Doctrine/DBAL/Cache/RowCacheStatement.php
+256
-0
Configuration.php
lib/Doctrine/DBAL/Configuration.php
+22
-0
Connection.php
lib/Doctrine/DBAL/Connection.php
+10
-2
ResultStatement.php
lib/Doctrine/DBAL/Driver/ResultStatement.php
+105
-0
Statement.php
lib/Doctrine/DBAL/Driver/Statement.php
+5
-81
ResultCacheTest.php
tests/Doctrine/Tests/DBAL/Functional/ResultCacheTest.php
+157
-0
No files found.
lib/Doctrine/DBAL/Cache/ArrayStatement.php
0 → 100644
View file @
bf1da42d
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace
Doctrine\DBAL\Cache
;
use
Doctrine\DBAL\Driver\ResultStatement
;
use
PDO
;
class
ArrayStatement
implements
ResultStatement
{
private
$data
;
private
$columnCount
=
0
;
private
$num
=
0
;
public
function
__construct
(
array
$data
)
{
$this
->
data
=
$data
;
if
(
count
(
$data
))
{
$this
->
columnCount
=
count
(
$data
[
0
]);
}
}
public
function
closeCursor
()
{
unset
(
$this
->
data
);
}
public
function
columnCount
()
{
return
$this
->
columnCount
;
}
public
function
fetch
(
$fetchStyle
=
PDO
::
FETCH_BOTH
)
{
if
(
isset
(
$this
->
data
[
$this
->
num
]))
{
$row
=
$this
->
data
[
$this
->
num
++
];
if
(
$fetchStyle
===
PDO
::
FETCH_ASSOC
)
{
return
$row
;
}
else
if
(
$fetchStyle
===
PDO
::
FETCH_NUM
)
{
return
array_values
(
$row
);
}
else
if
(
$fetchStyle
===
PDO
::
FETCH_BOTH
)
{
return
array_merge
(
$row
,
array_values
(
$row
));
}
}
return
false
;
}
public
function
fetchAll
(
$fetchStyle
=
PDO
::
FETCH_BOTH
)
{
$rows
=
array
();
while
(
$row
=
$this
->
fetch
(
$fetchStyle
))
{
$rows
[]
=
$row
;
}
return
$rows
;
}
public
function
fetchColumn
(
$columnIndex
=
0
)
{
$row
=
$this
->
fetch
(
PDO
::
FETCH_NUM
);
if
(
!
isset
(
$row
[
$columnIndex
]))
{
// TODO: verify this is correct behavior
return
false
;
}
return
$row
[
$columnIndex
];
}
}
\ No newline at end of file
lib/Doctrine/DBAL/Cache/RowCacheStatement.php
0 → 100644
View file @
bf1da42d
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace
Doctrine\DBAL\Cache
;
use
Doctrine\DBAL\Driver\ResultStatement
;
use
PDO
;
use
Doctrine\DBAL\Connection
;
/**
* Cache statement for SQL results.
*
* A result is saved in multiple cache keys, there is the originally specified
* cache key which is just pointing to result rows by key. The following things
* have to be ensured:
*
* 1. lifetime of the original key has to be longer than that of all the individual rows keys
* 2. if any one row key is missing the query has to be re-executed.
*
* Also you have to realize that the cache will load the whole result into memory at once to ensure 2.
* This means that the memory usage for cached results might increase by using this feature.
*/
class
RowCacheStatement
implements
ResultStatement
{
/**
* @var \Doctrine\DBAL\Connection
*/
private
$conn
;
/**
* @var \Doctrine\Common\Cache\Cache
*/
private
$cache
;
/**
*
* @var string
*/
private
$cacheKey
;
/**
* @var int
*/
private
$lifetime
;
/**
* @var Doctrine\DBAL\Driver\Statement
*/
private
$statement
;
/**
* @var array
*/
private
$rowPointers
=
array
();
/**
* @var int
*/
private
$num
=
0
;
/**
* Did we reach the end of the statement?
*
* @var bool
*/
private
$emptied
=
false
;
/**
* @param Connection $conn
* @param string $cacheKey
* @param int|null $lifetime
* @param string $query
* @param array $params
* @param array $types
* @return RowCacheStatement
*/
static
public
function
create
(
Connection
$conn
,
$cacheKey
,
$lifetime
,
$query
,
$params
,
$types
)
{
$resultCache
=
$conn
->
getConfiguration
()
->
getResultCacheImpl
();
if
(
!
$resultCache
)
{
return
$conn
->
executeQuery
(
$query
,
$params
,
$types
);
}
if
(
$rowPointers
=
$resultCache
->
fetch
(
$cacheKey
))
{
$data
=
array
();
foreach
(
$rowPointers
AS
$rowPointer
)
{
if
(
$row
=
$resultCache
->
fetch
(
$rowPointer
))
{
$data
[]
=
$row
;
}
else
{
return
new
self
(
$conn
->
executeQuery
(
$query
,
$params
,
$types
),
$resultCache
,
$cacheKey
,
$lifetime
);
}
}
return
new
ArrayStatement
(
$data
);
}
return
new
self
(
$conn
->
executeQuery
(
$query
,
$params
,
$types
),
$resultCache
,
$cacheKey
,
$lifetime
);
}
public
function
__construct
(
$stmt
,
$resultCache
,
$cacheKey
,
$lifetime
=
0
)
{
$this
->
statement
=
$stmt
;
$this
->
resultCache
=
$resultCache
;
$this
->
cacheKey
=
$cacheKey
;
$this
->
lifetime
=
$lifetime
;
}
/**
* Closes the cursor, enabling the statement to be executed again.
*
* @return boolean Returns TRUE on success or FALSE on failure.
*/
public
function
closeCursor
()
{
// the "important" key is written as the last one. This way we ensure it has a longer lifetime than the rest
// avoiding potential cache "misses" during the reconstruction.
if
(
$this
->
emptied
&&
$this
->
rowPointers
)
{
$this
->
resultCache
->
save
(
$this
->
cacheKey
,
$this
->
rowPointers
,
$this
->
lifetime
);
unset
(
$this
->
rowPointers
);
}
}
/**
* columnCount
* Returns the number of columns in the result set
*
* @return integer Returns the number of columns in the result set represented
* by the PDOStatement object. If there is no result set,
* this method should return 0.
*/
public
function
columnCount
()
{
return
$this
->
statement
->
columnCount
();
}
/**
* fetch
*
* @see Query::HYDRATE_* constants
* @param integer $fetchStyle Controls how the next row will be returned to the caller.
* This value must be one of the Query::HYDRATE_* constants,
* defaulting to Query::HYDRATE_BOTH
*
* @param integer $cursorOrientation For a PDOStatement object representing a scrollable cursor,
* this value determines which row will be returned to the caller.
* This value must be one of the Query::HYDRATE_ORI_* constants, defaulting to
* Query::HYDRATE_ORI_NEXT. To request a scrollable cursor for your
* PDOStatement object,
* you must set the PDO::ATTR_CURSOR attribute to Doctrine::CURSOR_SCROLL when you
* prepare the SQL statement with Doctrine_Adapter_Interface->prepare().
*
* @param integer $cursorOffset For a PDOStatement object representing a scrollable cursor for which the
* $cursorOrientation parameter is set to Query::HYDRATE_ORI_ABS, this value specifies
* the absolute number of the row in the result set that shall be fetched.
*
* For a PDOStatement object representing a scrollable cursor for
* which the $cursorOrientation parameter is set to Query::HYDRATE_ORI_REL, this value
* specifies the row to fetch relative to the cursor position before
* PDOStatement->fetch() was called.
*
* @return mixed
*/
public
function
fetch
(
$fetchStyle
=
PDO
::
FETCH_BOTH
)
{
$row
=
$this
->
statement
->
fetch
(
PDO
::
FETCH_ASSOC
);
if
(
$row
)
{
$rowCacheKey
=
$this
->
cacheKey
.
"#row"
.
(
$this
->
num
++
);
$this
->
rowPointers
[]
=
$rowCacheKey
;
$this
->
resultCache
->
save
(
$rowCacheKey
,
$row
,
$this
->
lifetime
);
if
(
$fetchStyle
==
PDO
::
FETCH_ASSOC
)
{
return
$row
;
}
else
if
(
$fetchStyle
==
PDO
::
FETCH_NUM
)
{
return
array_values
(
$row
);
}
else
if
(
$fetchStyle
==
PDO
::
FETCH_BOTH
)
{
return
array_merge
(
$row
,
array_values
(
$row
));
}
else
{
throw
new
\InvalidArgumentException
(
"Invalid fetch-style given for caching result."
);
}
}
$this
->
emptied
=
true
;
return
false
;
}
/**
* Returns an array containing all of the result set rows
*
* @param integer $fetchStyle Controls how the next row will be returned to the caller.
* This value must be one of the Query::HYDRATE_* constants,
* defaulting to Query::HYDRATE_BOTH
*
* @param integer $columnIndex Returns the indicated 0-indexed column when the value of $fetchStyle is
* Query::HYDRATE_COLUMN. Defaults to 0.
*
* @return array
*/
public
function
fetchAll
(
$fetchStyle
=
PDO
::
FETCH_BOTH
)
{
$rows
=
array
();
while
(
$row
=
$this
->
fetch
(
$fetchStyle
))
{
$rows
[]
=
$row
;
}
return
$rows
;
}
/**
* fetchColumn
* Returns a single column from the next row of a
* result set or FALSE if there are no more rows.
*
* @param integer $columnIndex 0-indexed number of the column you wish to retrieve from the row. If no
* value is supplied, PDOStatement->fetchColumn()
* fetches the first column.
*
* @return string returns a single column in the next row of a result set.
*/
public
function
fetchColumn
(
$columnIndex
=
0
)
{
$row
=
$this
->
fetch
(
PDO
::
FETCH_NUM
);
if
(
!
isset
(
$row
[
$columnIndex
]))
{
// TODO: verify this is correct behavior
return
false
;
}
return
$row
[
$columnIndex
];
}
/**
* rowCount
* rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement
* executed by the corresponding object.
*
* If the last SQL statement executed by the associated Statement object was a SELECT statement,
* some databases may return the number of rows returned by that statement. However,
* this behaviour is not guaranteed for all databases and should not be
* relied on for portable applications.
*
* @return integer Returns the number of rows.
*/
public
function
rowCount
()
{
return
$this
->
statement
->
rowCount
();
}
}
\ No newline at end of file
lib/Doctrine/DBAL/Configuration.php
View file @
bf1da42d
...
...
@@ -20,6 +20,7 @@
namespace
Doctrine\DBAL
;
use
Doctrine\DBAL\Logging\SQLLogger
;
use
Doctrine\Common\Cache\Cache
;
/**
* Configuration container for the Doctrine DBAL.
...
...
@@ -61,4 +62,25 @@ class Configuration
return
isset
(
$this
->
_attributes
[
'sqlLogger'
])
?
$this
->
_attributes
[
'sqlLogger'
]
:
null
;
}
/**
* Gets the cache driver implementation that is used for query result caching.
*
* @return \Doctrine\Common\Cache\Cache
*/
public
function
getResultCacheImpl
()
{
return
isset
(
$this
->
_attributes
[
'resultCacheImpl'
])
?
$this
->
_attributes
[
'resultCacheImpl'
]
:
null
;
}
/**
* Sets the cache driver implementation that is used for query result caching.
*
* @param \Doctrine\Common\Cache\Cache $cacheImpl
*/
public
function
setResultCacheImpl
(
Cache
$cacheImpl
)
{
$this
->
_attributes
[
'resultCacheImpl'
]
=
$cacheImpl
;
}
}
\ No newline at end of file
lib/Doctrine/DBAL/Connection.php
View file @
bf1da42d
...
...
@@ -23,7 +23,8 @@ use PDO, Closure, Exception,
Doctrine\DBAL\Types\Type
,
Doctrine\DBAL\Driver\Connection
as
DriverConnection
,
Doctrine\Common\EventManager
,
Doctrine\DBAL\DBALException
;
Doctrine\DBAL\DBALException
,
Doctrine\DBAL\Cache\RowCacheStatement
;
/**
* A wrapper around a Doctrine\DBAL\Driver\Connection that adds features like
...
...
@@ -593,11 +594,18 @@ class Connection implements DriverConnection
*
* @param string $query The SQL query to execute.
* @param array $params The parameters to bind to the query, if any.
* @param array $types The types the previous parameters are in.
* @param string|null $cacheResultKey name of the result cache key.
* @param int $cacheLifetime lifetime of the cache result.
* @return Doctrine\DBAL\Driver\Statement The executed statement.
* @internal PERF: Directly prepares a driver statement, not a wrapper.
*/
public
function
executeQuery
(
$query
,
array
$params
=
array
(),
$types
=
array
())
public
function
executeQuery
(
$query
,
array
$params
=
array
(),
$types
=
array
()
,
$cacheResultKey
=
null
,
$cacheLifetime
=
0
)
{
if
(
$cacheResultKey
!==
null
)
{
return
RowCacheStatement
::
create
(
$this
,
$cacheResultKey
,
$cacheLifetime
,
$query
,
$params
,
$types
);
}
$this
->
connect
();
$hasLogger
=
$this
->
_config
->
getSQLLogger
()
!==
null
;
...
...
lib/Doctrine/DBAL/Driver/ResultStatement.php
0 → 100644
View file @
bf1da42d
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace
Doctrine\DBAL\Driver
;
use
PDO
;
/**
* Interface for the reading part of a prepare statement only.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
interface
ResultStatement
{
/**
* Closes the cursor, enabling the statement to be executed again.
*
* @return boolean Returns TRUE on success or FALSE on failure.
*/
function
closeCursor
();
/**
* columnCount
* Returns the number of columns in the result set
*
* @return integer Returns the number of columns in the result set represented
* by the PDOStatement object. If there is no result set,
* this method should return 0.
*/
function
columnCount
();
/**
* fetch
*
* @see Query::HYDRATE_* constants
* @param integer $fetchStyle Controls how the next row will be returned to the caller.
* This value must be one of the Query::HYDRATE_* constants,
* defaulting to Query::HYDRATE_BOTH
*
* @param integer $cursorOrientation For a PDOStatement object representing a scrollable cursor,
* this value determines which row will be returned to the caller.
* This value must be one of the Query::HYDRATE_ORI_* constants, defaulting to
* Query::HYDRATE_ORI_NEXT. To request a scrollable cursor for your
* PDOStatement object,
* you must set the PDO::ATTR_CURSOR attribute to Doctrine::CURSOR_SCROLL when you
* prepare the SQL statement with Doctrine_Adapter_Interface->prepare().
*
* @param integer $cursorOffset For a PDOStatement object representing a scrollable cursor for which the
* $cursorOrientation parameter is set to Query::HYDRATE_ORI_ABS, this value specifies
* the absolute number of the row in the result set that shall be fetched.
*
* For a PDOStatement object representing a scrollable cursor for
* which the $cursorOrientation parameter is set to Query::HYDRATE_ORI_REL, this value
* specifies the row to fetch relative to the cursor position before
* PDOStatement->fetch() was called.
*
* @return mixed
*/
function
fetch
(
$fetchStyle
=
PDO
::
FETCH_BOTH
);
/**
* Returns an array containing all of the result set rows
*
* @param integer $fetchStyle Controls how the next row will be returned to the caller.
* This value must be one of the Query::HYDRATE_* constants,
* defaulting to Query::HYDRATE_BOTH
*
* @param integer $columnIndex Returns the indicated 0-indexed column when the value of $fetchStyle is
* Query::HYDRATE_COLUMN. Defaults to 0.
*
* @return array
*/
function
fetchAll
(
$fetchStyle
=
PDO
::
FETCH_BOTH
);
/**
* fetchColumn
* Returns a single column from the next row of a
* result set or FALSE if there are no more rows.
*
* @param integer $columnIndex 0-indexed number of the column you wish to retrieve from the row. If no
* value is supplied, PDOStatement->fetchColumn()
* fetches the first column.
*
* @return string returns a single column in the next row of a result set.
*/
function
fetchColumn
(
$columnIndex
=
0
);
}
lib/Doctrine/DBAL/Driver/Statement.php
View file @
bf1da42d
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...
...
@@ -34,9 +32,8 @@ use \PDO;
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
*/
interface
Statement
interface
Statement
extends
ResultStatement
{
/**
* Binds a value to a corresponding named or positional
...
...
@@ -77,23 +74,6 @@ interface Statement
*/
function
bindParam
(
$column
,
&
$variable
,
$type
=
null
);
/**
* Closes the cursor, enabling the statement to be executed again.
*
* @return boolean Returns TRUE on success or FALSE on failure.
*/
function
closeCursor
();
/**
* columnCount
* Returns the number of columns in the result set
*
* @return integer Returns the number of columns in the result set represented
* by the PDOStatement object. If there is no result set,
* this method should return 0.
*/
function
columnCount
();
/**
* errorCode
* Fetch the SQLSTATE associated with the last operation on the statement handle
...
...
@@ -128,62 +108,6 @@ interface Statement
*/
function
execute
(
$params
=
null
);
/**
* fetch
*
* @see Query::HYDRATE_* constants
* @param integer $fetchStyle Controls how the next row will be returned to the caller.
* This value must be one of the Query::HYDRATE_* constants,
* defaulting to Query::HYDRATE_BOTH
*
* @param integer $cursorOrientation For a PDOStatement object representing a scrollable cursor,
* this value determines which row will be returned to the caller.
* This value must be one of the Query::HYDRATE_ORI_* constants, defaulting to
* Query::HYDRATE_ORI_NEXT. To request a scrollable cursor for your
* PDOStatement object,
* you must set the PDO::ATTR_CURSOR attribute to Doctrine::CURSOR_SCROLL when you
* prepare the SQL statement with Doctrine_Adapter_Interface->prepare().
*
* @param integer $cursorOffset For a PDOStatement object representing a scrollable cursor for which the
* $cursorOrientation parameter is set to Query::HYDRATE_ORI_ABS, this value specifies
* the absolute number of the row in the result set that shall be fetched.
*
* For a PDOStatement object representing a scrollable cursor for
* which the $cursorOrientation parameter is set to Query::HYDRATE_ORI_REL, this value
* specifies the row to fetch relative to the cursor position before
* PDOStatement->fetch() was called.
*
* @return mixed
*/
function
fetch
(
$fetchStyle
=
PDO
::
FETCH_BOTH
);
/**
* Returns an array containing all of the result set rows
*
* @param integer $fetchStyle Controls how the next row will be returned to the caller.
* This value must be one of the Query::HYDRATE_* constants,
* defaulting to Query::HYDRATE_BOTH
*
* @param integer $columnIndex Returns the indicated 0-indexed column when the value of $fetchStyle is
* Query::HYDRATE_COLUMN. Defaults to 0.
*
* @return array
*/
function
fetchAll
(
$fetchStyle
=
PDO
::
FETCH_BOTH
);
/**
* fetchColumn
* Returns a single column from the next row of a
* result set or FALSE if there are no more rows.
*
* @param integer $columnIndex 0-indexed number of the column you wish to retrieve from the row. If no
* value is supplied, PDOStatement->fetchColumn()
* fetches the first column.
*
* @return string returns a single column in the next row of a result set.
*/
function
fetchColumn
(
$columnIndex
=
0
);
/**
* rowCount
* rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement
...
...
tests/Doctrine/Tests/DBAL/Functional/ResultCacheTest.php
0 → 100644
View file @
bf1da42d
<?php
namespace
Doctrine\Tests\DBAL\Functional
;
use
Doctrine\DBAL\Types\Type
;
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
));
$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
);
$config
->
setResultCacheImpl
(
new
\Doctrine\Common\Cache\ArrayCache
);
}
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
);
}
public
function
testMixingFetch
()
{
$numExpectedResult
=
array
();
foreach
(
$this
->
expectedResult
AS
$v
)
{
$numExpectedResult
[]
=
array_values
(
$v
);
}
$stmt
=
$this
->
_conn
->
executeQuery
(
"SELECT * FROM caching"
,
array
(),
array
(),
"testcachekey"
,
10
);
$data
=
array
();
while
(
$row
=
$stmt
->
fetch
(
\PDO
::
FETCH_ASSOC
))
{
$data
[]
=
$row
;
}
$stmt
->
closeCursor
();
$this
->
assertEquals
(
$this
->
expectedResult
,
$data
);
$stmt
=
$this
->
_conn
->
executeQuery
(
"SELECT * FROM caching"
,
array
(),
array
(),
"testcachekey"
,
10
);
$data
=
array
();
while
(
$row
=
$stmt
->
fetch
(
\PDO
::
FETCH_NUM
))
{
$data
[]
=
$row
;
}
$stmt
->
closeCursor
();
$this
->
assertEquals
(
$numExpectedResult
,
$data
);
}
public
function
testDontCloseNoCache
()
{
$stmt
=
$this
->
_conn
->
executeQuery
(
"SELECT * FROM caching"
,
array
(),
array
(),
"testcachekey"
,
10
);
$data
=
array
();
while
(
$row
=
$stmt
->
fetch
(
\PDO
::
FETCH_ASSOC
))
{
$data
[]
=
$row
;
}
$stmt
=
$this
->
_conn
->
executeQuery
(
"SELECT * FROM caching"
,
array
(),
array
(),
"testcachekey"
,
10
);
$data
=
array
();
while
(
$row
=
$stmt
->
fetch
(
\PDO
::
FETCH_NUM
))
{
$data
[]
=
$row
;
}
$this
->
assertEquals
(
2
,
count
(
$this
->
sqlLogger
->
queries
));
}
public
function
testDontFinishNoCache
()
{
$stmt
=
$this
->
_conn
->
executeQuery
(
"SELECT * FROM caching"
,
array
(),
array
(),
"testcachekey"
,
10
);
$row
=
$stmt
->
fetch
(
\PDO
::
FETCH_ASSOC
);
$stmt
->
closeCursor
();
$stmt
=
$this
->
_conn
->
executeQuery
(
"SELECT * FROM caching"
,
array
(),
array
(),
"testcachekey"
,
10
);
$data
=
array
();
while
(
$row
=
$stmt
->
fetch
(
\PDO
::
FETCH_NUM
))
{
$data
[]
=
$row
;
}
$stmt
->
closeCursor
();
$this
->
assertEquals
(
2
,
count
(
$this
->
sqlLogger
->
queries
));
}
public
function
assertCacheNonCacheSelectSameFetchModeAreEqual
(
$expectedResult
,
$fetchStyle
)
{
$stmt
=
$this
->
_conn
->
executeQuery
(
"SELECT * FROM caching"
,
array
(),
array
(),
"testcachekey"
,
10
);
$this
->
assertEquals
(
2
,
$stmt
->
columnCount
());
$data
=
array
();
while
(
$row
=
$stmt
->
fetch
(
$fetchStyle
))
{
$data
[]
=
$row
;
}
$stmt
->
closeCursor
();
$this
->
assertEquals
(
$expectedResult
,
$data
);
$stmt
=
$this
->
_conn
->
executeQuery
(
"SELECT * FROM caching"
,
array
(),
array
(),
"testcachekey"
,
10
);
$this
->
assertEquals
(
2
,
$stmt
->
columnCount
());
$data
=
array
();
while
(
$row
=
$stmt
->
fetch
(
$fetchStyle
))
{
$data
[]
=
$row
;
}
$stmt
->
closeCursor
();
$this
->
assertEquals
(
$expectedResult
,
$data
);
$this
->
assertEquals
(
1
,
count
(
$this
->
sqlLogger
->
queries
),
"just one dbal hit"
);
}
}
\ No newline at end of file
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