]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - classes/Memcached_DataObject.php
remove debugging statement in Memcached_DataObject::multiGet()
[quix0rs-gnu-social.git] / classes / Memcached_DataObject.php
index d50b4071d1eeaef3548dd992675498bd991fad31..ec36079c1c7a92a46b43fe69f4cbcbc9d1bcab5f 100644 (file)
@@ -34,7 +34,7 @@ class Memcached_DataObject extends Safe_DataObject
     {
         if (is_null($v)) {
             $v = $k;
-            # XXX: HACK!
+            // XXX: HACK!
             $i = new $cls;
             $keys = $i->keys();
             $k = $keys[0];
@@ -63,7 +63,116 @@ class Memcached_DataObject extends Safe_DataObject
         }
         return $i;
     }
+    
+    /**
+     * Get multiple items from the database by key
+     * 
+     * @param string  $cls       Class to fetch
+     * @param string  $keyCol    name of column for key
+     * @param array   $keyVals   key values to fetch
+     * @param boolean $skipNulls return only non-null results?
+     * 
+     * @return array Array of objects, in order
+     */
+    function multiGet($cls, $keyCol, $keyVals, $skipNulls=true)
+    {
+       $result = self::pivotGet($cls, $keyCol, $keyVals);
+       
+       $values = array_values($result);
+       
+       if ($skipNulls) {
+               $tmp = array();
+               foreach ($values as $value) {
+                       if (!empty($value)) {
+                               $tmp[] = $value;
+                       }
+               }
+               $values = $tmp;
+       }
+       
+       return new ArrayWrapper($values);
+    }
+    
+    /**
+     * Get multiple items from the database by key
+     * 
+     * @param string  $cls       Class to fetch
+     * @param string  $keyCol    name of column for key
+     * @param array   $keyVals   key values to fetch
+     * @param boolean $otherCols Other columns to hold fixed
+     * 
+     * @return array Array mapping $keyVals to objects, or null if not found
+     */
+    static function pivotGet($cls, $keyCol, $keyVals, $otherCols = array())
+    {
+       $result = array_fill_keys($keyVals, null);
+       
+       $toFetch = array();
+       
+       foreach ($keyVals as $keyVal) {
+               
+               $kv = array_merge($otherCols, array($keyCol => $keyVal));
+               
+               $i = self::multicache($cls, $kv);
+               
+               if ($i !== false) {
+                       $result[$keyVal] = $i;
+               } else if (!empty($keyVal)) {
+                       $toFetch[] = $keyVal;
+               }
+       }
+       
+       if (count($toFetch) > 0) {
+            $i = DB_DataObject::factory($cls);
+            if (empty($i)) {
+               throw new Exception(_('Cannot instantiate class ' . $cls));
+            }
+            foreach ($otherCols as $otherKeyCol => $otherKeyVal) {
+                $i->$otherKeyCol = $otherKeyVal;
+            }
+               $i->whereAddIn($keyCol, $toFetch, $i->columnType($keyCol));
+               if ($i->find()) {
+                       while ($i->fetch()) {
+                               $copy = clone($i);
+                               $copy->encache();
+                               $result[$i->$keyCol] = $copy;
+                       }
+               }
+               
+               // Save state of DB misses
+               
+               foreach ($toFetch as $keyVal) {
+                       if (empty($result[$keyVal])) {
+                               $kv = array_merge($otherCols, array($keyCol => $keyVal));
+                       // save the fact that no such row exists
+                       $c = self::memcache();
+                       if (!empty($c)) {
+                       $ck = self::multicacheKey($cls, $keyCol, $keyVal);
+                       $c->set($ck, null);
+                       }       
+                       }
+               }
+       }
+       
+       return $result;
+    }
 
+       function columnType($columnName)
+       {
+               $keys = $this->table();
+               if (!array_key_exists($columnName, $keys)) {
+                       throw new Exception('Unknown key column ' . $columnName . ' in ' . join(',', array_keys($keys)));
+               }
+               
+               $def = $keys[$columnName];
+               
+               if ($def & DB_DATAOBJECT_INT) {
+                       return 'integer';
+               } else {
+                       return 'string';
+               }
+       }
+       
     /**
      * @fixme Should this return false on lookup fail to match staticGet?
      */
@@ -78,7 +187,13 @@ class Memcached_DataObject extends Safe_DataObject
                 return false;
             }
             foreach ($kv as $k => $v) {
-                $i->$k = $v;
+               if (is_null($v)) {
+                       // XXX: possible SQL injection...? Don't 
+                       // pass keys from the browser, eh.
+                       $i->whereAdd("$k is null");
+               } else {
+                       $i->$k = $v;
+               }
             }
             if ($i->find(true)) {
                 $i->encache();
@@ -124,7 +239,7 @@ class Memcached_DataObject extends Safe_DataObject
     }
 
     static function memcache() {
-        return common_memcache();
+        return Cache::instance();
     }
 
     static function cacheKey($cls, $k, $v) {
@@ -134,7 +249,7 @@ class Memcached_DataObject extends Safe_DataObject
                 str_replace("\n", " ", $e->getTraceAsString()));
         }
         $vstr = self::valueString($v);
-        return common_cache_key(strtolower($cls).':'.$k.':'.$vstr);
+        return Cache::key(strtolower($cls).':'.$k.':'.$vstr);
     }
 
     static function getcached($cls, $k, $v) {
@@ -273,24 +388,23 @@ class Memcached_DataObject extends Safe_DataObject
     function getSearchEngine($table)
     {
         require_once INSTALLDIR.'/lib/search_engines.php';
-        static $search_engine;
-        if (!isset($search_engine)) {
-            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 {
-                        // Low level exception. No need for i18n as discussed with Brion.
-                        throw new ServerException('Unknown search type: ' . $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);
+                    // Low level exception. No need for i18n as discussed with Brion.
+                    throw new ServerException('Unknown search type: ' . $type);
                 }
+            } else {
+                $search_engine = new PGSearch($this, $table);
             }
         }
+
         return $search_engine;
     }
 
@@ -302,8 +416,8 @@ class Memcached_DataObject extends Safe_DataObject
             $inst->query($qry);
             return $inst;
         }
-        $key_part = common_keyize($cls).':'.md5($qry);
-        $ckey = common_cache_key($key_part);
+        $key_part = Cache::keyize($cls).':'.md5($qry);
+        $ckey = Cache::key($key_part);
         $stored = $c->get($ckey);
 
         if ($stored !== false) {
@@ -338,9 +452,15 @@ class Memcached_DataObject extends Safe_DataObject
         }
 
         $start = microtime(true);
+        $fail = false;
         $result = null;
         if (Event::handle('StartDBQuery', array($this, $string, &$result))) {
-            $result = parent::_query($string);
+            common_perf_counter('query', $string);
+            try {
+                $result = parent::_query($string);
+            } catch (Exception $e) {
+                $fail = $e;
+            }
             Event::handle('EndDBQuery', array($this, $string, &$result));
         }
         $delta = microtime(true) - $start;
@@ -348,7 +468,16 @@ class Memcached_DataObject extends Safe_DataObject
         $limit = common_config('db', 'log_slow_queries');
         if (($limit > 0 && $delta >= $limit) || common_config('db', 'log_queries')) {
             $clean = $this->sanitizeQuery($string);
-            common_log(LOG_DEBUG, sprintf("DB query (%0.3fs): %s", $delta, $clean));
+            if ($fail) {
+                $msg = sprintf("FAILED DB query (%0.3fs): %s - %s", $delta, $fail->getMessage(), $clean);
+            } else {
+                $msg = sprintf("DB query (%0.3fs): %s", $delta, $clean);
+            }
+            common_log(LOG_DEBUG, $msg);
+        }
+
+        if ($fail) {
+            throw $fail;
         }
         return $result;
     }
@@ -480,6 +609,10 @@ class Memcached_DataObject extends Safe_DataObject
                     }
                 }
             }
+            // Needed to make timestamp values usefully comparable.
+            if (common_config('db', 'type') == 'mysql') {
+                parent::_query("set time_zone='+0:00'");
+            }
         }
 
         return $result;
@@ -554,7 +687,7 @@ class Memcached_DataObject extends Safe_DataObject
 
         $keyPart = vsprintf($format, $args);
 
-        $cacheKey = common_cache_key($keyPart);
+        $cacheKey = Cache::key($keyPart);
 
         return $c->delete($cacheKey);
     }
@@ -596,7 +729,7 @@ class Memcached_DataObject extends Safe_DataObject
             return false;
         }
 
-        $cacheKey = common_cache_key($keyPart);
+        $cacheKey = Cache::key($keyPart);
 
         return $c->get($cacheKey);
     }
@@ -609,7 +742,7 @@ class Memcached_DataObject extends Safe_DataObject
             return false;
         }
 
-        $cacheKey = common_cache_key($keyPart);
+        $cacheKey = Cache::key($keyPart);
 
         return $c->set($cacheKey, $value, $flag, $expiry);
     }