X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FMemcached_DataObject.php;h=ea070ec849678c9570377fd2ff9b6a51cca59003;hb=4d05afae302f1870af369a713ab7ed291c821165;hp=12e55af21f25c0bebd28a013288ebb729f8a6b7b;hpb=156207d58d41066bb43826d9e038c8ff44c9195f;p=quix0rs-gnu-social.git diff --git a/classes/Memcached_DataObject.php b/classes/Memcached_DataObject.php index 12e55af21f..ea070ec849 100644 --- a/classes/Memcached_DataObject.php +++ b/classes/Memcached_DataObject.php @@ -1,7 +1,7 @@ encache(); - } - return $i; - } - } - - function insert() { - $result = parent::insert(); - if ($result) { - $this->encache(); - } - return $result; - } - - function update($orig=NULL) { - if (!is_null($orig)) { - $orig->decache(); # might be different keys - } - $result = parent::update($orig); - if ($result) { - $this->encache(); - } - } - - function delete() { - $this->decache(); # while we still have the values! - return parent::delete(); - } - - static function memcache() { - if (!common_config('memcached', 'enabled')) { - return NULL; - } else { - $cache = new Memcache(); - $res = $cache->connect(common_config('memcached', 'server'), - common_config('memcached', 'port')); - return ($res) ? $cache : NULL; - } - } - - static function cacheKey($cls, $k, $v) { - return common_cache_key(strtolower($cls) . ':' . - $k . ':' . - $v); - } - - static function getcached($cls, $k, $v) { - $c = Memcached_DataObject::memcache(); - if (!$c) { - return false; - } else { - return $c->get(Memcached_DataObject::cacheKey($cls, $k, $v)); - } - } - - function keyTypes() { - global $_DB_DATAOBJECT; + function &staticGet($cls, $k, $v=null) + { + if (is_null($v)) { + $v = $k; + # XXX: HACK! + $i = new $cls; + $keys = $i->keys(); + $k = $keys[0]; + unset($i); + } + $i = Memcached_DataObject::getcached($cls, $k, $v); + if ($i) { + return $i; + } else { + $i = DB_DataObject::staticGet($cls, $k, $v); + if ($i) { + $i->encache(); + } + return $i; + } + } + + function &pkeyGet($cls, $kv) + { + $i = Memcached_DataObject::multicache($cls, $kv); + if ($i) { + return $i; + } else { + $i = new $cls(); + foreach ($kv as $k => $v) { + $i->$k = $v; + } + if ($i->find(true)) { + $i->encache(); + } else { + $i = null; + } + return $i; + } + } + + function insert() + { + $result = parent::insert(); + return $result; + } + + function update($orig=null) + { + if (is_object($orig) && $orig instanceof Memcached_DataObject) { + $orig->decache(); # might be different keys + } + $result = parent::update($orig); + if ($result) { + $this->encache(); + } + return $result; + } + + function delete() + { + $this->decache(); # while we still have the values! + return parent::delete(); + } + + static function memcache() { + return common_memcache(); + } + + static function cacheKey($cls, $k, $v) { + return common_cache_key(strtolower($cls).':'.$k.':'.$v); + } + + static function getcached($cls, $k, $v) { + $c = Memcached_DataObject::memcache(); + if (!$c) { + return false; + } else { + return $c->get(Memcached_DataObject::cacheKey($cls, $k, $v)); + } + } + + function keyTypes() + { + global $_DB_DATAOBJECT; if (!isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"])) { - $this->databaseStructure(); - - } - return $_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"]; - } - - function encache() { - $c = $this->memcache(); - if (!$c) { - return false; - } else { - $primary = array(); - $types = ksort($this->keyTypes()); - foreach ($types as $key => $type) { - if ($type == 'K') { - $primary[] = $key; - } else { - $c->set($this->cacheKey($this->tableName(), $key, $this->$key), - $this); - } - } - # XXX: figure out what to do with compound pkeys - if (count($primary) == 1) { - $key = $primary[0]; - $c->set($this->cacheKey($this->tableName(), $key, $this->$key), - $this); - } - } - } - - function decache() { - $c = $this->memcache(); - if (!$c) { - return false; - } else { - $primary = array(); - $types = ksort($this->keyTypes()); - foreach ($types as $key => $type) { - if ($type == 'K') { - $primary[] = $this->$key; - } else { - $c->delete($this->cacheKey($this->tableName(), $key, $this->$key), - $this); - } - } - # XXX: figure out what to do with compound pkeys - if (count($primary) == 1) { - $key = $primary[0]; - $c->delete($this->cacheKey($this->tableName(), $key, $this->$key), - $this); - } - } - } + $this->databaseStructure(); + + } + return $_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"]; + } + + function encache() + { + $c = $this->memcache(); + if (!$c) { + return false; + } else { + $pkey = array(); + $pval = array(); + $types = $this->keyTypes(); + ksort($types); + foreach ($types as $key => $type) { + if ($type == 'K') { + $pkey[] = $key; + $pval[] = $this->$key; + } else { + $c->set($this->cacheKey($this->tableName(), $key, $this->$key), $this); + } + } + # XXX: should work for both compound and scalar pkeys + $pvals = implode(',', $pval); + $pkeys = implode(',', $pkey); + $c->set($this->cacheKey($this->tableName(), $pkeys, $pvals), $this); + } + } + + function decache() + { + $c = $this->memcache(); + if (!$c) { + return false; + } else { + $pkey = array(); + $pval = array(); + $types = $this->keyTypes(); + ksort($types); + foreach ($types as $key => $type) { + if ($type == 'K') { + $pkey[] = $key; + $pval[] = $this->$key; + } else { + $c->delete($this->cacheKey($this->tableName(), $key, $this->$key)); + } + } + # should work for both compound and scalar pkeys + # XXX: comma works for now but may not be safe separator for future keys + $pvals = implode(',', $pval); + $pkeys = implode(',', $pkey); + $c->delete($this->cacheKey($this->tableName(), $pkeys, $pvals)); + } + } + + function multicache($cls, $kv) + { + ksort($kv); + $c = Memcached_DataObject::memcache(); + if (!$c) { + return false; + } else { + $pkeys = implode(',', array_keys($kv)); + $pvals = implode(',', array_values($kv)); + return $c->get(Memcached_DataObject::cacheKey($cls, $pkeys, $pvals)); + } + } + + function getSearchEngine($table) + { + 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')) { + $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 { + throw new ServerException('Unknown search type: ' . $type); + } + } else { + $search_engine = new PGSearch($this, $table); + } + } + } + return $search_engine; + } + + static function cachedQuery($cls, $qry, $expiry=3600) + { + $c = Memcached_DataObject::memcache(); + if (!$c) { + $inst = new $cls(); + $inst->query($qry); + return $inst; + } + $key_part = common_keyize($cls).':'.md5($qry); + $ckey = common_cache_key($key_part); + $stored = $c->get($ckey); + if ($stored) { + return new ArrayWrapper($stored); + } + + $inst = new $cls(); + $inst->query($qry); + $cached = array(); + while ($inst->fetch()) { + $cached[] = clone($inst); + } + $inst->free(); + $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; + } }