]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
break up big inbox queries into lots of small ones
authorEvan Prodromou <evan@controlyourself.ca>
Fri, 26 Jun 2009 06:00:46 +0000 (23:00 -0700)
committerEvan Prodromou <evan@controlyourself.ca>
Fri, 26 Jun 2009 06:00:46 +0000 (23:00 -0700)
classes/Group_inbox.php
classes/Notice.php
classes/Notice_inbox.php
classes/Profile.php
classes/User.php
classes/User_group.php

index b80ba42729d8b84cfb0a9186584721406d6355d7..1af7439f7f749e668824773aa6363012e77e33f2 100644 (file)
@@ -14,8 +14,14 @@ class Group_inbox extends Memcached_DataObject
     public $created;                         // datetime()   not_null
 
     /* Static get */
+
     function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Group_inbox',$k,$v); }
 
     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
+
+    function &pkeyGet($kv)
+    {
+        return Memcached_DataObject::pkeyGet('Group_inbox', $kv);
+    }
 }
index 5bcfa896e07a0bc29a3e16069f1fbff2a99dfa66..fdcef1bc2ed6de3e17a82e505abe90b2aeb5eebf 100644 (file)
@@ -832,24 +832,60 @@ class Notice extends Memcached_DataObject
         $enabled = common_config('inboxes', 'enabled');
 
         if ($enabled === true || $enabled === 'transitional') {
-            $inbox = new Notice_inbox();
-            $UT = common_config('db','type')=='pgsql'?'"user"':'user';
-            $qry = 'INSERT INTO notice_inbox (user_id, notice_id, created) ' .
-              "SELECT $UT.id, " . $this->id . ", '" . $this->created . "' " .
-              "FROM $UT JOIN subscription ON $UT.id = subscription.subscriber " .
-              'WHERE subscription.subscribed = ' . $this->profile_id . ' ' .
-              'AND NOT EXISTS (SELECT user_id, notice_id ' .
-              'FROM notice_inbox ' .
-              "WHERE user_id = $UT.id " .
-              'AND notice_id = ' . $this->id . ' )';
-            if ($enabled === 'transitional') {
-                $qry .= " AND $UT.inboxed = 1";
+
+            $users = $this->getSubscribedUsers();
+
+            // FIXME: kind of ignoring 'transitional'...
+            // we'll probably stop supporting inboxless mode
+            // in 0.9.x
+
+            foreach ($users as $id) {
+                $this->addToUserInbox($id, NOTICE_INBOX_SOURCE_SUB);
             }
-            $inbox->query($qry);
         }
+
         return;
     }
 
+    function getSubscribedUsers()
+    {
+        $user = new User();
+
+        $qry =
+          'SELECT id ' .
+          'FROM user JOIN subscription '.
+          'ON user.id = subscription.subscriber ' .
+          'WHERE subscription.subscribed = %d ';
+
+        $user->query(sprintf($qry, $this->profile_id));
+
+        $ids = array();
+
+        while ($user->fetch()) {
+            $ids[] = $user->id;
+        }
+
+        $user->free();
+
+        return $ids;
+    }
+
+    function addToUserInbox($user_id, $source)
+    {
+        $inbox = Notice_inbox::pkeyGet(array('user_id' => $user_id,
+                                             'notice_id' => $this->id));
+        if (empty($inbox)) {
+            $inbox = new Notice_inbox();
+            $inbox->user_id   = $user_id;
+            $inbox->notice_id = $this->id;
+            $inbox->source    = $source;
+            $inbox->created   = $this->created;
+            return $inbox->insert();
+        }
+
+        return true;
+    }
+
     function saveGroups()
     {
         $enabled = common_config('inboxes', 'enabled');
@@ -888,13 +924,7 @@ class Notice extends Memcached_DataObject
 
             if ($profile->isMember($group)) {
 
-                $gi = new Group_inbox();
-
-                $gi->group_id  = $group->id;
-                $gi->notice_id = $this->id;
-                $gi->created   = common_sql_now();
-
-                $result = $gi->insert();
+                $result = $this->addToGroupInbox($group);
 
                 if (!$result) {
                     common_log_db_error($gi, 'INSERT', __FILE__);
@@ -902,27 +932,37 @@ class Notice extends Memcached_DataObject
 
                 // FIXME: do this in an offline daemon
 
-                $this->addToGroupInboxes($group);
+                $this->addToGroupMemberInboxes($group);
             }
         }
     }
 
-    function addToGroupInboxes($group)
+    function addToGroupInbox($group)
+    {
+        $gi = Group_inbox::pkeyGet(array('group_id' => $group->id,
+                                         'notice_id' => $this->id));
+
+        if (empty($gi)) {
+
+            $gi = new Group_inbox();
+
+            $gi->group_id  = $group->id;
+            $gi->notice_id = $this->id;
+            $gi->created   = $this->created;
+
+            return $gi->insert();
+        }
+
+        return true;
+    }
+
+    function addToGroupMemberInboxes($group)
     {
-        $inbox = new Notice_inbox();
-        $UT = common_config('db','type')=='pgsql'?'"user"':'user';
-        $qry = 'INSERT INTO notice_inbox (user_id, notice_id, created, source) ' .
-          "SELECT $UT.id, " . $this->id . ", '" . $this->created . "', " . NOTICE_INBOX_SOURCE_GROUP . " " .
-          "FROM $UT JOIN group_member ON $UT.id = group_member.profile_id " .
-          'WHERE group_member.group_id = ' . $group->id . ' ' .
-          'AND NOT EXISTS (SELECT user_id, notice_id ' .
-          'FROM notice_inbox ' .
-          "WHERE user_id = $UT.id " .
-          'AND notice_id = ' . $this->id . ' )';
-        if ($enabled === 'transitional') {
-            $qry .= " AND $UT.inboxed = 1";
-        }
-        $result = $inbox->query($qry);
+        $users = $group->getUserMembers();
+
+        foreach ($users as $id) {
+            $this->addToUserInbox($id, NOTICE_INBOX_SOURCE_GROUP);
+        }
     }
 
     function saveReplies()
index 4ca2e9ae3c6705bc53c58ca8bd8826f19131d7e7..940381f84cd1e258ba0a8563ea79bae62c6b4b8a 100644 (file)
@@ -27,6 +27,7 @@ define('INBOX_CACHE_WINDOW', 101);
 
 define('NOTICE_INBOX_SOURCE_SUB', 1);
 define('NOTICE_INBOX_SOURCE_GROUP', 2);
+define('NOTICE_INBOX_SOURCE_REPLY', 3);
 define('NOTICE_INBOX_SOURCE_GATEWAY', -1);
 
 class Notice_inbox extends Memcached_DataObject
index 6b27c80cb5528e549126e4b84294f142f0c54cfb..a0ed6b3ca349e0da83dc161a409893f821cdb8af 100644 (file)
@@ -289,4 +289,52 @@ class Profile extends Memcached_DataObject
             return Avatar::defaultImage($size);
         }
     }
+
+    function getSubscriptions($offset=0, $limit=null)
+    {
+        $qry =
+          'SELECT profile.* ' .
+          'FROM profile JOIN subscription ' .
+          'ON profile.id = subscription.subscribed ' .
+          'WHERE subscription.subscriber = %d ' .
+          'AND subscription.subscribed != subscription.subscriber ' .
+          'ORDER BY subscription.created DESC ';
+
+        if (common_config('db','type') == 'pgsql') {
+            $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
+        } else {
+            $qry .= ' LIMIT ' . $offset . ', ' . $limit;
+        }
+
+        $profile = new Profile();
+
+        $profile->query(sprintf($qry, $this->id));
+
+        return $profile;
+    }
+
+    function getSubscribers($offset=0, $limit=null)
+    {
+        $qry =
+          'SELECT profile.* ' .
+          'FROM profile JOIN subscription ' .
+          'ON profile.id = subscription.subscriber ' .
+          'WHERE subscription.subscribed = %d ' .
+          'AND subscription.subscribed != subscription.subscriber ' .
+          'ORDER BY subscription.created DESC ';
+
+        if ($offset) {
+            if (common_config('db','type') == 'pgsql') {
+                $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
+            } else {
+                $qry .= ' LIMIT ' . $offset . ', ' . $limit;
+            }
+        }
+
+        $profile = new Profile();
+
+        $cnt = $profile->query(sprintf($qry, $this->id));
+
+        return $profile;
+    }
 }
index a01a3106f294608458af4af3b1d878c1afb4612f..62a3f8a66e214835548ceec645e021587e54a1bd 100644 (file)
@@ -600,50 +600,16 @@ class User extends Memcached_DataObject
 
     function getSubscriptions($offset=0, $limit=null)
     {
-        $qry =
-          'SELECT profile.* ' .
-          'FROM profile JOIN subscription ' .
-          'ON profile.id = subscription.subscribed ' .
-          'WHERE subscription.subscriber = %d ' .
-          'AND subscription.subscribed != subscription.subscriber ' .
-          'ORDER BY subscription.created DESC ';
-
-        if (common_config('db','type') == 'pgsql') {
-            $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
-        } else {
-            $qry .= ' LIMIT ' . $offset . ', ' . $limit;
-        }
-
-        $profile = new Profile();
-
-        $profile->query(sprintf($qry, $this->id));
-
-        return $profile;
+        $profile = $this->getProfile();
+        assert(!empty($profile));
+        return $profile->getSubscriptions($offset, $limit);
     }
 
     function getSubscribers($offset=0, $limit=null)
     {
-        $qry =
-          'SELECT profile.* ' .
-          'FROM profile JOIN subscription ' .
-          'ON profile.id = subscription.subscriber ' .
-          'WHERE subscription.subscribed = %d ' .
-          'AND subscription.subscribed != subscription.subscriber ' .
-          'ORDER BY subscription.created DESC ';
-
-        if ($offset) {
-            if (common_config('db','type') == 'pgsql') {
-                $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
-            } else {
-                $qry .= ' LIMIT ' . $offset . ', ' . $limit;
-            }
-        }
-
-        $profile = new Profile();
-
-        $cnt = $profile->query(sprintf($qry, $this->id));
-
-        return $profile;
+        $profile = $this->getProfile();
+        assert(!empty($profile));
+        return $profile->getSubscribers($offset, $limit);
     }
 
     function getTaggedSubscribers($tag, $offset=0, $limit=null)
index 8a56b9e52b32e893cab4fd5f0c582abd2380330b..9b4b01ead7424f60ba7bae7db2df4152ee2ab335 100644 (file)
@@ -246,4 +246,28 @@ class User_group extends Memcached_DataObject
         return Design::staticGet('id', $this->design_id);
     }
 
+    function getUserMembers()
+    {
+        // XXX: cache this
+
+        $user = new User();
+
+        $qry =
+          'SELECT id ' .
+          'FROM user JOIN group_member '.
+          'ON user.id = group_member.profile_id ' .
+          'WHERE group_member.group_id = %d ';
+
+        $user->query(sprintf($qry, $this->id));
+
+        $ids = array();
+
+        while ($user->fetch()) {
+            $ids[] = $user->id;
+        }
+
+        $user->free();
+
+        return $ids;
+    }
 }