Cache implementation continues
This commit is contained in:
parent
10a6a5fc17
commit
a7d1bc5633
@ -31,7 +31,7 @@
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
*/
|
||||
class Doctrine_Adapter_Mock implements Doctrine_Adapter_Interface
|
||||
class Doctrine_Adapter_Mock implements Doctrine_Adapter_Interface, Countable
|
||||
{
|
||||
private $name;
|
||||
|
||||
@ -59,7 +59,10 @@ class Doctrine_Adapter_Mock implements Doctrine_Adapter_Interface
|
||||
}
|
||||
public function prepare($query)
|
||||
{
|
||||
return new Doctrine_Adapter_Statement_Mock($this, $query);
|
||||
$mock = new Doctrine_Adapter_Statement_Mock($this, $query);
|
||||
$mock->queryString = $query;
|
||||
|
||||
return $mock;
|
||||
}
|
||||
public function addQuery($query)
|
||||
{
|
||||
@ -79,7 +82,10 @@ class Doctrine_Adapter_Mock implements Doctrine_Adapter_Interface
|
||||
throw new $name($e[1], $e[2]);
|
||||
}
|
||||
|
||||
return new Doctrine_Adapter_Statement_Mock($this, $query);
|
||||
$stmt = new Doctrine_Adapter_Statement_Mock($this, $query);
|
||||
$stmt->queryString = $query;
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
public function getAll()
|
||||
{
|
||||
@ -122,6 +128,10 @@ class Doctrine_Adapter_Mock implements Doctrine_Adapter_Interface
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
public function count()
|
||||
{
|
||||
return count($this->queries);
|
||||
}
|
||||
public function beginTransaction()
|
||||
{
|
||||
$this->queries[] = 'BEGIN TRANSACTION';
|
||||
|
@ -35,12 +35,11 @@ class Doctrine_Adapter_Statement_Mock
|
||||
{
|
||||
private $mock;
|
||||
|
||||
private $query;
|
||||
public $queryString;
|
||||
|
||||
public function __construct(Doctrine_Adapter_Mock $mock, $query)
|
||||
public function __construct($mock)
|
||||
{
|
||||
$this->mock = $mock;
|
||||
$this->query = $query;
|
||||
}
|
||||
public function fetch($fetchMode)
|
||||
{
|
||||
@ -52,7 +51,9 @@ class Doctrine_Adapter_Statement_Mock
|
||||
}
|
||||
public function execute()
|
||||
{
|
||||
$this->mock->addQuery($this->query);
|
||||
if(is_object($this->mock)) {
|
||||
$this->mock->addQuery($this->queryString);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public function fetchColumn($colnum = 0)
|
||||
|
@ -41,6 +41,8 @@ class Doctrine_Cache extends Doctrine_Db_EventListener implements Countable, Ite
|
||||
|
||||
protected $_driver;
|
||||
|
||||
protected $_data;
|
||||
|
||||
public function __construct($driverName, $options = array())
|
||||
{
|
||||
$class = 'Doctrine_Cache_' . ucwords(strtolower($driverName));
|
||||
@ -51,10 +53,17 @@ class Doctrine_Cache extends Doctrine_Db_EventListener implements Countable, Ite
|
||||
|
||||
$this->_driver = new $class($options);
|
||||
}
|
||||
|
||||
|
||||
public function getDriver()
|
||||
{
|
||||
return $this->_driver;
|
||||
}
|
||||
/**
|
||||
* addQuery
|
||||
*
|
||||
* @param string $query sql query string
|
||||
* @param string|array $query sql query string
|
||||
* @param string $namespace connection namespace
|
||||
* @return void
|
||||
*/
|
||||
public function add($query, $namespace = null)
|
||||
@ -134,6 +143,9 @@ class Doctrine_Cache extends Doctrine_Db_EventListener implements Countable, Ite
|
||||
$stats = array();
|
||||
|
||||
foreach ($queries as $query) {
|
||||
if (is_array($query)) {
|
||||
$query = $query[0];
|
||||
}
|
||||
if (isset($stats[$query])) {
|
||||
$stats[$query]++;
|
||||
} else {
|
||||
@ -143,7 +155,7 @@ class Doctrine_Cache extends Doctrine_Db_EventListener implements Countable, Ite
|
||||
sort($stats);
|
||||
|
||||
$i = $this->_options['size'];
|
||||
|
||||
|
||||
while ($i--) {
|
||||
$element = next($stats);
|
||||
$query = key($stats);
|
||||
@ -166,15 +178,34 @@ class Doctrine_Cache extends Doctrine_Db_EventListener implements Countable, Ite
|
||||
|
||||
public function onPreQuery(Doctrine_Db_Event $event)
|
||||
{
|
||||
$query = $event->getQuery();
|
||||
|
||||
// only process SELECT statements
|
||||
if (substr(trim(strtoupper($query)), 0, 6) == 'SELECT') {
|
||||
|
||||
$this->add($query, $event->getInvoker()->getName());
|
||||
|
||||
$data = $this->_driver->fetch(md5($query));
|
||||
|
||||
$this->_data = $data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onQuery(Doctrine_Db_Event $event)
|
||||
{
|
||||
$this->add($event->getQuery(), $event->getInvoker()->getName());
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function onPreFetchAll(Doctrine_Db_Event $event)
|
||||
{
|
||||
return $this->_data;
|
||||
}
|
||||
public function onPrePrepare(Doctrine_Db_Event $event)
|
||||
{
|
||||
{
|
||||
|
||||
}
|
||||
public function onPrepare(Doctrine_Db_Event $event)
|
||||
@ -187,16 +218,29 @@ class Doctrine_Cache extends Doctrine_Db_EventListener implements Countable, Ite
|
||||
|
||||
}
|
||||
public function onExec(Doctrine_Db_Event $event)
|
||||
{
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function onPreExecute(Doctrine_Db_Event $event)
|
||||
{
|
||||
$query = $event->getQuery();
|
||||
|
||||
// only process SELECT statements
|
||||
if (substr(trim(strtoupper($query)), 0, 6) == 'SELECT') {
|
||||
|
||||
$this->add($query, $event->getInvoker()->getDbh()->getName());
|
||||
|
||||
$data = $this->_driver->fetch(md5(serialize(array($query, $event->getParams()))));
|
||||
|
||||
$this->_data = $data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public function onExecute(Doctrine_Db_Event $event)
|
||||
{
|
||||
$this->add($event->getQuery(), $event->getInvoker()->getName());
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ class Doctrine_Cache_Apc extends Doctrine_Cache_Driver
|
||||
* @param int $lifeTime if != false, set a specific lifetime for this cache record (null => infinite lifeTime)
|
||||
* @return boolean true if no problem
|
||||
*/
|
||||
public function save($data, $id, $lifeTime = false)
|
||||
public function save($id, $data, $lifeTime = false)
|
||||
{
|
||||
$lifeTime = $this->getLifeTime($lifeTime);
|
||||
|
||||
|
@ -74,7 +74,7 @@ class Doctrine_Cache_Array
|
||||
* @param int $lifeTime if != false, set a specific lifetime for this cache record (null => infinite lifeTime)
|
||||
* @return boolean true if no problem
|
||||
*/
|
||||
public function save($data, $id, $lifeTime = false)
|
||||
public function save($id, $data, $lifeTime = false)
|
||||
{
|
||||
$this->data[$id] = $data;
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ class Doctrine_Cache_Memcache extends Doctrine_Cache_Driver
|
||||
* @param int $lifeTime if != false, set a specific lifetime for this cache record (null => infinite lifeTime)
|
||||
* @return boolean true if no problem
|
||||
*/
|
||||
public function save($data, $id, $lifeTime = false)
|
||||
public function save($id, $data, $lifeTime = false)
|
||||
{
|
||||
$lifeTime = $this->getLifeTime($specificLifeTime);
|
||||
|
||||
|
@ -74,15 +74,13 @@ class Doctrine_Db implements Countable, IteratorAggregate, Doctrine_Adapter_Inte
|
||||
* listener for listening events
|
||||
*/
|
||||
protected $listener;
|
||||
/**
|
||||
* @var integer $querySequence
|
||||
*/
|
||||
protected $querySequence = 0;
|
||||
/**
|
||||
* @var string $name name of this connection
|
||||
* @see Doctrine_Manager::openConnection()
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
protected $count = 0;
|
||||
|
||||
|
||||
private static $driverMap = array('oracle' => 'oci8',
|
||||
@ -120,17 +118,10 @@ class Doctrine_Db implements Countable, IteratorAggregate, Doctrine_Adapter_Inte
|
||||
$this->options['password'] = $pass;
|
||||
$this->listener = new Doctrine_Db_EventListener();
|
||||
}
|
||||
|
||||
public function nextQuerySequence()
|
||||
|
||||
public function incrementQueryCount()
|
||||
{
|
||||
return ++$this->querySequence;
|
||||
}
|
||||
/**
|
||||
* getQuerySequence
|
||||
*/
|
||||
public function getQuerySequence()
|
||||
{
|
||||
return $this->querySequence;
|
||||
$this->count++;
|
||||
}
|
||||
/**
|
||||
* getDbh
|
||||
@ -139,6 +130,15 @@ class Doctrine_Db implements Countable, IteratorAggregate, Doctrine_Adapter_Inte
|
||||
{
|
||||
return $this->dbh;
|
||||
}
|
||||
/**
|
||||
* getAdapter
|
||||
*
|
||||
* @return Doctrine_Adapter_Interface|PDO $adapter
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->dbh;
|
||||
}
|
||||
/**
|
||||
* setAdapter
|
||||
*
|
||||
@ -410,8 +410,6 @@ class Doctrine_Db implements Countable, IteratorAggregate, Doctrine_Adapter_Inte
|
||||
|
||||
$this->listener->onPrepare($event);
|
||||
|
||||
$this->querySequence++;
|
||||
|
||||
return new Doctrine_Db_Statement($this, $stmt);
|
||||
}
|
||||
/**
|
||||
@ -426,16 +424,23 @@ class Doctrine_Db implements Countable, IteratorAggregate, Doctrine_Adapter_Inte
|
||||
|
||||
$event = new Doctrine_Db_Event($this, Doctrine_Db_Event::QUERY, $statement);
|
||||
|
||||
$this->listener->onPreQuery($event);
|
||||
$skip = $this->listener->onPreQuery($event);
|
||||
|
||||
if ( ! empty($params)) {
|
||||
$stmt = $this->dbh->query($statement)->execute($params);
|
||||
$stmt = $this->dbh->prepare($statement);
|
||||
return $stmt->execute($params);
|
||||
} else {
|
||||
$stmt = $this->dbh->query($statement);
|
||||
if ( ! $skip) {
|
||||
$stmt = $this->dbh->query($statement);
|
||||
$this->count++;
|
||||
} else {
|
||||
$stmt = new stdClass;
|
||||
$stmt->queryString = $statement;
|
||||
}
|
||||
$stmt = new Doctrine_Db_Statement($this, $stmt);
|
||||
}
|
||||
$this->listener->onQuery($event);
|
||||
|
||||
$this->querySequence++;
|
||||
$this->listener->onQuery($event);
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
@ -471,6 +476,8 @@ class Doctrine_Db implements Countable, IteratorAggregate, Doctrine_Adapter_Inte
|
||||
|
||||
$rows = $this->dbh->exec($statement);
|
||||
|
||||
$this->count++;
|
||||
|
||||
$this->listener->onExec($event);
|
||||
|
||||
return $rows;
|
||||
@ -591,8 +598,9 @@ class Doctrine_Db implements Countable, IteratorAggregate, Doctrine_Adapter_Inte
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
if ($this->listener instanceof Doctrine_Db_Profiler)
|
||||
if ($this->listener instanceof Doctrine_Db_Profiler) {
|
||||
return $this->listener;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* count
|
||||
@ -602,6 +610,6 @@ class Doctrine_Db implements Countable, IteratorAggregate, Doctrine_Adapter_Inte
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->querySequence;
|
||||
return $this->count;
|
||||
}
|
||||
}
|
||||
|
@ -87,9 +87,16 @@ class Doctrine_Db_EventListener_Chain extends Doctrine_Access implements Doctrin
|
||||
}
|
||||
public function onPreQuery(Doctrine_Db_Event $event)
|
||||
{
|
||||
$return = null;
|
||||
|
||||
foreach ($this->listeners as $listener) {
|
||||
$listener->onPreQuery($event);
|
||||
$tmp = $listener->onPreQuery($event);
|
||||
|
||||
if ($tmp !== null) {
|
||||
$return = $tmp;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function onPreExec(Doctrine_Db_Event $event)
|
||||
@ -145,9 +152,16 @@ class Doctrine_Db_EventListener_Chain extends Doctrine_Access implements Doctrin
|
||||
|
||||
public function onPreFetchAll(Doctrine_Db_Event $event)
|
||||
{
|
||||
$return = null;
|
||||
|
||||
foreach ($this->listeners as $listener) {
|
||||
$listener->onPreFetchAll($event);
|
||||
$tmp = $listener->onPreFetchAll($event);
|
||||
|
||||
if ($tmp !== null) {
|
||||
$return = $tmp;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
public function onFetchAll(Doctrine_Db_Event $event)
|
||||
{
|
||||
@ -184,9 +198,16 @@ class Doctrine_Db_EventListener_Chain extends Doctrine_Access implements Doctrin
|
||||
|
||||
public function onPreExecute(Doctrine_Db_Event $event)
|
||||
{
|
||||
$return = null;
|
||||
|
||||
foreach ($this->listeners as $listener) {
|
||||
$listener->onPreExecute($event);
|
||||
$tmp = $listener->onPreExecute($event);
|
||||
|
||||
if ($tmp !== null) {
|
||||
$return = $tmp;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
public function onExecute(Doctrine_Db_Event $event)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ Doctrine::autoload('Doctrine_Overloadable');
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
*/
|
||||
class Doctrine_Db_Profiler extends Doctrine_Access implements Doctrine_Overloadable, IteratorAggregate
|
||||
class Doctrine_Db_Profiler extends Doctrine_Access implements Doctrine_Overloadable, IteratorAggregate, Countable
|
||||
{
|
||||
/**
|
||||
* @param array $listeners an array containing all availible listeners
|
||||
@ -109,11 +109,10 @@ class Doctrine_Db_Profiler extends Doctrine_Access implements Doctrine_Overloada
|
||||
*/
|
||||
if ( ! is_null($this->filterTypes)) {
|
||||
if ( ! ($a[0]->getQueryType() & $this->_filterTypes)) {
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
/**
|
||||
* get
|
||||
@ -148,6 +147,15 @@ class Doctrine_Db_Profiler extends Doctrine_Access implements Doctrine_Overloada
|
||||
{
|
||||
return new ArrayIterator($this->events);
|
||||
}
|
||||
/**
|
||||
* count
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->events);
|
||||
}
|
||||
/**
|
||||
* pop the last event from the event stack
|
||||
*
|
||||
|
@ -42,7 +42,13 @@ class Doctrine_Db_Statement implements Doctrine_Adapter_Statement_Interface
|
||||
$this->adapter = $adapter;
|
||||
$this->stmt = $stmt;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function getDbh()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
public function getQuery()
|
||||
{
|
||||
return $this->stmt->queryString;
|
||||
@ -62,9 +68,9 @@ class Doctrine_Db_Statement implements Doctrine_Adapter_Statement_Interface
|
||||
public function bindColumn($column, $param, $type = null)
|
||||
{
|
||||
if($type === null) {
|
||||
return $this->stmt->bindValue($column, $param);
|
||||
return $this->stmt->bindColumn($column, $param);
|
||||
} else {
|
||||
return $this->stmt->bindValue($column, $param, $type);
|
||||
return $this->stmt->bindColumn($column, $param, $type);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -187,9 +193,12 @@ class Doctrine_Db_Statement implements Doctrine_Adapter_Statement_Interface
|
||||
{
|
||||
$event = new Doctrine_Db_Event($this, Doctrine_Db_Event::EXECUTE, $this->stmt->queryString, $params);
|
||||
|
||||
$this->adapter->getListener()->onPreExecute($event);
|
||||
$skip = $this->adapter->getListener()->onPreExecute($event);
|
||||
|
||||
$this->stmt->execute($params);
|
||||
if ( ! $skip) {
|
||||
$this->stmt->execute($params);
|
||||
$this->adapter->incrementQueryCount();
|
||||
}
|
||||
|
||||
$this->adapter->getListener()->onExecute($event);
|
||||
|
||||
@ -242,11 +251,21 @@ class Doctrine_Db_Statement implements Doctrine_Adapter_Statement_Interface
|
||||
public function fetchAll($fetchStyle = Doctrine::FETCH_BOTH,
|
||||
$columnIndex = null)
|
||||
{
|
||||
if($columnIndex !== null) {
|
||||
return $this->stmt->fetchAll($fetchStyle, $columnIndex);
|
||||
} else {
|
||||
return $this->stmt->fetchAll($fetchStyle);
|
||||
$event = new Doctrine_Db_Event($this, Doctrine_Db_Event::FETCHALL, $this->stmt->queryString, array($fetchStyle, $columnIndex));
|
||||
|
||||
$data = $this->adapter->getListener()->onPreFetchAll($event);
|
||||
|
||||
if ($data === null) {
|
||||
if ($columnIndex !== null) {
|
||||
$data = $this->stmt->fetchAll($fetchStyle, $columnIndex);
|
||||
} else {
|
||||
$data = $this->stmt->fetchAll($fetchStyle);
|
||||
}
|
||||
}
|
||||
|
||||
$this->adapter->getListener()->onFetchAll($event);
|
||||
|
||||
return $data;
|
||||
}
|
||||
/**
|
||||
* fetchColumn
|
||||
|
@ -39,13 +39,48 @@ class Doctrine_Cache_TestCase extends Doctrine_UnitTestCase
|
||||
{ }
|
||||
public function prepareData()
|
||||
{ }
|
||||
|
||||
/**
|
||||
public function testAdapterQueryAddsQueriesToCacheStack()
|
||||
{
|
||||
$this->dbh->query('SELECT * FROM user');
|
||||
|
||||
$this->assertEqual($this->cache->getAll(), array('main' => array('SELECT * FROM user')));
|
||||
}
|
||||
*/
|
||||
public function testAdapterQueryChecksCache()
|
||||
{
|
||||
$query = 'SELECT * FROM user';
|
||||
|
||||
$resultSet = array(array('name' => 'John'), array('name' => 'Arnold'));
|
||||
|
||||
$this->cache->getDriver()->save(md5($query), $resultSet);
|
||||
|
||||
$count = $this->dbh->getAdapter()->count();
|
||||
|
||||
$stmt = $this->dbh->query($query);
|
||||
$data = $stmt->fetchAll(Doctrine::FETCH_ASSOC);
|
||||
|
||||
$this->assertEqual($data, $resultSet);
|
||||
$this->assertEqual($this->dbh->getAdapter()->count(), $count);
|
||||
}
|
||||
public function testAdapterStatementExecuteChecksCache()
|
||||
{
|
||||
$query = 'SELECT * FROM user WHERE id = ?';
|
||||
$params = array(1);
|
||||
$resultSet = array(array('name' => 'John'), array('name' => 'Arnold'));
|
||||
|
||||
$this->cache->getDriver()->save(md5(serialize(array($query, $params))), $resultSet);
|
||||
|
||||
$count = $this->dbh->getAdapter()->count();
|
||||
|
||||
$stmt = $this->dbh->prepare($query);
|
||||
$stmt->execute($params);
|
||||
$data = $stmt->fetchAll(Doctrine::FETCH_ASSOC);
|
||||
|
||||
$this->assertEqual($data, $resultSet);
|
||||
$this->assertEqual($this->dbh->getAdapter()->count(), $count);
|
||||
}
|
||||
/**
|
||||
public function testAdapterStatementExecuteAddsQueriesToCacheStack()
|
||||
{
|
||||
$stmt = $this->dbh->prepare('SELECT * FROM user');
|
||||
@ -54,13 +89,22 @@ class Doctrine_Cache_TestCase extends Doctrine_UnitTestCase
|
||||
|
||||
$this->assertEqual($this->cache->getAll(), array('main' => array('SELECT * FROM user')));
|
||||
}
|
||||
public function testAdapterStatementFetchCallsCacheFetch()
|
||||
{
|
||||
$stmt = $this->dbh->prepare('SELECT * FROM user');
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
$a = $stmt->fetchAll();
|
||||
}
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if ( ! isset($this->cache)) {
|
||||
$this->cache = new Doctrine_Cache('Array');
|
||||
|
||||
|
||||
$this->dbh->setAdapter(new Doctrine_Adapter_Mock());
|
||||
$this->dbh->addListener($this->cache);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ class Doctrine_UnitTestCase extends UnitTestCase {
|
||||
protected $old;
|
||||
protected $dbh;
|
||||
protected $listener;
|
||||
protected $cache;
|
||||
|
||||
protected $users;
|
||||
protected $valueHolder;
|
||||
protected $tables = array();
|
||||
|
@ -214,12 +214,12 @@ $test->addTestCase(new Doctrine_Query_JoinCondition_TestCase());
|
||||
$test->addTestCase(new Doctrine_ColumnAlias_TestCase());
|
||||
$test->addTestCase(new Doctrine_Query_Subquery_TestCase());
|
||||
$test->addTestCase(new Doctrine_Query_Orderby_TestCase());
|
||||
/**
|
||||
|
||||
$test->addTestCase(new Doctrine_Cache_TestCase());
|
||||
$test->addTestCase(new Doctrine_Cache_Apc_TestCase());
|
||||
$test->addTestCase(new Doctrine_Cache_Memcache_TestCase());
|
||||
$test->addTestCase(new Doctrine_Cache_Sqlite_TestCase());
|
||||
*/
|
||||
|
||||
// Cache tests
|
||||
//$test->addTestCase(new Doctrine_Cache_Query_SqliteTestCase());
|
||||
//$test->addTestCase(new Doctrine_Cache_FileTestCase());
|
||||
|
Loading…
x
Reference in New Issue
Block a user