? revisioned_taxonomy_head.patch
Index: modules/forum/forum.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.module,v
retrieving revision 1.382
diff -u -p -r1.382 forum.module
--- modules/forum/forum.module	1 Feb 2007 21:44:36 -0000	1.382
+++ modules/forum/forum.module	7 Feb 2007 07:45:50 -0000
@@ -394,7 +394,7 @@ function forum_form(&$node) {
   $form['title'] = array('#type' => 'textfield', '#title' => check_plain($type->title_label), '#default_value' => !empty($node->title) ? $node->title : '', '#required' => TRUE, '#weight' => -5);
 
   if (!empty($node->nid)) {
-    $forum_terms = taxonomy_node_get_terms_by_vocabulary(_forum_get_vid(), $node->nid);
+    $forum_terms = taxonomy_node_get_terms_by_vocabulary(_forum_get_vid(), $node);
     // if editing, give option to leave shadows
     $shadow = (count($forum_terms) > 1);
     $form['shadow'] = array('#type' => 'checkbox', '#title' => t('Leave shadow copy'), '#default_value' => $shadow, '#description' => t('If you move this topic, you can leave a link in the old forum to the new forum.'));
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.76
diff -u -p -r1.76 system.install
--- modules/system/system.install	31 Jan 2007 21:26:56 -0000	1.76
+++ modules/system/system.install	7 Feb 2007 07:45:52 -0000
@@ -517,10 +517,12 @@ function system_install() {
 
       db_query("CREATE TABLE {term_node} (
         nid int unsigned NOT NULL default '0',
+        vid int unsigned NOT NULL default '0',
         tid int unsigned NOT NULL default '0',
         KEY nid (nid),
+        KEY vid (vid),
         KEY tid (tid),
-        PRIMARY KEY (tid,nid)
+        PRIMARY KEY (vid,tid,nid)
       ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
 
       db_query("CREATE TABLE {term_relation} (
@@ -991,10 +993,12 @@ function system_install() {
 
       db_query("CREATE TABLE {term_node} (
         nid int_unsigned NOT NULL default '0',
+        vid int_unsigned NOT NULL default '0',
         tid int_unsigned NOT NULL default '0',
-        PRIMARY KEY (tid,nid)
+        PRIMARY KEY (tid,nid,vid)
       )");
       db_query("CREATE INDEX {term_node}_nid_idx ON {term_node} (nid)");
+      db_query("CREATE INDEX {term_node}_vid_idx ON {term_node} (vid)");
       db_query("CREATE INDEX {term_node}_tid_idx ON {term_node} (tid)");
 
       db_query("CREATE TABLE {term_relation} (
@@ -3544,6 +3548,24 @@ function system_update_2000() {
 }
 
 /**
+ * Add version id column to {term_node} to allow taxonomy module to use revisions.
+ */
+function system_update_2001() {
+  $ret = array();
+  // Add revision id to term-node relation.
+  db_add_column($ret, 'term_node', 'vid', 'int', array('default' => 0));
+  $ret[] = update_sql('ALTER TABLE {term_node} DROP PRIMARY KEY');
+  $ret[] = update_sql('ALTER TABLE {term_node} ADD PRIMARY KEY (tid,nid,vid)');
+  $ret[] = update_sql('ALTER TABLE {term_node} ADD KEY (vid)');
+  // Update all entries with the current revision number.
+  $nodes = db_query('SELECT nid,vid FROM {node}');
+  while ($node = db_fetch_object($nodes)) {
+    db_query('UPDATE {term_node} SET vid = %d WHERE nid = %d', $node->vid, $node->nid);
+  }
+  return $ret;
+}
+
+/**
  * @} End of "defgroup updates-5.0-to-x.x"
  * The next series of updates should start at 3000.
  */
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.337
diff -u -p -r1.337 taxonomy.module
--- modules/taxonomy/taxonomy.module	31 Jan 2007 21:26:56 -0000	1.337
+++ modules/taxonomy/taxonomy.module	7 Feb 2007 07:45:52 -0000
@@ -659,7 +659,7 @@ function taxonomy_form_alter($form_id, &
     $node = $form['#node'];
 
     if (!isset($node->taxonomy)) {
-      $terms = empty($node->nid) ? array() : taxonomy_node_get_terms($node->nid);
+      $terms = empty($node->nid) ? array() : taxonomy_node_get_terms($node);
     }
     else {
       $terms = $node->taxonomy;
@@ -731,8 +731,13 @@ function taxonomy_form_alter($form_id, &
 /**
  * Find all terms associated with the given node, within one vocabulary.
  */
-function taxonomy_node_get_terms_by_vocabulary($nid, $vid, $key = 'tid') {
-  $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_node} r ON r.tid = t.tid WHERE t.vid = %d AND r.nid = %d ORDER BY weight', 't', 'tid'), $vid, $nid);
+function taxonomy_node_get_terms_by_vocabulary($node, $vid, $key = 'tid') {
+  if (is_numeric($node)) {
+    // If a node id is passed get the newest version id for that node.
+    $node = db_fetch_object(db_query('SELECT nid, vid FROM {node} WHERE nid = %d', $node));
+  }
+
+  $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_node} r ON r.tid = t.tid WHERE t.vid = %d AND r.vid = %d ORDER BY weight', 't', 'tid'), $vid, $node->vid);
   $terms = array();
   while ($term = db_fetch_object($result)) {
     $terms[$term->$key] = $term;
@@ -743,17 +748,22 @@ function taxonomy_node_get_terms_by_voca
 /**
  * Find all terms associated with the given node, ordered by vocabulary and term weight.
  */
-function taxonomy_node_get_terms($nid, $key = 'tid') {
+function taxonomy_node_get_terms($node, $key = 'tid') {
   static $terms;
 
-  if (!isset($terms[$nid])) {
-    $result = db_query(db_rewrite_sql('SELECT t.* FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.nid = %d ORDER BY v.weight, t.weight, t.name', 't', 'tid'), $nid);
-    $terms[$nid] = array();
+  if (is_numeric($node)) {
+    // If a node id is passed get the newest version id for that node.
+    $node = db_fetch_object(db_query('SELECT nid, vid FROM {node} WHERE nid = %d', $node));
+  }
+
+  if (!isset($terms[$node->vid])) {
+    $result = db_query(db_rewrite_sql('SELECT t.* FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.vid = %d ORDER BY v.weight, t.weight, t.name', 't', 'tid'), $node->vid);
+    $terms[$node->vid] = array();
     while ($term = db_fetch_object($result)) {
-      $terms[$nid][$term->$key] = $term;
+      $terms[$node->vid][$term->$key] = $term;
     }
   }
-  return $terms[$nid];
+  return $terms[$node->vid];
 }
 
 /**
@@ -778,8 +788,13 @@ function taxonomy_node_validate(&$node) 
 /**
  * Save term associations for a given node.
  */
-function taxonomy_node_save($nid, $terms) {
-  taxonomy_node_delete($nid);
+function taxonomy_node_save($node, $terms) {
+  if (is_numeric($node)) {
+    // If a node id is passed get the newest version id for that node.
+    $node = db_fetch_object(db_query('SELECT nid, vid FROM {node} WHERE nid = %d', $node));
+  }
+
+  taxonomy_node_delete_revision($node);
 
   // Free tagging vocabularies do not send their tids in the form,
   // so we'll detect them here and process them independently.
@@ -821,7 +836,7 @@ function taxonomy_node_save($nid, $terms
 
         // Defend against duplicate, differently cased tags
         if (!isset($inserted[$typed_term_tid])) {
-          db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $typed_term_tid);
+          db_query('INSERT INTO {term_node} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $typed_term_tid);
           $inserted[$typed_term_tid] = TRUE;
         }
       }
@@ -833,15 +848,15 @@ function taxonomy_node_save($nid, $terms
       if (is_array($term)) {
         foreach ($term as $tid) {
           if ($tid) {
-            db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $tid);
+            db_query('INSERT INTO {term_node} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $tid);
           }
         }
       }
       else if (is_object($term)) {
-        db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $term->tid);
+        db_query('INSERT INTO {term_node} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $term->tid);
       }
       else if ($term) {
-        db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $term);
+        db_query('INSERT INTO {term_node} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $term);
       }
     }
   }
@@ -850,8 +865,24 @@ function taxonomy_node_save($nid, $terms
 /**
  * Remove associations of a node to its terms.
  */
-function taxonomy_node_delete($nid) {
-  db_query('DELETE FROM {term_node} WHERE nid = %d', $nid);
+function taxonomy_node_delete($node) {
+  if (is_numeric($param)) {
+    db_query('DELETE FROM {term_node} WHERE nid = %d', $node);
+  }
+  else {
+    db_query('DELETE FROM {term_node} WHERE nid = %d', $node->nid);
+  }
+}
+
+/**
+ * Remove associations of a node to its terms.
+ */
+function taxonomy_node_delete_revision($node) {
+  if (is_numeric($node)) {
+    // If a node id is passed get the newest version id for that node.
+    $node = db_fetch_object(db_query('SELECT nid, vid FROM {node} WHERE nid = %d', $node));
+  }
+  db_query('DELETE FROM {term_node} WHERE vid = %d', $node->vid);
 }
 
 /**
@@ -1037,10 +1068,10 @@ function taxonomy_term_count_nodes($tid,
   if (!isset($count[$type])) {
     // $type == 0 always evaluates TRUE if $type is a string
     if (is_numeric($type)) {
-      $result = db_query(db_rewrite_sql('SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.nid = n.nid WHERE n.status = 1 GROUP BY t.tid'));
+      $result = db_query(db_rewrite_sql('SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.vid = n.vid WHERE n.status = 1 GROUP BY t.tid'));
     }
     else {
-      $result = db_query(db_rewrite_sql("SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.nid = n.nid WHERE n.status = 1 AND n.type = '%s' GROUP BY t.tid"), $type);
+      $result = db_query(db_rewrite_sql("SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.vid = n.vid WHERE n.status = 1 AND n.type = '%s' GROUP BY t.tid"), $type);
     }
     while ($term = db_fetch_object($result)) {
       $count[$type][$term->tid] = $term->c;
@@ -1218,14 +1249,14 @@ function taxonomy_select_nodes($tids = a
 
     if ($operator == 'or') {
       $str_tids = implode(',', call_user_func_array('array_merge', $descendant_tids));
-      $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid IN ('. $str_tids .') AND n.status = 1 ORDER BY '. $order;
-      $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid IN ('. $str_tids .') AND n.status = 1';
+      $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n INNER JOIN {term_node} tn ON n.vid = t.vid WHERE tn.tid IN ('. $str_tids .') AND n.status = 1 ORDER BY '. $order;
+      $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n INNER JOIN {term_node} tn ON n.vid = tn.vid WHERE tn.tid IN ('. $str_tids .') AND n.status = 1';
     }
     else {
       $joins = '';
       $wheres = '';
       foreach ($descendant_tids as $index => $tids) {
-        $joins .= ' INNER JOIN {term_node} tn'. $index .' ON n.nid = tn'. $index .'.nid';
+        $joins .= ' INNER JOIN {term_node} tn'. $index .' ON n.vid = tn'. $index .'.vid';
         $wheres .= ' AND tn'. $index .'.tid IN ('. implode(',', $tids) .')';
       }
       $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n '. $joins .' WHERE n.status = 1 '. $wheres .' ORDER BY '. $order;
@@ -1267,22 +1298,32 @@ function taxonomy_render_nodes($result) 
 function taxonomy_nodeapi($node, $op, $arg = 0) {
   switch ($op) {
     case 'load':
-     $output['taxonomy'] = taxonomy_node_get_terms($node->nid);
+     $output['taxonomy'] = taxonomy_node_get_terms($node);
      return $output;
+
     case 'insert':
-      taxonomy_node_save($node->nid, $node->taxonomy);
+      taxonomy_node_save($node, $node->taxonomy);
       break;
+
     case 'update':
-      taxonomy_node_save($node->nid, $node->taxonomy);
+      taxonomy_node_save($node, $node->taxonomy);
       break;
+
     case 'delete':
-      taxonomy_node_delete($node->nid);
+      taxonomy_node_delete($node);
       break;
+
+    case 'delete revision':
+      taxonomy_node_delete_revision($node);
+      break;
+
     case 'validate':
       taxonomy_node_validate($node);
       break;
+
     case 'rss item':
       return taxonomy_rss_item($node);
+
     case 'update index':
       return taxonomy_node_update_index($node);
   }
