+ $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')) {
+ $search_engine = new MySQLSearch($this, $table);
+ } 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