summaryrefslogtreecommitdiff
path: root/adodb-memcache.lib.inc.php
diff options
context:
space:
mode:
authorDamien Regad <dregad@mantisbt.org>2021-08-17 00:30:04 +0200
committerDamien Regad <dregad@mantisbt.org>2021-08-17 00:30:04 +0200
commit507466ef798b18a3a8830230cfcd51bb488513cf (patch)
tree8b6ddc09e077883e9b0567d9c3b1c5249884ea09 /adodb-memcache.lib.inc.php
parent20b01e83cb61b6b2460f64c7d1277c5f4cc28574 (diff)
downloadadodb-507466ef798b18a3a8830230cfcd51bb488513cf.tar.gz
adodb-507466ef798b18a3a8830230cfcd51bb488513cf.tar.bz2
adodb-507466ef798b18a3a8830230cfcd51bb488513cf.zip
Revert changes since Standardized file headers merge
The conflicts resolution applied when merging the Standardized file headers (commit e9dcce3df24912ad869d0193f0b419f2309101fc) was seriously messed up, actually overwriting a number of changes in the master branch. Rather than trying to go and fix things one by one which has a high risk of messing things further, it's easier to redo the merge from a clean slate, so this commit reverts the following: - "Merge branch 'hotfix/5.21' Standardized file headers", e9dcce3df24912ad869d0193f0b419f2309101fc - "Merge tag 'v5.21.1'", 5f437df3104159d5d659f60e31bef8d33c34995f - "Reset version to 5.22.0-dev" af9234a525c3255af051a330164486d73be4c63a - "Fix incorrect resolution of merge conflicts" a6733f61b0165b366c8d2c70d9af82edc3881951. - "Fix syntax error in toexport.inc.php" 20b01e83cb61b6b2460f64c7d1277c5f4cc28574. Fixes #751
Diffstat (limited to 'adodb-memcache.lib.inc.php')
-rw-r--r--adodb-memcache.lib.inc.php546
1 files changed, 388 insertions, 158 deletions
diff --git a/adodb-memcache.lib.inc.php b/adodb-memcache.lib.inc.php
index 7f110e74..be9be1b1 100644
--- a/adodb-memcache.lib.inc.php
+++ b/adodb-memcache.lib.inc.php
@@ -1,23 +1,4 @@
<?php
-/**
- * Memory caching.
- *
- * This file is part of ADOdb, a Database Abstraction Layer library for PHP.
- *
- * @package ADOdb
- * @link https://adodb.org Project's web site and documentation
- * @link https://github.com/ADOdb/ADOdb Source code and issue tracker
- *
- * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause
- * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option,
- * any later version. This means you can use it in proprietary products.
- * See the LICENSE.md file distributed with this source code for details.
- * @license BSD-3-Clause
- * @license LGPL-2.1-or-later
- *
- * @copyright 2000-2013 John Lim
- * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
- */
// security - hide paths
if (!defined('ADODB_DIR')) die();
@@ -26,183 +7,432 @@ global $ADODB_INCLUDED_MEMCACHE;
$ADODB_INCLUDED_MEMCACHE = 1;
global $ADODB_INCLUDED_CSV;
-if (empty($ADODB_INCLUDED_CSV)) include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
+if (empty($ADODB_INCLUDED_CSV))
+ include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
+/*
- class ADODB_Cache_MemCache {
- var $createdir = false; // create caching directory structure?
+ @version v5.22.0-dev Unreleased
+ @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
+ @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
+ Released under both BSD license and Lesser GPL library license.
+ Whenever there is any discrepancy between the two licenses,
+ the BSD license will take precedence. See License.txt.
+ Set tabs to 4 for best viewing.
- // $library will be populated with the proper library on connect
- // and is used later when there are differences in specific calls
- // between memcache and memcached
- var $library = false;
+ Latest version is available at https://adodb.org/
- //-----------------------------
- // memcache specific variables
- var $hosts; // array of hosts
- var $port = 11211;
- var $compress = false; // memcache compression with zlib
- var $_connected = false;
- var $_memcache = false;
+ Class instance is stored in $ADODB_CACHE
+*/
- function __construct(&$obj)
+class ADODB_Cache_MemCache
+{
+ /*
+ * Prevents parent class calling non-existant function
+ */
+ public $createdir = false;
+
+ /*
+ * populated with the proper library on connect
+ * and is used later when there are differences in specific calls
+ * between memcache and memcached
+ */
+ private $memCacheLibrary = false;
+
+ /*
+ * array of hosts
+ */
+ private $hosts;
+
+ /*
+ * Connection Port, uses default
+ */
+ private $port = 11211;
+
+ /*
+ * memcache compression with zlib
+ */
+ private $compress = false;
+
+ /*
+ * Array of options for memcached only
+ */
+ private $options = false;
+
+ /*
+ * Internal flag indicating successful connection
+ */
+ private $isConnected = false;
+
+ /*
+ * Handle for the Memcache library
+ */
+ private $memcacheLibrary = false;
+
+ /*
+ * New server feature controller lists available servers
+ */
+ private $serverControllers = array();
+
+ /*
+ * New server feature controller uses granular
+ * server controller
+ */
+ private $serverControllerTemplate = array(
+ 'host'=>'',
+ 'port'=>11211,
+ 'weight'=>0,
+ 'key'=>''
+ );
+
+
+ /*
+ * An integer index into the libraries
+ */
+ const MCLIB = 1;
+ const MCLIBD = 2;
+
+ /*
+ * Xrefs the library flag to the actual class name
+ */
+ private $libraries = array(
+ 1=>'Memcache',
+ 2=>'Memcached'
+ );
+
+ /*
+ * An indicator of which library we are using
+ */
+ private $libraryFlag;
+
+ /**
+ * constructor passes in a ADONewConnection Object
+ *
+ * @param $db ADONewConnection object
+ *
+ * @return obj
+ */
+ public function __construct(&$db)
+ {
+ $this->hosts = $db->memCacheHost;
+ $this->port = $db->memCachePort;
+ $this->compress = $db->memCacheCompress;
+ $this->options = $db->memCacheOptions;
+
+ }
+
+ /**
+ * implement as lazy connection. The connection only occurs on CacheExecute call
+ *
+ * @param string $err
+ *
+ * @return bool success of connecting to a server
+ */
+ public function connect(&$err)
+ {
+ /*
+ * do we have memcache or memcached? see the note
+ * at adodb.org on memcache
+ */
+ if (class_exists('Memcache'))
+ $this->libraryFlag = self::MCLIB;
+ elseif (class_exists('Memcached'))
+ $this->libraryFlag = self::MCLIB;
+ else
{
- $this->hosts = $obj->memCacheHost;
- $this->port = $obj->memCachePort;
- $this->compress = $obj->memCacheCompress;
+ $err = 'Neither the Memcache nor Memcached PECL extensions were found!';
+ return false;
}
-
- // implement as lazy connection. The connection only occurs on CacheExecute call
- function connect(&$err)
+
+ $usedLibrary = $this->libraries[$this->libraryFlag];
+
+ $this->memCacheLibrary = new $usedLibrary;
+ if (!$this->memcacheLibrary)
+ {
+ $err = 'Memcache library failed to initialize';
+ return false;
+ }
+
+ /*
+ * Convert simple compression flag for memcached
+ */
+ if ($this->libraryFlag == self::MCLIBD && $this->compress)
{
- // do we have memcache or memcached?
- if (class_exists('Memcache')) {
- $this->library='Memcache';
- $memcache = new MemCache;
- } elseif (class_exists('Memcached')) {
- $this->library='Memcached';
- $memcache = new MemCached;
- } else {
- $err = 'Neither the Memcache nor Memcached PECL extensions were found!';
+ /*
+ * Value of Memcached::OPT_COMPRESSION = 2;
+ */
+ $this->options[2] == 1;
+ }
+ /*
+ * Are there any options available for memcached
+ */
+ if ($this->libraryFlag == self::MCLIBD && count($this->options) > 0)
+ {
+ $optionSuccess = $this->memCacheLibrary->setOptions($this->options);
+ if (!$optionSuccess)
+ {
+ $err = 'Invalid option parameters passed to Memecached';
return false;
}
-
- if (!is_array($this->hosts)) $this->hosts = array($this->hosts);
-
- $failcnt = 0;
- foreach($this->hosts as $host) {
- if (!@$memcache->addServer($host,$this->port)) {
- $failcnt += 1;
- }
+ }
+
+ /*
+ * Have we passed a controller array
+ */
+ if (!is_array($this->hosts))
+ $this->hosts = array($this->hosts);
+
+ if (array_values($this->hosts) == $this->hosts)
+ {
+ /*
+ * Old way, convert to controller
+ */
+ foreach ($this->hosts as $ipAddress)
+ {
+ $connector = $this->serverControllerTemplate;
+
+ $connector['host'] = $ipAddress;
+ $connector['port'] = $this->port;
+
+ $this->serverControllers[] = $connector;
}
- if ($failcnt == sizeof($this->hosts)) {
- $err = 'Can\'t connect to any memcache server';
- return false;
+ }
+ else
+ {
+ /*
+ * New way, must validate port, etc
+ */
+ foreach ($this->hosts as $controller)
+ {
+ $connector = array_merge($this->serverControllerTemplate,$controller);
+ if ($this->libraryFlag == self::MCLIB)
+ {
+ /*
+ * Cannot use a key or weight in memcache, simply discard
+ */
+ $connector['key'] = '';
+ $connector['weight'] = 0;
+
+ }
+ else
+ $connector['weight'] = $connector['weight'] ? (int)$connector['weight']:0;
+
+ $this->serverControllers[] = $connector;
}
- $this->_connected = true;
- $this->_memcache = $memcache;
- return true;
}
- // returns true or false. true if successful save
- function writecache($filename, $contents, $debug, $secs2cache)
+ /*
+ * Checks for existing connections ( but only for memcached )
+ */
+ if ($this->libraryFlag == self::MCLIBD)
{
- if (!$this->_connected) {
- $err = '';
- if (!$this->connect($err) && $debug) ADOConnection::outp($err);
+ $existingServers = $memCache->getServerList();
+ if (is_array($existingServers))
+ {
+ /*
+ * Use the existing configuration
+ */
+ $this->isConnected = true;
+ $this->memcacheLibrary = $memcache;
+ return true;
}
- if (!$this->_memcache) return false;
-
- $failed=false;
- switch ($this->library) {
- case 'Memcache':
- if (!$this->_memcache->set($filename, $contents, $this->compress ? MEMCACHE_COMPRESSED : 0, $secs2cache)) {
- $failed=true;
- }
- break;
- case 'Memcached':
- if (!$this->_memcache->set($filename, $contents, $secs2cache)) {
- $failed=true;
- }
- break;
+ }
+ $failcnt = 0;
+ foreach($this->serverControllers as $controller)
+ {
+ switch($this->libraryFlag)
+ {
+ case self::MCLIB:
+ if (!@$this->memcacheLibrary->addServer($controller['host'],$controller['port']))
+ $failcnt++;
+ break;
default:
- $failed=true;
- break;
- }
-
- if($failed) {
- if ($debug) ADOConnection::outp(" Failed to save data at the memcache server!<br>\n");
- return false;
+ if (!@$this->memcacheLibrary->addServer($controller['host'],$controller['port'],$controller['weight']))
+ $failcnt++;
}
-
- return true;
+
}
-
- // returns a recordset
- function readcache($filename, &$err, $secs2cache, $rsClass)
+ if ($failcnt == sizeof($this->serverControllers))
{
- $false = false;
- if (!$this->_connected) $this->connect($err);
- if (!$this->_memcache) return $false;
+ $err = 'Can\'t connect to any memcache server';
+ return false;
- $rs = $this->_memcache->get($filename);
- if (!$rs) {
- $err = 'Item with such key doesn\'t exist on the memcache server.';
- return $false;
- }
+ }
+
+ /*
+ * A valid memcache connection is available
+ */
+ $this->isConnected = true;
+ return true;
+ }
- // hack, should actually use _csv2rs
- $rs = explode("\n", $rs);
- unset($rs[0]);
- $rs = join("\n", $rs);
- $rs = unserialize($rs);
- if (! is_object($rs)) {
- $err = 'Unable to unserialize $rs';
- return $false;
- }
- if ($rs->timeCreated == 0) return $rs; // apparently have been reports that timeCreated was set to 0 somewhere
+ /**
+ * Writes a cached query to the server
+ *
+ * @param string $filename The MD5 of the query to cache
+ * @param string $contents The query results
+ * @param bool $debug
+ * @param int $secs2cache
+ *
+ * @return bool true or false. true if successful save
+ */
+ public function writeCache($filename, $contents, $debug, $secs2cache)
+ {
+ $err = '';
+ if (!$this->isConnected && $debug)
+ {
+ /*
+ * Call to writecache before connect, try
+ * to connect
+ */
+ if (!$this->connect($err))
+ ADOConnection::outp($err);
+ }
+ else if (!$this->isConnected)
+ $this->connect($err);
+
+ if (!$this->memcacheLibrary)
+ return false;
- $tdiff = intval($rs->timeCreated+$secs2cache - time());
- if ($tdiff <= 2) {
- switch($tdiff) {
- case 2:
- if ((rand() & 15) == 0) {
- $err = "Timeout 2";
- return $false;
- }
- break;
- case 1:
- if ((rand() & 3) == 0) {
- $err = "Timeout 1";
- return $false;
- }
- break;
- default:
- $err = "Timeout 0";
- return $false;
+ $failed=false;
+ switch ($this->libraryFlag)
+ {
+ case self::MCLIB:
+ if (!$this->memcacheLibrary->set($filename, $contents, $this->compress ? MEMCACHE_COMPRESSED : 0, $secs2cache)) {
+ $failed=true;
}
- }
- return $rs;
+ break;
+ case self::MCLIBD:
+ if (!$this->memcacheLibrary->set($filename, $contents, $secs2cache)) {
+ $failed=true;
+ }
+ break;
+ default:
+ $failed=true;
+ break;
}
- function flushall($debug=false)
- {
- if (!$this->_connected) {
- $err = '';
- if (!$this->connect($err) && $debug) ADOConnection::outp($err);
- }
- if (!$this->_memcache) return false;
+ if($failed) {
+ if ($debug) ADOConnection::outp(" Failed to save data at the memcache server!<br>\n");
+ return false;
+ }
- $del = $this->_memcache->flush();
+ return true;
+ }
- if ($debug)
- if (!$del) ADOConnection::outp("flushall: failed!<br>\n");
- else ADOConnection::outp("flushall: succeeded!<br>\n");
+ /**
+ * Reads a cached query to the server
+ *
+ * @param string $filename The MD5 of the query to read
+ * @param string $err The query results
+ * @param int $secs2cache
+ * @param obj $rsClass **UNUSED**
+
+ * @return the record or false.
+ */
+ public function readCache($filename, &$err, $secs2cache, $rsClass)
+ {
+ if (!$this->isConnected) $this->connect($err);
+ if (!$this->memcacheLibrary)
+ return false;
- return $del;
+ $rs = $this->memcacheLibrary->get($filename);
+ if (!$rs)
+ {
+ $err = 'Item with such key doesn\'t exist on the memcache server.';
+ return false;
}
- function flushcache($filename, $debug=false)
+ // hack, should actually use _csv2rs
+ $rs = explode("\n", $rs);
+ unset($rs[0]);
+ $rs = join("\n", $rs);
+ $rs = unserialize($rs);
+ if (! is_object($rs)) {
+ $err = 'Unable to unserialize $rs';
+ return $false;
+ }
+ if ($rs->timeCreated == 0)
+ return $rs; // apparently have been reports that timeCreated was set to 0 somewhere
+
+ $tdiff = intval($rs->timeCreated+$secs2cache - time());
+ if ($tdiff <= 2)
{
- if (!$this->_connected) {
- $err = '';
- if (!$this->connect($err) && $debug) ADOConnection::outp($err);
+ switch($tdiff)
+ {
+ case 2:
+ if ((rand() & 15) == 0) {
+ $err = "Timeout 2";
+ return false;
+ }
+ break;
+ case 1:
+ if ((rand() & 3) == 0) {
+ $err = "Timeout 1";
+ return false;
+ }
+ break;
+ default:
+ $err = "Timeout 0";
+ return false;
}
- if (!$this->_memcache) return false;
+ }
+ return $rs;
+ }
- $del = $this->_memcache->delete($filename);
+ /**
+ * Flushes all of the stored memcache data
+ *
+ * @param bool $debug
+ *
+ * @return int The response from the memcache server
+ */
+ public function flushAll($debug=false)
+ {
+ if (!$this->isConnected) {
+ $err = '';
+ if (!$this->connect($err) && $debug) ADOConnection::outp($err);
+ }
+ if (!$this->memcacheLibrary)
+ return false;
- if ($debug)
- if (!$del) ADOConnection::outp("flushcache: $key entry doesn't exist on memcache server!<br>\n");
- else ADOConnection::outp("flushcache: $key entry flushed from memcache server!<br>\n");
+ $del = $this->memcacheLibrary->flush();
- return $del;
- }
+ if ($debug)
+ if (!$del)
+ ADOConnection::outp("flushall: failed!<br>\n");
+ else
+ ADOConnection::outp("flushall: succeeded!<br>\n");
+
+ return $del;
+ }
- // not used for memcache
- function createdir($dir, $hash)
+ /**
+ * Flushes the contents of a specified query
+ *
+ * @param str $filname The MD5 of the query to flush
+ * @param bool $debug
+ *
+ * @return int The response from the memcache server
+ */
+ public function flushCache($filename, $debug=false)
+ {
+ if (!$this->isConnected)
{
- return true;
+ $err = '';
+ if (!$this->connect($err) && $debug) ADOConnection::outp($err);
}
+ if (!$this->memcacheLibrary)
+ return false;
+
+ $del = $this->memcacheLibrary->delete($filename);
+
+ if ($debug)
+ if (!$del) ADOConnection::outp("flushcache: $key entry doesn't exist on memcache server!<br>\n");
+ else ADOConnection::outp("flushcache: $key entry flushed from memcache server!<br>\n");
+
+ return $del;
}
+
+}