Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: gabordemooij/redbean
...
head fork: gabordemooij/redbean
  • 4 commits
  • 5 files changed
  • 0 commit comments
  • 1 contributor
View
199 RedBean/Plugin/Cache.php
@@ -0,0 +1,199 @@
+<?php
+/**
+ * RedBeanPHP Cache Plugin
+ *
+ * @file RedBean/Plugin/Cache.php
+ * @description Cache plugin, caches beans.
+ *
+ * @author Gabor de Mooij and the RedBeanPHP community
+ * @license BSD/GPLv2
+ *
+ * Provides a means to cache beans after loading or batch loading.
+ * Any other action will flush the cache unless keepCache() has been
+ * called.
+ *
+ * copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
+ * This source file is subject to the BSD/GPLv2 License that is bundled
+ * with this source code in the file license.txt.
+ */
+
+class RedBean_Plugin_Cache extends RedBean_OODB implements RedBean_Observer {
+
+ /**
+ * Bean cache, contains the cached beans identified by
+ * label keys containing the type id and the fetch method;
+ * i.e. single load or batch load.
+ *
+ * @var array
+ */
+ private $cache = array();
+
+ /**
+ * Flag, indicating the current cache handling mode.
+ * TRUE means to flush the cache after the next SQL query,
+ * FALSE means keep the cache whatever happens.
+ * By default the flag is set to TRUE to avoid caching issues.
+ *
+ * @var boolean
+ */
+ private $flushCache = true;
+
+ /**
+ * Number of hits (beans/calls being served from cache).
+ * Can be used to monitor cache performance.
+ *
+ * @var integer
+ */
+ private $hits = 0;
+
+ /**
+ * Number of misses (beans not being served from cache), can be
+ * used to monitor cache performance.
+ *
+ * @var integer
+ */
+ private $misses = 0;
+
+ /**
+ * Constructor.
+ * Cache decorates RedBeanPHP OODB class, so needs a writer.
+ *
+ * @param RedBean_QueryWriter $writer
+ */
+ public function __construct(RedBean_QueryWriter $writer) {
+ parent::__construct($writer);
+ }
+
+ /**
+ * In order for the cache to work properly you need to attach
+ * a listener to the database adapter. This enables the cache to be flushed
+ * whenever a possible destructive SQL query gets executed.
+ *
+ * @param RedBean_Adapter $adapter
+ */
+ public function addListener(RedBean_Adapter $adapter) {
+ $adapter->addEventListener('sql_exec',$this);
+ }
+
+ /**
+ * Loads a bean by type and id. If the bean cannot be found an
+ * empty bean will be returned instead. This is a cached version
+ * of the loader, if the bean has been cached it will be served
+ * from cache, otherwise the bean will be retrieved from the database
+ * as usual an a new cache entry will be added..
+ *
+ * @param string $type type of bean you are looking for
+ * @param integer $id identifier of the bean
+ *
+ * @return RedBean_OODBBean $bean the bean object found
+ */
+ public function load($type,$id) {
+ $this->flushCache = false;
+ $label = $type.'-'.$id;
+ if (isset($this->cache[$label])) {
+ $this->hits ++;
+ $bean = $this->cache[$label];
+ }
+ else {
+ $this->misses ++;
+ $bean = parent::load($type,$id);
+ $this->cache[$label] = $bean;
+ }
+ $this->flushCache = true;
+ return $bean;
+
+ }
+
+ /**
+ * Loads a batch of beans from the database. Loads beans by type and id
+ * collection. If the beans are in the cache they will be served from cache.
+ *
+ * @param string $type type of bean you are looking for
+ * @param array $ids list of identifiers to look for
+ *
+ * @return array $beans beans
+ */
+ public function batch($type,$ids) {
+ $this->flushCache = false;
+ $label = 'batch-'.$type.'-'.implode(',',$ids);
+ if (isset($this->cache[$label])) {
+ $this->hits ++;
+ $beans = $this->cache[$label];
+ }
+ else {
+ $beans = parent::batch($type,$ids);
+ $this->misses ++;
+ $this->cache[$label] = $beans;
+ }
+ $this->flushCache = true;
+ return $beans;
+ }
+
+ /**
+ * Instructs cache to not flush the cache after the
+ * upcoming SQL queries.
+ */
+ public function keepCache() {
+ $this->flushCache = false;
+ }
+
+ /**
+ * Instructs the cache to flush itself after the next SQL
+ * Query and flushes the cache directly as well.
+ */
+ public function flushCache() {
+ $this->cache = array();
+ $this->flushCache = true;
+ }
+
+ /**
+ * Event handler.
+ * If an SQL query is executed and the flush-cache flag has been set
+ * the cache will be flushed.
+ *
+ * @param string $eventname identifier string of the event
+ * @param mixed $bean info
+ */
+ public function onEvent($eventname, $bean) {
+ if ($eventname=='sql_exec') {
+ if ($this->flushCache) $this->cache = array();
+ }
+ }
+
+ /**
+ * Returns the number of hits. If a call to load() or
+ * batch() can use the cache this counts as a hit.
+ * Otherwise it's a miss.
+ *
+ * @return integer
+ */
+ public function getHits() {
+ return $this->hits;
+ }
+
+ /**
+ * Returns the number of hits. If a call to load() or
+ * batch() can use the cache this counts as a hit.
+ * Otherwise it's a miss.
+ *
+ * @return integer
+ */
+ public function getMisses() {
+ return $this->misses;
+ }
+
+ /**
+ * Resets hits counter to 0.
+ */
+ public function resetHits() {
+ $this->hits = 0;
+ }
+
+ /**
+ * Resets misses counter to 0.
+ */
+ public function resetMisses() {
+ $this->misses = 0;
+ }
+
+}
View
2  RedBean/QueryWriter/CUBRID.php
@@ -414,7 +414,7 @@ public function addIndex($type, $name, $column) {
$table = $this->safeTable($table);
$name = preg_replace('/\W/','',$name);
$column = $this->safeColumn($column);
- $index = $this->adapter->get("SELECT 1 as `exists` FROM db_index WHERE index_name = ? ",array($name));
+ $index = $this->adapter->getRow("SELECT 1 as `exists` FROM db_index WHERE index_name = ? ",array($name));
if ($index && $index['exists']) return; // positive number will return, 0 will continue.
try{ $this->adapter->exec("CREATE INDEX $name ON $table ($column) "); }catch(Exception $e){}
}
View
97 testing/RedUNIT/Plugin/Cache.php
@@ -0,0 +1,97 @@
+<?php
+
+require_once('../../RedBean/Plugin/Cache.php');
+
+/**
+ * RedUNIT_Plugin_Cache
+ * @file RedUNIT/Plugin/Cache.php
+ * @description Tests caching plugin.
+ *
+ * @author Gabor de Mooij
+ * @license BSD
+ *
+ *
+ * (c) G.J.G.T. (Gabor) de Mooij
+ * This source file is subject to the BSD/GPLv2 License that is bundled
+ * with this source code in the file license.txt.
+ */
+class RedUNIT_Plugin_Cache extends RedUNIT {
+
+
+ /**
+ * What drivers should be loaded for this test pack?
+ */
+ public function getTargetDrivers() {
+ return array('sqlite');
+ }
+
+ public function run() {
+
+ R::nuke();
+ R::$redbean = new RedBean_Plugin_Cache(R::$writer);
+ $cachedOODB = R::$redbean;
+ $cachedOODB->addListener(R::$adapter);
+
+
+ $p = R::dispense('person');
+ $p->name = 'Tom';
+ $id = R::store($p);
+ $p = R::load('person',$id);
+ asrt($cachedOODB->getHits(),0);
+ asrt($cachedOODB->getMisses(),1);
+ asrt($p->name,'Tom');
+ $p = R::load('person',$id);
+ asrt($cachedOODB->getHits(),1);
+ asrt($cachedOODB->getMisses(),1);
+ asrt($p->name,'Tom');
+ $p = R::load('person',$id);
+ asrt($cachedOODB->getHits(),2);
+ asrt($cachedOODB->getMisses(),1);
+ asrt($p->name,'Tom');
+ $cachedOODB->flushCache();
+ $p = R::load('person',$id);
+ asrt($cachedOODB->getHits(),2);
+ asrt($cachedOODB->getMisses(),2);
+ asrt($p->name,'Tom');
+
+ $pizzas = R::dispense('pizza',4);
+ $pizzas[0]->name = 'Funghi';
+ $pizzas[1]->name = 'Quattro Fromaggi';
+ $pizzas[2]->name = 'Tonno';
+ $pizzas[3]->name = 'Caprese';
+ R::storeAll($pizzas);
+ $ids = array($pizzas[0]->id,$pizzas[1]->id,$pizzas[2]->id,$pizzas[3]->id);
+ $pizzas = R::findAll('pizza');
+ $cachedOODB->resetHits();
+ $cachedOODB->resetMisses();
+ asrt($cachedOODB->getHits(),0);
+ asrt($cachedOODB->getMisses(),0);
+ $pizzas = R::batch('pizza',$ids);
+ asrt($cachedOODB->getHits(),4);
+ asrt($cachedOODB->getMisses(),1);
+ $pizzas = R::batch('pizza',$ids);
+ asrt($cachedOODB->getHits(),5);
+ asrt($cachedOODB->getMisses(),1);
+ $id = array_pop($ids);
+ $pizza = R::load('pizza',$id);
+ asrt($cachedOODB->getHits(),6);
+ asrt($cachedOODB->getMisses(),1);
+ R::trash($pizza); //flushes cache
+ $pizzas = R::batch('pizza',$ids);
+ asrt($cachedOODB->getHits(),6);
+ asrt($cachedOODB->getMisses(),5);
+ $pizzas = R::batch('pizza',$ids);
+ asrt($cachedOODB->getHits(),7);
+ asrt($cachedOODB->getMisses(),5);
+ $p = end($pizzas);
+ $p->price = 7.00;
+ $cachedOODB->keepCache();
+ R::store($p);
+ $pizzas = R::batch('pizza',$ids);
+ asrt($cachedOODB->getHits(),8);
+ asrt($cachedOODB->getMisses(),5);
+
+
+ }
+
+}
View
15 testing/cli/phpcoverage.inc.php
@@ -0,0 +1,15 @@
+<?php
+
+$PHPCOVERAGE_REPORT_DIR = false;
+$PHPCOVERAGE_HOME = false;
+global $PHPCOVERAGE_REPORT_DIR;
+global $PHPCOVERAGE_HOME;
+
+$PHPCOVERAGE_HOME = '../phpcoverage/src';
+
+$include_path = get_include_path();
+set_include_path($PHPCOVERAGE_HOME. PATH_SEPARATOR . $include_path);
+define('PHPCOVERAGE_HOME', $PHPCOVERAGE_HOME);
+
+
+
View
11 testing/helpers/selector.php
@@ -39,6 +39,7 @@
if (isset($ini['mysql'])) {
$dsn = "mysql:host={$ini['mysql']['host']};dbname={$ini['mysql']['schema']}";
R::addDatabase('mysql',$dsn,$ini['mysql']['user'],$ini['mysql']['pass'],false);
+
}
if (isset($ini['pgsql'])) {
$dsn="pgsql:host={$ini['pgsql']['host']};dbname={$ini['pgsql']['schema']}";
@@ -140,10 +141,20 @@ function activate_driver($d) {
'Base/Close'
);
+$pluginPacks = array(
+ 'Plugin/Cache'
+);
+
//Default (mode == all)
if ($mode == 'all') {
$packList = $allPacks;
}
+elseif ($mode == 'plugins') {
+ $packList = $pluginPacks;
+}
+elseif ($mode == 'all+plugins') {
+ $packList = array_merge($allPacks,$pluginPacks);
+}
else {
foreach($allPacks as $pack) {
if (strpos($pack,$mode)===0) $packList[] = $pack;

No commit comments for this range

Something went wrong with that request. Please try again.