]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge remote-tracking branch 'gitorious/1.0.x' into 1.0.x
authorEvan Prodromou <evan@status.net>
Fri, 19 Aug 2011 00:27:55 +0000 (17:27 -0700)
committerEvan Prodromou <evan@status.net>
Fri, 19 Aug 2011 00:27:55 +0000 (17:27 -0700)
classes/Fave.php
classes/Memcached_DataObject.php
classes/Notice.php
lib/noticelist.php
lib/threadednoticelist.php

index 5067185c0e427719ecc7f15645cd76c0f0417698..c69a6816d000a13c69bc9f9e990043a0c7cdf4fa 100644 (file)
@@ -44,7 +44,7 @@ class Fave extends Memcached_DataObject
                 common_log_db_error($fave, 'INSERT', __FILE__);
                 return false;
             }
-            self::blow('fave:list:notice_id:%d', $fave->notice_id);
+            self::blow('fave:list-ids:notice_id:%d', $fave->notice_id);
 
             Event::handle('EndFavorNotice', array($profile, $notice));
         }
@@ -62,7 +62,7 @@ class Fave extends Memcached_DataObject
         if (Event::handle('StartDisfavorNotice', array($profile, $notice, &$result))) {
 
             $result = parent::delete();
-            self::blow('fave:list:notice_id:%d', $this->notice_id);
+            self::blow('fave:list-ids:notice_id:%d', $this->notice_id);
 
             if ($result) {
                 Event::handle('EndDisfavorNotice', array($profile, $notice));
index e1610c56b214e34205c380dc1c187d2453c3c0a2..e515e3d9e0abd6c87e0fb71b880bd2492471e335 100644 (file)
@@ -105,23 +105,39 @@ class Memcached_DataObject extends Safe_DataObject
      */
     static function pivotGet($cls, $keyCol, $keyVals, $otherCols = array())
     {
-       $result = array_fill_keys($keyVals, null);
+        if (is_array($keyCol)) {
+            foreach ($keyVals as $keyVal) {
+                $result[implode(',', $keyVal)] = null;
+            }
+        } else {
+            $result = array_fill_keys($keyVals, null);
+        }
        
        $toFetch = array();
        
        foreach ($keyVals as $keyVal) {
-               
-               $kv = array_merge($otherCols, array($keyCol => $keyVal));
+
+            if (is_array($keyCol)) {
+                $kv = array_combine($keyCol, $keyVal);
+            } else {
+                $kv = array($keyCol => $keyVal);
+            }
+
+               $kv = array_merge($otherCols, $kv);
                
                $i = self::multicache($cls, $kv);
                
                if ($i !== false) {
-                       $result[$keyVal] = $i;
+                if (is_array($keyCol)) {
+                    $result[implode(',', $keyVal)] = $i;
+                } else {
+                    $result[$keyVal] = $i;
+                }
                } else if (!empty($keyVal)) {
                        $toFetch[] = $keyVal;
                }
        }
-       
+        
        if (count($toFetch) > 0) {
             $i = DB_DataObject::factory($cls);
             if (empty($i)) {
@@ -130,20 +146,43 @@ class Memcached_DataObject extends Safe_DataObject
             foreach ($otherCols as $otherKeyCol => $otherKeyVal) {
                 $i->$otherKeyCol = $otherKeyVal;
             }
-               $i->whereAddIn($keyCol, $toFetch, $i->columnType($keyCol));
+            if (is_array($keyCol)) {
+                $i->whereAdd(self::_inMultiKey($i, $keyCol, $toFetch));
+            } else {
+                $i->whereAddIn($keyCol, $toFetch, $i->columnType($keyCol));
+            }
                if ($i->find()) {
                        while ($i->fetch()) {
                                $copy = clone($i);
                                $copy->encache();
-                               $result[$i->$keyCol] = $copy;
+                    if (is_array($keyCol)) {
+                        $vals = array();
+                        foreach ($keyCol as $k) {
+                            $vals[] = $i->$k;
+                        }
+                        $result[implode(',', $vals)] = $copy;
+                    } else {
+                        $result[$i->$keyCol] = $copy;
+                    }
                        }
                }
                
                // Save state of DB misses
                
                foreach ($toFetch as $keyVal) {
-                       if (empty($result[$keyVal])) {
-                               $kv = array_merge($otherCols, array($keyCol => $keyVal));
+                $r = null;
+                if (is_array($keyCol)) {
+                    $r = $result[implode(',', $keyVal)];
+                } else {
+                    $r = $result[$keyVal];
+                }
+                       if (empty($r)) {
+                    if (is_array($keyCol)) {
+                        $kv = array_combine($keyCol, $keyVal);
+                    } else {
+                        $kv = array($keyCol => $keyVal);
+                    }
+                    $kv = array_merge($otherCols, $kv);
                        // save the fact that no such row exists
                        $c = self::memcache();
                        if (!empty($c)) {
@@ -153,45 +192,140 @@ class Memcached_DataObject extends Safe_DataObject
                        }
                }
        }
-       
+
        return $result;
     }
-    
+
+    static function _inMultiKey($i, $cols, $values)
+    {
+        $types = array();
+
+        foreach ($cols as $col) {
+            $types[$col] = $i->columnType($col);
+        }
+
+        $first = true;
+
+        $query = '';
+
+        foreach ($values as $value) {
+            if ($first) {
+                $query .= '( ';
+                $first = false;
+            } else {
+                $query .= ' OR ';
+            }
+            $query .= '( ';
+            $i = 0;
+            $firstc = true;
+            foreach ($cols as $col) {
+                if (!$firstc) {
+                    $query .= ' AND ';
+                } else {
+                    $firstc = false;
+                }
+                switch ($types[$col]) {
+                case 'string':
+                case 'datetime':
+                    $query .= sprintf("%s = %s", $col, $i->_quote($value[$i]));
+                    break;
+                default:
+                    $query .= sprintf("%s = %s", $col, $value[$i]);
+                    break;
+                }
+            }
+            $query .= ') ';
+        }
+
+        if (!$first) {
+            $query .= ' )';
+        }
+
+        return $query;
+    }
+
+    static function pkeyCols($cls)
+    {
+        $i = DB_DataObject::factory($cls);
+        if (empty($i)) {
+            throw new Exception(_('Cannot instantiate a ' . $cls));
+        }
+        $types = $i->keyTypes();
+        ksort($types);
+
+        $pkey = array();
+
+        foreach ($types as $key => $type) {
+            if ($type == 'K' || $type == 'N') {
+                $pkey[] = $key;
+            }
+        }
+
+        return $pkey;
+    }
+
     function listGet($cls, $keyCol, $keyVals)
     {
-       $result = array_fill_keys($keyVals, array());
-       
+       $pkeyMap = array_fill_keys($keyVals, array());
+        $result = array_fill_keys($keyVals, array());
+
+        $pkeyCols = self::pkeyCols($cls);
+
        $toFetch = array();
-       
+        $allPkeys = array();
+
+        // We only cache keys -- not objects!
+
        foreach ($keyVals as $keyVal) {
-           $l = self::cacheGet(sprintf("%s:list:%s:%s", $cls, $keyCol, $keyVal));
+           $l = self::cacheGet(sprintf("%s:list-ids:%s:%s", $cls, $keyCol, $keyVal));
            if ($l !== false) {
-               $result[$keyVal] = $l;
+               $pkeyMap[$keyVal] = $l;
+                foreach ($l as $pkey) {
+                    $allPkeys[] = $pkey;
+                }
            } else {
                $toFetch[] = $keyVal;
            }
        }
-        
+
+        if (count($allPkeys) > 0) {
+            $keyResults = self::pivotGet($cls, $pkeyCols, $allPkeys);
+
+            foreach ($pkeyMap as $keyVal => $pkeyList) {
+                foreach ($pkeyList as $pkeyVal) {
+                    $i = $keyResults[implode(',',$pkeyVal)];
+                    if (!empty($i)) {
+                        $result[$keyVal][] = $i;
+                    }
+                }
+            }
+        }
+
         if (count($toFetch) > 0) {
                $i = DB_DataObject::factory($cls);
                if (empty($i)) {
                        throw new Exception(_('Cannot instantiate class ' . $cls));
                }
-                       $i->whereAddIn($keyCol, $toFetch, $i->columnType($keyCol));
-                       if ($i->find()) {
-                               while ($i->fetch()) {
-                                       $copy = clone($i);
-                                       $copy->encache();
-                                       $result[$i->$keyCol][] = $copy;
-                               }
-                       }        
-               foreach ($toFetch as $keyVal)
-               {
-                       self::cacheSet(sprintf("%s:list:%s:%s", $cls, $keyCol, $keyVal),
-                                                  $result[$keyVal]);   
-               }      
+            $i->whereAddIn($keyCol, $toFetch, $i->columnType($keyCol));
+            if ($i->find()) {
+                sprintf("listGet() got {$i->N} results for class $cls key $keyCol");
+                while ($i->fetch()) {
+                    $copy = clone($i);
+                    $copy->encache();
+                    $result[$i->$keyCol][] = $copy;
+                    $pkeyVal = array();
+                    foreach ($pkeyCols as $pkeyCol) {
+                        $pkeyVal[] = $i->$pkeyCol;
+                    }
+                    $pkeyMap[$i->$keyCol][] = $pkeyVal;
+                }
+            }       
+               foreach ($toFetch as $keyVal) {
+                self::cacheSet(sprintf("%s:list-ids:%s:%s", $cls, $keyCol, $keyVal),
+                               $pkeyMap[$keyVal]);
+            }      
         }
-       
+
        return $result;        
     }
 
index d39aea6c225776d398e2e82b1eff7022a49fc10b..122c3c6299d2f5825d44d685c0e6ce9b5f6d1daf 100644 (file)
@@ -2547,7 +2547,7 @@ class Notice extends Memcached_DataObject
                }
     }
 
-    protected $_faves = -1;
+    protected $_faves;
 
     /**
      * All faves of this notice
@@ -2557,15 +2557,15 @@ class Notice extends Memcached_DataObject
 
     function getFaves()
     {
-        if ($this->_faves != -1) {
+        if (isset($this->_faves) && is_array($this->_faves)) {
             return $this->_faves;
         }
-        $faveMap = Memcached_DataObject::listGet('Fave', 'notice_id', array($noticeId));
-        $this->_faves = $faveMap[$noticeId];
+        $faveMap = Memcached_DataObject::listGet('Fave', 'notice_id', array($this->id));
+        $this->_faves = $faveMap[$this->id];
         return $this->_faves;
     }
 
-    function _setFaves($faves)
+    function _setFaves(&$faves)
     {
         $this->_faves = $faves;
     }
@@ -2574,6 +2574,14 @@ class Notice extends Memcached_DataObject
     {
         $ids = self::_idsOf($notices);
         $faveMap = Memcached_DataObject::listGet('Fave', 'notice_id', $ids);
+        $cnt = 0;
+        $faved = array();
+        foreach ($faveMap as $id => $faves) {
+            $cnt += count($faves);
+            if (count($faves) > 0) {
+                $faved[] = $id;
+            }
+        }
         foreach ($notices as $notice) {
             $notice->_setFaves($faveMap[$notice->id]);
         }
index 148f428edf0955420c58a7510b70c31ce1bf3def..7ec5be1c0ff169f9e86b9d8980846bfde66f7c7c 100644 (file)
@@ -143,6 +143,7 @@ class NoticeList extends Widget
        
        if (!empty($p)) {
                Memcached_DataObject::pivotGet('Fave', 'notice_id', $ids, array('user_id' => $p->id));
+               Memcached_DataObject::pivotGet('Notice', 'repeat_of', $ids, array('profile_id' => $p->id));
        }
     }
 }
index cf3c0b8943ab74ec523ed55512694bdd54be2d5c..6df4ed99df92dc94da5dcaa2c581a990e29f62dc 100644 (file)
@@ -80,7 +80,7 @@ class ThreadedNoticeList extends NoticeList
                $total = count($notices);
                $notices = array_slice($notices, 0, NOTICES_PER_PAGE);
                
-       self::prefill($notices);
+       self::prefill(self::_allNotices($notices));
        
         $conversations = array();
         
@@ -123,6 +123,21 @@ class ThreadedNoticeList extends NoticeList
         return $total;
     }
 
+    function _allNotices($notices)
+    {
+        $convId = array();
+        foreach ($notices as $notice) {
+            $convId[] = $notice->conversation;
+        }
+        $convId = array_unique($convId);
+        $allMap = Memcached_DataObject::listGet('Notice', 'conversation', $convId);
+        $allArray = array();
+        foreach ($allMap as $convId => $convNotices) {
+            $allArray = array_merge($allArray, $convNotices);
+        }
+        return $allArray;
+    }
+
     /**
      * returns a new list item for the current notice
      *