? css
? favicon.ico
? files
? i148849.patch
? img
? index.html
? test
? modules/node/node.install
? sites/default/settings.php
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.561
diff -u -r1.561 comment.module
--- modules/comment/comment.module	2 Jul 2007 14:41:35 -0000	1.561
+++ modules/comment/comment.module	4 Jul 2007 08:09:08 -0000
@@ -292,8 +292,7 @@
 /**
  * Find a number of recent comments. This is done in two steps.
  *   1. Find the n (specified by $number) nodes that have the most recent
- *      comments.  This is done by querying node_comment_statistics which has
- *      an index on last_comment_timestamp, and is thus a fast query.
+ *      comments.
  *   2. Loading the information from the comments table based on the nids found
  *      in step 1.
  *
@@ -305,8 +304,10 @@
 function comment_get_recent($number = 10) {
   // Select the $number nodes (visible to the current user) with the most
   // recent comments. This is efficient due to the index on
-  // last_comment_timestamp.
-  $result = db_query_range(db_rewrite_sql("SELECT nc.nid FROM {node_comment_statistics} nc WHERE nc.comment_count > 0 ORDER BY nc.last_comment_timestamp DESC", 'nc'), 0, $number);
+  // last_activity.
+  
+  // TODO: Rewrite to only retrieve *comments* and not just activity
+  $result = db_query_range(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.comment_count > 0 ORDER BY n.last_activity DESC", 'nc'), 0, $number);
 
   $nids = array();
   while ($row = db_fetch_object($result)) {
@@ -461,23 +462,14 @@
  */
 function comment_nodeapi(&$node, $op, $arg = 0) {
   switch ($op) {
-    case 'load':
-      return db_fetch_array(db_query("SELECT last_comment_timestamp, last_comment_name, comment_count FROM {node_comment_statistics} WHERE nid = %d", $node->nid));
-      break;
-
     case 'prepare':
       if (!isset($node->comment)) {
         $node->comment = variable_get("comment_$node->type", COMMENT_NODE_READ_WRITE);
       }
       break;
 
-    case 'insert':
-      db_query('INSERT INTO {node_comment_statistics} (nid, last_comment_timestamp, last_comment_name, last_comment_uid, comment_count) VALUES (%d, %d, NULL, %d, 0)', $node->nid, $node->created, $node->uid);
-      break;
-
     case 'delete':
       db_query('DELETE FROM {comments} WHERE nid = %d', $node->nid);
-      db_query('DELETE FROM {node_comment_statistics} WHERE nid = %d', $node->nid);
       break;
 
     case 'update index':
@@ -489,7 +481,7 @@
       return $text;
 
     case 'search result':
-      $comments = db_result(db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = %d', $node->nid));
+      $comments = db_result(db_query('SELECT comment_count FROM {node} WHERE nid = %d', $node->nid));
       return format_plural($comments, '1 comment', '@count comments');
 
     case 'rss item':
@@ -508,7 +500,6 @@
 function comment_user($type, $edit, &$user, $category = NULL) {
   if ($type == 'delete') {
     db_query('UPDATE {comments} SET uid = 0 WHERE uid = %d', $user->uid);
-    db_query('UPDATE {node_comment_statistics} SET last_comment_uid = 0 WHERE last_comment_uid = %d', $user->uid);
   }
 }
 
@@ -1382,7 +1373,7 @@
   static $cache;
 
   if (!isset($cache[$nid])) {
-    $cache[$nid] = db_result(db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = %d', $nid));
+    $cache[$nid] = db_result(db_query('SELECT COUNT(*) AS comment_count FROM {comments} WHERE nid = %d', $nid));
   }
   return $cache[$nid];
 }
@@ -1391,7 +1382,7 @@
   static $cache;
 
   if (!isset($cache[$pid])) {
-    $cache[$pid] = db_result(db_query('SELECT COUNT(cid) FROM {comments} WHERE pid = %d AND status = %d', $pid, COMMENT_PUBLISHED));
+    $cache[$pid] = db_result(db_query('SELECT COUNT(*) FROM {comments} WHERE pid = %d AND status = %d', $pid, COMMENT_PUBLISHED));
   }
 
   return $cache[$pid];
@@ -1416,7 +1407,7 @@
     $timestamp = ($timestamp > NODE_NEW_LIMIT ? $timestamp : NODE_NEW_LIMIT);
 
     // Use the timestamp to retrieve the number of new comments.
-    $result = db_result(db_query('SELECT COUNT(c.cid) FROM {node} n INNER JOIN {comments} c ON n.nid = c.nid WHERE n.nid = %d AND timestamp > %d AND c.status = %d', $nid, $timestamp, COMMENT_PUBLISHED));
+    $result = db_result(db_query('SELECT COUNT(*) FROM {comments} WHERE nid = %d AND timestamp > %d AND status = %d', $nid, $timestamp, COMMENT_PUBLISHED));
 
     return $result;
   }
@@ -2029,29 +2020,12 @@
 }
 
 /**
- * Updates the comment statistics for a given node. This should be called any
- * time a comment is added, deleted, or updated.
- *
- * The following fields are contained in the node_comment_statistics table.
- * - last_comment_timestamp: the timestamp of the last comment for this node or the node create stamp if no comments exist for the node.
- * - last_comment_name: the name of the anonymous poster for the last comment
- * - last_comment_uid: the uid of the poster for the last comment for this node or the node authors uid if no comments exists for the node.
- * - comment_count: the total number of approved/published comments on this node.
+ * Implementation of hook_activity().
  */
-function _comment_update_node_statistics($nid) {
-  $count = db_result(db_query('SELECT COUNT(cid) FROM {comments} WHERE nid = %d AND status = %d', $nid, COMMENT_PUBLISHED));
-
-  // comments exist
-  if ($count > 0) {
-    $last_reply = db_fetch_object(db_query_range('SELECT cid, name, timestamp, uid FROM {comments} WHERE nid = %d AND status = %d ORDER BY cid DESC', $nid, COMMENT_PUBLISHED, 0, 1));
-    db_query("UPDATE {node_comment_statistics} SET comment_count = %d, last_comment_timestamp = %d, last_comment_name = '%s', last_comment_uid = %d WHERE nid = %d", $count, $last_reply->timestamp, $last_reply->uid ? '' : $last_reply->name, $last_reply->uid, $nid);
-  }
-
-  // no comments
-  else {
-    $node = db_fetch_object(db_query("SELECT uid, created FROM {node} WHERE nid = %d", $nid));
-    db_query("UPDATE {node_comment_statistics} SET comment_count = 0, last_comment_timestamp = %d, last_comment_name = '', last_comment_uid = %d WHERE nid = %d", $node->created, $node->uid, $nid);
-  }
+function comment_activity($node) {
+  $activity = db_fetch_array(db_query_range('SELECT timestamp, uid FROM {comments} WHERE nid = %d ORDER BY timestamp DESC', $node->nid, 0, 1));
+  $activity['count'] = db_result(db_query('SELECT COUNT(*) FROM {comments} WHERE nid = %d', $node->nid));
+  return $activity;
 }
 
 /**
@@ -2079,7 +2053,6 @@
   return $return;
 }
 
-
 /**
  * Generate vancode.
  *
@@ -2208,4 +2181,26 @@
       break;
     }
   }
+}
+
+/**
+ * Implementation of hook_user_activity().
+ */
+function comment_user_activity($node, $uid) {
+  $count = db_query('SELECT COUNT(*) FROM {comments} WHERE nid = %d AND uid = %d', $node->nid, $uid);
+  return ($count > 0);
+}
+
+/**
+ * Implementation of hook_node_activity().
+ */
+function comment_node_activity($node) {
+  $res = db_query_range('SELECT uid, timestamp FROM {comments} WHERE nid = %d ORDER BY timestamp DESC', 0, 1);
+  if ($comment = db_fetch_object($res)) {
+    return array(
+      'timestamp' => $comment->timestamp,
+      'uid'       => $comment->uid,
+    );
+  }
+  return FALSE;
 }
\ No newline at end of file
Index: modules/comment/comment.schema
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.schema,v
retrieving revision 1.2
diff -u -r1.2 comment.schema
--- modules/comment/comment.schema	15 Jun 2007 07:15:24 -0000	1.2
+++ modules/comment/comment.schema	4 Jul 2007 08:09:08 -0000
@@ -28,18 +28,6 @@
     'primary key' => array('cid'),
   );
 
-  $schema['node_comment_statistics'] = array(
-    'fields' => array(
-      'nid'                    => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
-      'last_comment_timestamp' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
-      'last_comment_name'      => array('type' => 'varchar', 'length' => 60, 'not null' => FALSE),
-      'last_comment_uid'       => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
-      'comment_count'          => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0)
-    ),
-    'indexes' => array('node_comment_timestamp' => array('last_comment_timestamp')),
-    'primary key' => array('nid'),
-  );
-
   return $schema;
 }
 
Index: modules/forum/forum.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.module,v
retrieving revision 1.407
diff -u -r1.407 forum.module
--- modules/forum/forum.module	2 Jul 2007 17:08:35 -0000	1.407
+++ modules/forum/forum.module	4 Jul 2007 08:09:09 -0000
@@ -382,7 +382,7 @@
         switch ($delta) {
           case 0:
             $title = t('Active forum topics');
-            $sql = db_rewrite_sql("SELECT n.nid, n.title, l.comment_count, l.last_comment_timestamp FROM {node} n INNER JOIN {term_node} tn ON tn.nid = n.nid INNER JOIN {term_data} td ON td.tid = tn.tid INNER JOIN {node_comment_statistics} l ON n.nid = l.nid WHERE n.status = 1 AND td.vid = %d ORDER BY l.last_comment_timestamp DESC");
+            $sql = db_rewrite_sql("SELECT n.nid, n.title, n.comment_count, n.last_activity FROM {node} n WHERE n.status = 1 AND n.type = 'forum' ORDER BY n.last_activity DESC");
             $result = db_query_range($sql, variable_get('forum_nav_vocabulary', ''), 0, variable_get('forum_block_num_0', '5'));
             if (db_num_rows($result)) {
               $content = node_title_list($result);
@@ -391,7 +391,7 @@
 
           case 1:
             $title = t('New forum topics');
-            $sql = db_rewrite_sql("SELECT n.nid, n.title, l.comment_count FROM {node} n INNER JOIN {term_node} tn ON tn.nid = n.nid INNER JOIN {term_data} td ON td.tid = tn.tid INNER JOIN {node_comment_statistics} l ON n.nid = l.nid WHERE n.status = 1 AND td.vid = %d ORDER BY n.nid DESC");
+            $sql = db_rewrite_sql("SELECT n.nid, n.title, n.comment_count FROM {node} n WHERE n.type = 'forum' AND n.status = 1 ORDER BY n.nid DESC");
             $result = db_query_range($sql, variable_get('forum_nav_vocabulary', ''), 0, variable_get('forum_block_num_1', '5'));
             if (db_num_rows($result)) {
               $content = node_title_list($result);
@@ -725,7 +725,7 @@
 
     $counts = array();
 
-    $sql = "SELECT r.tid, COUNT(n.nid) AS topic_count, SUM(l.comment_count) AS comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {term_node} r ON n.nid = r.nid WHERE n.status = 1 GROUP BY r.tid";
+    $sql = "SELECT r.tid, COUNT(n.nid) AS topic_count, SUM(n.comment_count) AS comment_count FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid WHERE n.status = 1 GROUP BY r.tid";
     $sql = db_rewrite_sql($sql);
     $_counts = db_query($sql);
     while ($count = db_fetch_object($_counts)) {
@@ -747,18 +747,15 @@
       $forum->num_posts = 0;
     }
 
-    // This query does not use full ANSI syntax since MySQL 3.x does not support
-    // table1 INNER JOIN table2 INNER JOIN table3 ON table2_criteria ON table3_criteria
-    // used to join node_comment_statistics to users.
-    $sql = "SELECT ncs.last_comment_timestamp, IF (ncs.last_comment_uid != 0, u2.name, ncs.last_comment_name) AS last_comment_name, ncs.last_comment_uid FROM {node} n INNER JOIN {users} u1 ON n.uid = u1.uid INNER JOIN {term_node} tn ON n.nid = tn.nid INNER JOIN {node_comment_statistics} ncs ON n.nid = ncs.nid INNER JOIN {users} u2 ON ncs.last_comment_uid=u2.uid WHERE n.status = 1 AND tn.tid = %d ORDER BY ncs.last_comment_timestamp DESC";
+    $sql = "SELECT n.last_activity, lau.name AS last_activity_name, n.last_activity_uid FROM {node} n INNER JOIN {users} lau ON n.last_activity_uid = lau.uid INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.status = 1 AND tn.tid = %d ORDER BY tn.last_activity_timestamp DESC";
     $sql = db_rewrite_sql($sql);
     $topic = db_fetch_object(db_query_range($sql, $forum->tid, 0, 1));
 
     $last_post = new stdClass();
-    if (!empty($topic->last_comment_timestamp)) {
-      $last_post->timestamp = $topic->last_comment_timestamp;
-      $last_post->name = $topic->last_comment_name;
-      $last_post->uid = $topic->last_comment_uid;
+    if (!empty($topic->last_activity_timestamp)) {
+      $last_post->timestamp = $topic->last_activity;
+      $last_post->name = $topic->last_activity_name;
+      $last_post->uid = $topic->last_activity_uid;
     }
     $forum->last_post = $last_post;
 
@@ -783,10 +780,10 @@
 
   $forum_topic_list_header = array(
     array('data' => '&nbsp;', 'field' => NULL),
-    array('data' => t('Topic'), 'field' => 'n.title'),
-    array('data' => t('Replies'), 'field' => 'l.comment_count'),
-    array('data' => t('Created'), 'field' => 'n.created'),
-    array('data' => t('Last reply'), 'field' => 'l.last_comment_timestamp'),
+    array('data' => t('Topic'), 'field' => 'n.title'), // Slow but uncommon
+    array('data' => t('Replies'), 'field' => 'r.node_activity_count'),
+    array('data' => t('Created'), 'field' => 'r.node_created'),
+    array('data' => t('Last reply'), 'field' => 'r.node_last_activity'),
   );
 
   $order = _forum_get_topic_order($sortby);
@@ -798,9 +795,9 @@
 
   $term = taxonomy_get_term($tid);
 
-  $sql = db_rewrite_sql("SELECT n.nid, r.tid, n.title, n.sticky, u.name, u.uid, n.created AS timestamp, n.comment AS comment_mode, l.last_comment_timestamp, IF(l.last_comment_uid != 0, cu.name, l.last_comment_name) AS last_comment_name, l.last_comment_uid, l.comment_count AS num_comments FROM {node_comment_statistics} l, {users} cu, {term_node} r, {users} u, {node} n WHERE n.status = 1 AND l.last_comment_uid = cu.uid AND n.nid = l.nid AND n.nid = r.nid AND r.tid = %d AND n.uid = u.uid AND n.vid = r.vid");
-  $sql .= tablesort_sql($forum_topic_list_header, 'n.sticky DESC,');
-  $sql .= ', n.created DESC';  // Always add a secondary sort order so that the news forum topics are on top.
+  $sql = db_rewrite_sql("SELECT n.nid, f.tid, n.title, n.sticky, u.name, u.uid, n.created AS timestamp, n.comment AS comment_mode, n.last_activity, lau.name AS last_activity_name, n.last_activity_uid, n.comment_count AS num_comments FROM {node} n INNER JOIN {users} lau ON n.last_activity_uid = lau.uid INNER JOIN {term_node} r ON n.nid = r.nid INNER JOIN {users} u ON n.uid = u.uid WHERE r.status = 1 AND r.tid = %d");
+  $sql .= tablesort_sql($forum_topic_list_header, 'r.sticky DESC,');
+  $sql .= ', r.node_created DESC';  // Always add a secondary sort order so that the new forum topics are on top.
 
   $sql_count = db_rewrite_sql("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1");
 
@@ -826,9 +823,9 @@
 
     if ($topic->num_comments > 0) {
       $last_reply = new stdClass();
-      $last_reply->timestamp = $topic->last_comment_timestamp;
-      $last_reply->name = $topic->last_comment_name;
-      $last_reply->uid = $topic->last_comment_uid;
+      $last_reply->timestamp = $topic->last_activity_timestamp;
+      $last_reply->name = $topic->last_activity_name;
+      $last_reply->uid = $topic->last_activity_uid;
       $topic->last_reply = $last_reply;
     }
     $topics[] = $topic;
@@ -1093,7 +1090,7 @@
   $output = '';
 
   // get previous and next topic
-  $sql = "SELECT n.nid, n.title, n.sticky, l.comment_count, l.last_comment_timestamp FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 ORDER BY n.sticky DESC, ". _forum_get_topic_order_sql(variable_get('forum_order', 1));
+  $sql = "SELECT n.nid, n.title, n.sticky, n.comment_count, n.last_activity_timestamp FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 ORDER BY n.sticky DESC, ". _forum_get_topic_order_sql(variable_get('forum_order', 1));
   $result = db_query(db_rewrite_sql($sql), isset($node->tid) ? $node->tid : 0);
 
   $stop = 0;
@@ -1150,16 +1147,16 @@
 function _forum_get_topic_order($sortby) {
   switch ($sortby) {
     case 1:
-      return array('field' => 'l.last_comment_timestamp', 'sort' => 'desc');
+      return array('field' => 'n.last_activity', 'sort' => 'desc');
       break;
     case 2:
-      return array('field' => 'l.last_comment_timestamp', 'sort' => 'asc');
+      return array('field' => 'n.last_activity', 'sort' => 'asc');
       break;
     case 3:
-      return array('field' => 'l.comment_count', 'sort' => 'desc');
+      return array('field' => 'n.comment_count', 'sort' => 'desc');
       break;
     case 4:
-      return array('field' => 'l.comment_count', 'sort' => 'asc');
+      return array('field' => 'n.comment_count', 'sort' => 'asc');
       break;
   }
 }
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.852
diff -u -r1.852 node.module
--- modules/node/node.module	3 Jul 2007 20:31:15 -0000	1.852
+++ modules/node/node.module	4 Jul 2007 08:09:09 -0000
@@ -105,7 +105,7 @@
  * Gather a listing of links to nodes.
  *
  * @param $result
- *   A DB result object from a query to fetch node objects. If your query joins the <code>node_comment_statistics</code> table so that the <code>comment_count</code> field is available, a title attribute will be added to show the number of comments.
+ *   A DB result object from a query to fetch node objects. A title attribute is added to show the number of comments.
  * @param $title
  *   A heading for the resulting list.
  *
@@ -114,7 +114,7 @@
  */
 function node_title_list($result, $title = NULL) {
   while ($node = db_fetch_object($result)) {
-    $items[] = l($node->title, 'node/'. $node->nid, !empty($node->comment_count) ? array('title' => format_plural($node->comment_count, '1 comment', '@count comments')) : array());
+    $items[] = l($node->title, 'node/'. $node->nid, array('title' => format_plural($node->comment_count, '1 comment', '@count comments')));
   }
 
   return theme('node_list', $items, $title);
@@ -697,12 +697,14 @@
                     'title' => $node->title, 'type' => $node->type, 'uid' => $node->uid,
                     'status' => $node->status, 'language' => $node->language, 'created' => $node->created,
                     'changed' => $node->changed, 'comment' => $node->comment,
-                    'promote' => $node->promote, 'sticky' => $node->sticky);
+                    'promote' => $node->promote, 'sticky' => $node->sticky,
+                    'last_activity' => $node->changed);
   $node_table_types = array(
                     'title' => "'%s'", 'type' => "'%s'", 'uid' => '%d',
                     'status' => '%d', 'language' => "'%s'",'created' => '%d',
                     'changed' => '%d', 'comment' => '%d',
-                    'promote' => '%d', 'sticky' => '%d');
+                    'promote' => '%d', 'sticky' => '%d',
+                    'last_activity' => '%d');
   $update_node = TRUE;
   //Generate the node table query and the
   //the node_revisions table query
@@ -912,9 +914,8 @@
 
     case 'status':
       $last = variable_get('node_cron_last', 0);
-      $last_nid = variable_get('node_cron_last_nid', 0);
       $total = db_result(db_query('SELECT COUNT(*) FROM {node} WHERE status = 1'));
-      $remaining = db_result(db_query('SELECT COUNT(*) FROM {node} n LEFT JOIN {node_comment_statistics} c ON n.nid = c.nid WHERE n.status = 1 AND ((GREATEST(n.created, n.changed, c.last_comment_timestamp) = %d AND n.nid > %d ) OR (n.created > %d OR n.changed > %d OR c.last_comment_timestamp > %d))', $last, $last_nid, $last, $last, $last));
+      $remaining = db_result(db_query('SELECT COUNT(*) FROM {node} n WHERE n.status = 1 AND n.last_activity >= %d', $last));
       return array('remaining' => $remaining, 'total' => $total);
 
     case 'admin':
@@ -972,8 +973,8 @@
       $ranking = array();
       $arguments2 = array();
       $join2 = '';
-      // Used to avoid joining on node_comment_statistics twice
-      $stats_join = FALSE;
+      // Used to avoid joining on node twice
+      $node_join = FALSE;
       $total = 0;
       if ($weight = (int)variable_get('node_rank_relevance', 5)) {
         // Average relevance values hover around 0.15
@@ -983,11 +984,11 @@
       }
       if ($weight = (int)variable_get('node_rank_recent', 5)) {
         // Exponential decay with half-life of 6 months, starting at last indexed node
-        $ranking[] = '%d * POW(2, (GREATEST(n.created, n.changed, c.last_comment_timestamp) - %d) * 6.43e-8)';
+        $ranking[] = '%d * POW(2, (n.last_activity - %d) * 6.43e-8)';
         $arguments2[] = $weight;
         $arguments2[] = (int)variable_get('node_cron_last', 0);
-        $join2 .= ' INNER JOIN {node} n ON n.nid = i.sid LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
-        $stats_join = TRUE;
+        $join2 .= ' INNER JOIN {node} n ON n.nid = i.sid';
+        $node_join = TRUE;
         $total += $weight;
       }
       if (module_exists('comment') && $weight = (int)variable_get('node_rank_comments', 5)) {
@@ -996,8 +997,9 @@
         $ranking[] = '%d * (2.0 - 2.0 / (1.0 + c.comment_count * %f))';
         $arguments2[] = $weight;
         $arguments2[] = $scale;
-        if (!$stats_join) {
-          $join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
+        if (!$node_join) {
+          $join2 .= ' INNER JOIN {node} n ON n.nid = i.sid';
+          $node_join = TRUE;
         }
         $total += $weight;
       }
@@ -1008,7 +1010,10 @@
         $ranking[] = '%d * (2.0 - 2.0 / (1.0 + nc.totalcount * %f))';
         $arguments2[] = $weight;
         $arguments2[] = $scale;
-        $join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid';
+        if (!$node_join) {
+          $join2 .= ' INNER JOIN {node} n ON n.nid = i.sid';
+          $node_join = TRUE;
+        }
         $total += $weight;
       }
       $select2 = (count($ranking) ? implode(' + ', $ranking) : 'i.relevance') .' AS score';
@@ -1052,6 +1057,7 @@
   if ($op == 'delete') {
     db_query('UPDATE {node} SET uid = 0 WHERE uid = %d', $user->uid);
     db_query('UPDATE {node_revisions} SET uid = 0 WHERE uid = %d', $user->uid);
+    db_query('UPDATE {node} SET last_activity_uid = 0 WHERE last_activity_uid = %d', $user->uid);
   }
 }
 
@@ -2642,10 +2648,10 @@
   $limit = (int)variable_get('search_cron_limit', 100);
 
   // Store the maximum possible comments per thread (used for ranking by reply count)
-  variable_set('node_cron_comments_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(comment_count) FROM {node_comment_statistics}'))));
-  variable_set('node_cron_views_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(totalcount) FROM {node_counter}'))));
+  variable_set('node_cron_comments_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(comment_count) FROM {node}'))));
+  variable_set('node_cron_views_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(totalcount) FROM {node}'))));
 
-  $result = db_query_range('SELECT GREATEST(IF(c.last_comment_timestamp IS NULL, 0, c.last_comment_timestamp), n.changed) as last_change, n.nid FROM {node} n LEFT JOIN {node_comment_statistics} c ON n.nid = c.nid WHERE n.status = 1 AND ((GREATEST(n.changed, c.last_comment_timestamp) = %d AND n.nid > %d) OR (n.changed > %d OR c.last_comment_timestamp > %d)) ORDER BY GREATEST(n.changed, c.last_comment_timestamp) ASC, n.nid ASC', $last, $last_nid, $last, $last, $last, 0, $limit);
+  $result = db_query_range('SELECT n.last_activity, n.nid FROM {node} n WHERE n.status = 1 AND ((n.last_activity = %d AND n.nid > %d) OR n.last_activity > %d) ORDER BY n.last_activity ASC, n.nid ASC', $last, $last_nid, $last, 0, $limit);
 
   while ($node = db_fetch_object($result)) {
     $last_change = $node->last_change;
@@ -2741,6 +2747,54 @@
 }
 
 /**
+ * Update the latest activity timestamp and uid for a node.
+ *
+ * @param $node
+ *   The node object which is being updated.
+ */
+function node_update_activity(&$node, $uid) {
+  $uid = $node->uid;
+  $timestamp = max($node->changed, $node->created);
+  $count = 0;
+  
+  // Determine the lastest activity's $timestamp and $uid
+  $activities = module_invoke_all('node_activity', $node);
+  foreach($activities as $activity) {
+    if ($activity && $activity['timestamp'] > $timestamp) {
+      $timestamp = $activity['timestamp'];
+      $uid = $activity['uid'];
+      $count += $activity['count'];
+    }
+  }
+  
+  // Update the $node activity record
+  if ($timestamp != $node->last_activity || $uid != $node->last_activity_uid) {
+    db_query('UPDATE {node} SET last_activity = %d, last_activity_uid = %d, activity_count = %d WHERE nid = %d', $timestamp, $uid, $count, $node->nid);
+    $node->last_activity = $timestamp;
+    $node->last_activity_uid = $uid;
+  }
+
+  // Determine if the given $uid is a participant in $node
+  $participation_possibilities = module_invoke_all('user_activity', $node, $uid);
+  $participant = FALSE;
+  foreach ($participation_possibilities as $participation_possibility) {
+    if ($participation_possibility) {
+      $participant = TRUE;
+    }
+  }
+  
+  // Update the participation record
+  db_query('DELETE FROM {node_user_activity} WHERE nid = %d AND uid = %d', $node->nid, $uid);
+  if ($participant) {
+    db_query('INSERT INTO {node_user_activity} (nid, uid, last_activity) VALUES (%d, %d, %d)', $node->nid, $uid, $timestamp);
+  }
+  db_query('UPDATE {node_user_activity} SET last_activity = %d WHERE nid = %d', $timestamp, $node->nid);
+  
+  // Notify other modules that the node has an updated activity record
+  module_invoke_all('node_activity_updated', $node);
+}
+
+/**
  * Form API callback for the search form. Registered in node_form_alter().
  */
 function node_search_validate($form, &$form_state) {
Index: modules/node/node.schema
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.schema,v
retrieving revision 1.4
diff -u -r1.4 node.schema
--- modules/node/node.schema	3 Jul 2007 19:42:14 -0000	1.4
+++ modules/node/node.schema	4 Jul 2007 08:09:09 -0000
@@ -19,6 +19,12 @@
       'sticky'    => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
       'tnid'      => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
       'translate' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+      'last_activity'     => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+      'last_activity_uid' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+      'activity_count'    => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'views_total'       => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'big'),
+      'views_today'       => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'medium'),
+      'last_viewed'       => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
     ),
     'indexes' => array(
       'nid'                 => array('nid'),
@@ -33,6 +39,7 @@
       'uid'                 => array('uid'),
       'tnid'                => array('tnid'),
       'translate'           => array('translate'),
+      'last_activity' => array('last_activity'),
     ),
     'unique keys' => array(
       'nid_vid' => array('nid', 'vid'),
@@ -57,16 +64,6 @@
     ),
   );
 
-  $schema['node_counter'] = array(
-    'fields' => array(
-      'nid'        => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
-      'totalcount' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'big'),
-      'daycount'   => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'medium'),
-      'timestamp'  => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0)
-    ),
-    'primary key' => array('nid'),
-  );
-
   $schema['node_revisions'] = array(
     'fields' => array(
       'nid'       => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
@@ -105,7 +102,19 @@
     ),
     'primary key' => array('type'),
   );
-
+  
+  $schema['node_user_activity'] = array(
+    'fields' => array(
+      'nid'           => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'uid'           => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+      'last_activity' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+    );
+    'primary key' => array('nid', 'uid'),
+    'indexes' => array(
+      'user_tracker' => array('uid', 'last_activity'),
+    ),
+  );
+  
   return $schema;
 }
 
Index: modules/search/search.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.module,v
retrieving revision 1.228
diff -u -r1.228 search.module
--- modules/search/search.module	1 Jul 2007 17:41:16 -0000	1.228
+++ modules/search/search.module	4 Jul 2007 08:09:09 -0000
@@ -849,7 +849,7 @@
  *
  * @param $join2
  *   (optional) Inserted into the JOIN par of the second SQL query.
- *   For example "INNER JOIN {node_comment_statistics} n ON n.nid = i.sid"
+ *   For example "INNER JOIN {node} n ON n.nid = i.sid".
  *
  * @param $arguments2
  *   (optional) Extra SQL arguments belonging to the second query parameter.
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.367
diff -u -r1.367 taxonomy.module
--- modules/taxonomy/taxonomy.module	2 Jul 2007 17:08:36 -0000	1.367
+++ modules/taxonomy/taxonomy.module	4 Jul 2007 08:09:09 -0000
@@ -1314,6 +1314,7 @@
     case 'update':
       if (!empty($node->taxonomy)) {
         taxonomy_node_save($node, $node->taxonomy);
+        db_query('UPDATE {term_node} SET node_status = %d WHERE nid = %d', $node->status, $node->nid);
       }
       break;
 
@@ -1567,4 +1568,14 @@
       ),
     ),
   );
+}
+
+/**
+ * Implementation of hook_activity_updated()
+ *
+ * The data managed by this function is used in forum.module, but it's useful
+ * for any need to find the lastest updates for nodes linked to a term.
+ */
+function taxonomy_activity_updated($node) {
+  db_query('UPDATE {term_node} SET node_last_activity = %d, node_activity_count = %d WHERE nid = %d', $node->last_activity, $node->activity_count, $node->nid);
 }
\ No newline at end of file
Index: modules/taxonomy/taxonomy.schema
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.schema,v
retrieving revision 1.1
diff -u -r1.1 taxonomy.schema
--- modules/taxonomy/taxonomy.schema	25 May 2007 12:46:46 -0000	1.1
+++ modules/taxonomy/taxonomy.schema	4 Jul 2007 08:09:09 -0000
@@ -21,26 +21,30 @@
     ),
     'indexes' => array(
       'parent' => array('parent'),
-      'tid'    => array('tid')
     ),
     'primary key' => array('tid', 'parent'),
   );
 
   $schema['term_node'] = array(
     'fields' => array(
-      'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'vid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'tid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0)
+      'nid'                 => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'vid'                 => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'tid'                 => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'node_sticky'         => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+      'node_status'         => array('type' => 'int', 'not null' => TRUE, 'default' => 1),
+      'node_created'        => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+      'node_last_activity'  => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+      'node_activity_count' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
     ),
     'indexes' => array(
-      'nid' => array('nid'),
-      'tid' => array('tid'),
-      'vid' => array('vid')
+      'nid'            => array('nid'),
+      'last_activity'  => array('tid', 'node_status', 'last_activity', 'node_created'),
+      'activity_count' => array('tid', 'node_status', 'node_activity_count', 'node_created'),
+      'new'            => array('tid', 'node_status', 'node_sticky', 'node_created'),
     ),
     'primary key' => array(
       'vid',
       'tid',
-      'nid'
     ),
   );
 
Index: modules/tracker/tracker.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/tracker/tracker.module,v
retrieving revision 1.149
diff -u -r1.149 tracker.module
--- modules/tracker/tracker.module	30 Jun 2007 19:46:58 -0000	1.149
+++ modules/tracker/tracker.module	4 Jul 2007 08:09:09 -0000
@@ -83,14 +83,14 @@
 
   // TODO: These queries are very expensive, see http://drupal.org/node/105639
   if ($uid) {
-    $sql = 'SELECT DISTINCT(n.nid), n.title, n.type, n.changed, n.uid, u.name, GREATEST(n.changed, l.last_comment_timestamp) AS last_updated, l.comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {users} u ON n.uid = u.uid LEFT JOIN {comments} c ON n.nid = c.nid AND (c.status = %d OR c.status IS NULL) WHERE n.status = 1 AND (n.uid = %d OR c.uid = %d) ORDER BY last_updated DESC';
+    $sql = 'SELECT DISTINCT(n.nid), n.title, n.type, n.changed, n.uid, u.name, n.last_activity_timestamp AS last_updated, n.comment_count FROM {node} n INNER JOIN {users} u ON n.uid = u.uid LEFT JOIN {comments} c ON n.nid = c.nid AND (c.status = %d OR c.status IS NULL) WHERE n.status = 1 AND (n.uid = %d OR c.uid = %d) ORDER BY last_updated DESC';
     $sql = db_rewrite_sql($sql);
     $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid AND (c.status = %d OR c.status IS NULL) WHERE n.status = 1 AND (n.uid = %d OR c.uid = %d)';
     $sql_count = db_rewrite_sql($sql_count);
     $result = pager_query($sql, 25, 0, $sql_count, COMMENT_PUBLISHED, $uid, $uid);
   }
   else {
-    $sql = 'SELECT DISTINCT(n.nid), n.title, n.type, n.changed, n.uid, u.name, GREATEST(n.changed, l.last_comment_timestamp) AS last_updated, l.comment_count FROM {node} n INNER JOIN {users} u ON n.uid = u.uid INNER JOIN {node_comment_statistics} l ON n.nid = l.nid WHERE n.status = 1 ORDER BY last_updated DESC';
+    $sql = 'SELECT DISTINCT(n.nid), n.title, n.type, n.changed, n.uid, u.name, n.last_activity_timestamp AS last_updated, n.comment_count FROM {node} n INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 ORDER BY last_updated DESC';
     $sql = db_rewrite_sql($sql);
     $sql_count = 'SELECT COUNT(n.nid) FROM {node} n WHERE n.status = 1';
     $sql_count = db_rewrite_sql($sql_count);
