X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FMemcached_DataObject.php;h=be8137573d31530862a1e63f05bd63d605c89902;hb=e119362fde9eabb27d48c94a98624aeae68e436c;hp=5f71f716b3dd569f84ef557420b03517ecc7c2f9;hpb=96bcfa49816c3b99e518d233b6c114d0965b3439;p=quix0rs-gnu-social.git diff --git a/classes/Memcached_DataObject.php b/classes/Memcached_DataObject.php index 5f71f716b3..be8137573d 100644 --- a/classes/Memcached_DataObject.php +++ b/classes/Memcached_DataObject.php @@ -1,7 +1,7 @@ . */ -if (!defined('LACONICA')) { exit(1); } +if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; class Memcached_DataObject extends DB_DataObject { + /** + * Destructor to free global memory resources associated with + * this data object when it's unset or goes out of scope. + * DB_DataObject doesn't do this yet by itself. + */ + + function __destruct() + { + $this->free(); + if (method_exists('DB_DataObject', '__destruct')) { + parent::__destruct(); + } + } + + /** + * Wrapper for DB_DataObject's static lookup using memcached + * as backing instead of an in-process cache array. + * + * @param string $cls classname of object type to load + * @param mixed $k key field name, or value for primary key + * @param mixed $v key field value, or leave out for primary key lookup + * @return mixed Memcached_DataObject subtype or false + */ function &staticGet($cls, $k, $v=null) { if (is_null($v)) { @@ -39,6 +62,13 @@ class Memcached_DataObject extends DB_DataObject } else { $i = DB_DataObject::staticGet($cls, $k, $v); if ($i) { + // DB_DataObject's in-process lookup cache interferes with GC + // to cause massive memory leaks in long-running processes. + if (php_sapi_name() == 'cli') { + $i->_clear_cache(); + } + + // Now store it into the shared memcached, if present... $i->encache(); } return $i; @@ -93,6 +123,11 @@ class Memcached_DataObject extends DB_DataObject } static function cacheKey($cls, $k, $v) { + if (is_object($cls) || is_object($j) || is_object($v)) { + $e = new Exception(); + common_log(LOG_ERR, __METHOD__ . ' object in param: ' . + str_replace("\n", " ", $e->getTraceAsString())); + } return common_cache_key(strtolower($cls).':'.$k.':'.$v); } @@ -184,20 +219,20 @@ class Memcached_DataObject extends DB_DataObject require_once INSTALLDIR.'/lib/search_engines.php'; static $search_engine; if (!isset($search_engine)) { - $connected = false; - if (common_config('sphinx', 'enabled')) { - $search_engine = new SphinxSearch($this, $table); - $connected = $search_engine->is_connected(); - } - - // unable to connect to sphinx' search daemon - if (!$connected) { - if ('mysql' === common_config('db', 'type')) { + if (Event::handle('GetSearchEngine', array($this, $table, &$search_engine))) { + if ('mysql' === common_config('db', 'type')) { + $type = common_config('search', 'type'); + if ($type == 'like') { + $search_engine = new MySQLLikeSearch($this, $table); + } else if ($type == 'fulltext') { $search_engine = new MySQLSearch($this, $table); } else { - $search_engine = new PGSearch($this, $table); + throw new ServerException('Unknown search type: ' . $type); } + } else { + $search_engine = new PGSearch($this, $table); } + } } return $search_engine; } @@ -227,4 +262,94 @@ class Memcached_DataObject extends DB_DataObject $c->set($ckey, $cached, MEMCACHE_COMPRESSED, $expiry); return new ArrayWrapper($cached); } + + // We overload so that 'SET NAMES "utf8"' is called for + // each connection + + function _connect() + { + global $_DB_DATAOBJECT; + + $sum = $this->_getDbDsnMD5(); + + if (!empty($_DB_DATAOBJECT['CONNECTIONS'][$sum]) && + !PEAR::isError($_DB_DATAOBJECT['CONNECTIONS'][$sum])) { + $exists = true; + } else { + $exists = false; + } + + $result = parent::_connect(); + + if ($result && !$exists) { + $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; + if (common_config('db', 'type') == 'mysql' && + common_config('db', 'utf8')) { + $conn = $DB->connection; + if (!empty($conn)) { + if ($DB instanceof DB_mysqli) { + mysqli_set_charset($conn, 'utf8'); + } else if ($DB instanceof DB_mysql) { + mysql_set_charset('utf8', $conn); + } + } + } + } + + return $result; + } + + // XXX: largely cadged from DB_DataObject + + function _getDbDsnMD5() + { + if ($this->_database_dsn_md5) { + return $this->_database_dsn_md5; + } + + $dsn = $this->_getDbDsn(); + + if (is_string($dsn)) { + $sum = md5($dsn); + } else { + /// support array based dsn's + $sum = md5(serialize($dsn)); + } + + return $sum; + } + + function _getDbDsn() + { + global $_DB_DATAOBJECT; + + if (empty($_DB_DATAOBJECT['CONFIG'])) { + DB_DataObject::_loadConfig(); + } + + $options = &$_DB_DATAOBJECT['CONFIG']; + + // if the databse dsn dis defined in the object.. + + $dsn = isset($this->_database_dsn) ? $this->_database_dsn : null; + + if (!$dsn) { + + if (!$this->_database) { + $this->_database = isset($options["table_{$this->__table}"]) ? $options["table_{$this->__table}"] : null; + } + + if ($this->_database && !empty($options["database_{$this->_database}"])) { + $dsn = $options["database_{$this->_database}"]; + } else if (!empty($options['database'])) { + $dsn = $options['database']; + } + } + + if (!$dsn) { + throw new Exception("No database name / dsn found anywhere"); + } + + return $dsn; + } }