Index: database/database.mysql =================================================================== RCS file: /cvs/drupal/drupal/database/database.mysql,v retrieving revision 1.168 diff -u -F^f -r1.168 database.mysql --- database/database.mysql 28 Jan 2005 15:47:03 -0000 1.168 +++ database/database.mysql 2 Feb 2005 20:18:21 -0000 @@ -135,11 +135,13 @@ -- CREATE TABLE book ( + vid int(10) unsigned NOT NULL default '0', nid int(10) unsigned NOT NULL default '0', parent int(10) NOT NULL default '0', weight tinyint(3) NOT NULL default '0', log longtext, - PRIMARY KEY (nid), + PRIMARY KEY (vid), + KEY nid (nid), KEY parent (parent) ) TYPE=MyISAM; @@ -280,9 +282,11 @@ -- CREATE TABLE forum ( + vid int(10) unsigned NOT NULL default '0', nid int(10) unsigned NOT NULL default '0', tid int(10) unsigned NOT NULL default '0', - PRIMARY KEY (nid), + PRIMARY KEY (vid), + KEY nid (nid), KEY tid (tid) ) TYPE=MyISAM; @@ -393,8 +397,8 @@ CREATE TABLE node ( nid int(10) unsigned NOT NULL auto_increment, + vid int(10) unsigned NOT NULL default '1', type varchar(16) NOT NULL default '', - title varchar(128) NOT NULL default '', uid int(10) NOT NULL default '0', status int(4) NOT NULL default '1', created int(11) NOT NULL default '0', @@ -402,16 +406,12 @@ comment int(2) NOT NULL default '0', promote int(2) NOT NULL default '0', moderate int(2) NOT NULL default '0', - teaser longtext NOT NULL, - body longtext NOT NULL, - revisions longtext NOT NULL, sticky int(2) NOT NULL default '0', - format int(4) NOT NULL default '0', PRIMARY KEY (nid), KEY node_type (type(4)), - KEY node_title_type (title,type(4)), KEY status (status), KEY uid (uid), + KEY vid (vid), KEY node_moderate (moderate), KEY node_promote_status (promote, status), KEY node_created (created), @@ -434,14 +434,39 @@ ) TYPE=MyISAM; -- --- Table structure for table 'page' +-- Table structure for table 'node_revisions' -- -CREATE TABLE page ( - nid int(10) unsigned NOT NULL default '0', - link varchar(128) NOT NULL default '', - description varchar(128) NOT NULL default '', - PRIMARY KEY (nid) +CREATE TABLE node_revisions ( + nid int(10) unsigned NOT NULL, + vid int(10) unsigned NOT NULL, + uid int(10) NOT NULL default '0', + title varchar(128) NOT NULL default '', + body longtext NOT NULL, + teaser longtext NOT NULL, + timestamp int(11) NOT NULL default '0', + format int(4) NOT NULL default '0', + PRIMARY KEY (nid,vid), + KEY uid (uid) +) TYPE=MyISAM; + +-- +-- Table structure for table 'node_revisions' +-- + +CREATE TABLE node_revisions ( + vid int(10) unsigned NOT NULL, + nid int(10) unsigned NOT NULL, + uid int(10) NOT NULL default '0', + title varchar(128) NOT NULL default '', + body longtext NOT NULL, + teaser longtext NOT NULL, + timestamp int(11) NOT NULL default '0', + format int(4) NOT NULL default '0', + data longtext NOT NULL, + PRIMARY KEY (vid), + KEY nid (nid), + KEY uid (uid) ) TYPE=MyISAM; -- Index: database/database.pgsql =================================================================== RCS file: /cvs/drupal/drupal/database/database.pgsql,v retrieving revision 1.103 diff -u -F^f -r1.103 database.pgsql --- database/database.pgsql 27 Jan 2005 19:41:00 -0000 1.103 +++ database/database.pgsql 2 Feb 2005 20:18:21 -0000 @@ -65,13 +65,14 @@ -- CREATE TABLE book ( + vid integer NOT NULL default '0', nid integer NOT NULL default '0', parent integer NOT NULL default '0', weight smallint NOT NULL default '0', - format smallint default '0', log text default '', - PRIMARY KEY (nid) + PRIMARY KEY (vid) ); +CREATE INDEX book_vid_idx ON book(vid); CREATE INDEX book_nid_idx ON book(nid); CREATE INDEX book_parent ON book(parent); @@ -159,6 +160,23 @@ PRIMARY KEY (iid) ); +-- +-- Table structure for table 'node_revisions' +-- + +CREATE TABLE node_revisions ( + nid integer NOT NULL default '0', + vid integer NOT NULL default '0', + uid integer NOT NULL default '0', + title varchar(128) NOT NULL default '', + body text NOT NULL default '', + teaser text NOT NULL default '', + format smallint NOT NULL default '0', + timestamp integer NOT NULL default '0', + PRIMARY KEY (nid,vid) +); + +CREATE INDEX node_revisions_uid_idx ON node_revisions(uid); -- -- Table structure for cache @@ -283,11 +301,13 @@ -- CREATE TABLE forum ( + vid integer NOT NULL default '0', nid integer NOT NULL default '0', tid integer NOT NULL default '0', - shadow integer NOT NULL default '0', - PRIMARY KEY (nid) + PRIMARY KEY (vid) ); +CREATE INDEX forum_vid_idx ON forum(vid); +CREATE INDEX forum_nid_idx ON forum(nid); CREATE INDEX forum_tid_idx ON forum(tid); -- @@ -395,24 +415,20 @@ CREATE TABLE node ( nid SERIAL, + vid integer NOT NULL default '0', type varchar(16) NOT NULL default '', - title varchar(128) NOT NULL default '', uid integer NOT NULL default '0', status integer NOT NULL default '1', created integer NOT NULL default '0', comment integer NOT NULL default '0', promote integer NOT NULL default '0', moderate integer NOT NULL default '0', - teaser text NOT NULL default '', - body text NOT NULL default '', changed integer NOT NULL default '0', - revisions text NOT NULL default '', sticky integer NOT NULL default '0', format smallint NOT NULL default '0', PRIMARY KEY (nid) ); CREATE INDEX node_type_idx ON node(type); -CREATE INDEX node_title_idx ON node(title,type); CREATE INDEX node_status_idx ON node(status); CREATE INDEX node_uid_idx ON node(uid); CREATE INDEX node_moderate_idx ON node (moderate); @@ -434,6 +450,25 @@ PRIMARY KEY (nid,gid,realm) ); +-- +-- Table structure for table 'node_revisions' +-- + +CREATE TABLE node_revisions ( + vid integer NOT NULL default '0', + nid integer NOT NULL default '0', + uid integer NOT NULL default '0', + title varchar(128) NOT NULL default '', + body text NOT NULL default '', + teaser text NOT NULL default '', + format smallint NOT NULL default '0', + timestamp integer NOT NULL default '0', + data text NOT NULL default '', + PRIMARY KEY (vid) +); + +CREATE INDEX node_revisions_nid_idx ON node_revisions(nid); +CREATE INDEX node_revisions_uid_idx ON node_revisions(uid); -- -- Table structure for table 'node_counter' @@ -449,19 +484,6 @@ CREATE INDEX node_counter_totalcount_idx ON node_counter(totalcount); CREATE INDEX node_counter_daycount_idx ON node_counter(daycount); CREATE INDEX node_counter_timestamp_idx ON node_counter(timestamp); - --- --- Table structure for page --- - -CREATE TABLE page ( - nid integer NOT NULL default '0', - link varchar(128) NOT NULL default '', - format smallint NOT NULL default '0', - description varchar(128) NOT NULL default '', - PRIMARY KEY (nid) -); -CREATE INDEX page_nid_idx ON page(nid); -- -- Table structure for table 'url_alias' Index: database/updates.inc =================================================================== RCS file: /cvs/drupal/drupal/database/updates.inc,v retrieving revision 1.90 diff -u -F^f -r1.90 updates.inc --- database/updates.inc 28 Jan 2005 15:47:03 -0000 1.90 +++ database/updates.inc 2 Feb 2005 20:18:22 -0000 @@ -99,7 +99,9 @@ "2005-01-25" => "update_120", "2005-01-26" => "update_121", "2005-01-27" => "update_122", - "2005-01-28" => "update_123" + "2005-01-28" => "update_123", + "2005-01-29" => "update_124", + "2005-01-30" => "update_125" ); function update_32() { @@ -2188,6 +2190,137 @@ function update_123() { if (!empty($vid)) { $ret[] = update_sql("UPDATE {vocabulary} SET module = 'forum' WHERE vid = " . $vid); } + + return $ret; +} + +function update_124() { + $ret = array(); + + if ($GLOBALS['db_type'] == 'mysql') { + $ret[] = update_sql("CREATE TABLE {node_revisions} ( + nid int(10) unsigned NOT NULL, + vid int(10) unsigned NOT NULL, + uid int(10) NOT NULL default '0', + title varchar(128) NOT NULL default '', + body longtext NOT NULL, + teaser longtext NOT NULL, + timestamp int(11) NOT NULL default '0', + format int(4) NOT NULL default '0', + PRIMARY KEY (vid), + KEY nid (nid), + KEY uid (uid) + )"); + $ret[] = update_sql("ALTER TABLE {node} ADD vid int(10) unsigned NOT NULL default '0'"); + $ret[] = update_sql("ALTER TABLE {book} ADD vid int(10) unsigned NOT NULL default '0'"); + $ret[] = update_sql("ALTER TABLE {forum} ADD vid int(10) unsigned NOT NULL default '0'"); + $ret[] = update_sql("ALTER TABLE {book} DROP PRIMARY KEY"); + $ret[] = update_sql("ALTER TABLE {forum} DROP PRIMARY KEY"); + $ret[] = update_sql("ALTER TABLE {book} ADD KEY nid (nid)"); + $ret[] = update_sql("ALTER TABLE {forum} ADD KEY nid (nid)"); + } + else { + $ret[] = update_sql("CREATE TABLE {node_revisions} ( + vid integer NOT NULL default '0', + nid integer NOT NULL default '0', + uid integer NOT NULL default '0', + title varchar(128) NOT NULL default '', + body text NOT NULL default '', + teaser text NOT NULL default '', + timestamp integer NOT NULL default '0', + format smallint NOT NULL default '0', + PRIMARY KEY (vid) + )"); + $ret[] = update_sql("ALTER TABLE {node} ADD vid integer NOT NULL default '0'"); + $ret[] = update_sql("ALTER TABLE {book} ADD vid integer NOT NULL default '0'"); + $ret[] = update_sql("ALTER TABLE {forum} ADD vid integer NOT NULL default '0'"); + $ret[] = update_sql("CREATE INDEX node_revisions_uid_idx ON node_revisions(uid)"); + $ret[] = update_sql("CREATE INDEX node_revisions_nid_idx ON node_revisions(nid)"); + $ret[] = update_sql("ALTER TABLE {book} DROP INDEX nid"); + $ret[] = update_sql("ALTER TABLE {forum} DROP INDEX nid"); +/* This needs to be ported to pgsql + $ret[] = update_sql("ALTER TABLE {book} ADD PRIMARY KEY vid (vid)"); + $ret[] = update_sql("ALTER TABLE {forum} ADD PRIMARY KEY vid (vid)"); + $ret[] = update_sql("ALTER TABLE {book} ADD KEY nid (nid)"); + $ret[] = update_sql("ALTER TABLE {forum} ADD KEY nid (nid)"); +*/ + } + + return $ret; +} + +function update_125() { + $ret = array(); + + $vid = 0; + $result = db_query("SELECT uid, type, title, body, teaser, changed, format, nid, revisions FROM {node}"); + while ($row = db_fetch_array($result)) { + $nid = $row['nid']; + $revisions = unserialize($row['revisions']); + if (is_array($revisions) && count($revisions) > 0) { + foreach ($revisions as $version) { + $revision = array(); + foreach ($version['node'] as $node_field => $node_value) { + $revision[$node_field] = $node_value; + } + $revision['uid'] = $version['uid']; + $revision['timestamp'] = $version['timestamp']; + $most_recent = max($revision['timestamp'], $most_recent); + $vid++; + db_query("INSERT INTO {node_revisions} (nid, vid, uid, title, body, teaser, timestamp, format) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d)", $nid, $vid, $revision['uid'], $revision['title'], $revision['body'], $revision['teaser'], $revision['timestamp'], $revision['format']); + switch ($row['type']) { + case 'forum': + db_query("INSERT INTO {forum} (vid, nid, tid) VALUES (%d, %d, %d)", $vid, $nid, $revision['tid']); + break; + case 'book': + db_query("INSERT INTO {book} (vid, nid, parent, weight, log) VALUES (%d, %d, %d, %d, '%s')", $vid, $nid, $revision['parent'], $revision['weight'], $revision['log']); + break; + } + } + $result_2 = db_fetch_object(db_query('SELECT nid, vid FROM {node_revisions} WHERE timestamp = %d', $most_recent)); + db_query("UPDATE {node} SET vid = %d WHERE nid = %d", $result_2->vid, $result_2->nid); + } + else { + $vid++; + db_query("INSERT INTO {node_revisions} (nid, vid, uid, title, body, teaser, timestamp, format) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d)", $nid, $vid, $row['uid'], $row['title'], $row['body'], $row['teaser'], $row['changed'], $row['format']); + switch ($row['type']) { + case 'forum': + db_query("UPDATE {forum} SET vid = %d WHERE nid = %d", $vid, $nid); + break; + case 'book': + db_query("UPDATE {book} SET vid = %d WHERE nid = %d", $vid, $nid); + break; + } + } + db_query("UPDATE {node} SET vid = %d WHERE nid = %d", $vid, $nid); + } + + // Other node types might be added to the book too. + $result = db_query('SELECT b.nid, r.vid, COUNT(r.vid) AS count, MAX(r.timestamp) AS most_recent FROM {book} b INNER JOIN {node_revisions} r ON b.nid = r.nid WHERE b.vid = 0'); + while ($row = db_fetch_object($result)) { + if ($row->count == 1) { + db_query("UPDATE {book} SET vid = %d WHERE nid = %d", $row->vid, $row->nid); + } + else { + $result_2 = db_fetch_object(db_query('SELECT vid FROM {node_revisions} WHERE timestamp = %d', $row->most_recent)); + db_query("UPDATE {book} SET vid = %d WHERE nid = %d", $result_2->vid, $row->nid); + } + } + + // There might be leftovers from old nodes in the book table. + // Don't know why, but they have to go. The new key cannot be unique otherwise. + update_sql('DELETE FROM {book} WHERE vid = 0'); + + if ($GLOBALS['db_type'] == 'mysql') { + $ret[] = update_sql("ALTER TABLE {book} ADD PRIMARY KEY vid (vid)"); + $ret[] = update_sql("ALTER TABLE {forum} ADD PRIMARY KEY vid (vid)"); + } + else { // pgsql update + } + $ret[] = update_sql("INSERT INTO {sequences} (name, id) VALUES ('{node_revisions}_vid', $vid)"); + $ret[] = update_sql("ALTER TABLE {node} DROP teaser"); + $ret[] = update_sql("ALTER TABLE {node} DROP body"); + $ret[] = update_sql("ALTER TABLE {node} DROP format"); return $ret; } Index: modules/blogapi.module =================================================================== RCS file: /cvs/drupal/drupal/modules/blogapi.module,v retrieving revision 1.37 diff -u -F^f -r1.37 blogapi.module --- modules/blogapi.module 31 Jan 2005 19:36:20 -0000 1.37 +++ modules/blogapi.module 2 Feb 2005 20:18:22 -0000 @@ -370,7 +370,12 @@ function blogapi_get_recent_posts($req_p } $type = _blogapi_blogid($params[0]); - $result = db_query_range('SELECT n.nid, n.title,'. ($bodies ? ' n.body,' : '') ." n.created, u.name FROM {node} n, {users} u WHERE n.uid=u.uid AND n.type = '%s' AND n.uid = %d ORDER BY n.created DESC", $type, $user->uid, 0, $params[3]); + if ($bodies) { + $result = db_query_range("SELECT n.nid, n.title, r.body, n.created, u.name FROM {node} n, {node_revisions} r, {users} u WHERE n.uid = u.uid AND n.vid = r.vid AND n.type = '%s' AND n.uid = %d ORDER BY n.created DESC", $type, $user->uid, 0, $params[3]); + } + else { + $result = db_query_range("SELECT n.nid, n.title, n.created, u.name FROM {node} n, {users} u WHERE n.uid = u.uid AND n.type = '%s' AND n.uid = %d ORDER BY n.created DESC", $type, $user->uid, 0, $params[3]); + } while ($blog = db_fetch_object($result)) { $xmlrpcval = _blogapi_get_post($blog, $bodies); $blogs[] = $xmlrpcval; Index: modules/book.module =================================================================== RCS file: /cvs/drupal/drupal/modules/book.module,v retrieving revision 1.283 diff -u -F^f -r1.283 book.module --- modules/book.module 30 Jan 2005 08:53:05 -0000 1.283 +++ modules/book.module 2 Feb 2005 20:18:22 -0000 @@ -106,7 +106,7 @@ function book_menu($may_cache) { // We don't want to cache these menu items because they could change whenever // a book page or outline node is edited. if (arg(0) == 'admin' && arg(1) == 'node' && arg(2) == 'book') { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = 0 ORDER BY b.weight, n.title')); + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = 0 ORDER BY b.weight, n.title')); while ($book = db_fetch_object($result)) { $items[] = array('path' => 'admin/node/book/'. $book->nid, 'title' => t('"%title" book', array('%title' => $book->title))); } @@ -131,7 +131,7 @@ function book_block($op = 'list', $delta else if ($op == 'view') { // Only display this block when the user is browsing a book: if (arg(0) == 'node' && is_numeric(arg(1))) { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.nid = %d'), arg(1)); + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.nid = %d'), arg(1)); if (db_num_rows($result) > 0) { $node = db_fetch_object($result); @@ -158,7 +158,7 @@ function book_block($op = 'list', $delta function book_load($node) { global $user; - $book = db_fetch_object(db_query('SELECT parent, weight, log FROM {book} WHERE nid = %d', $node->nid)); + $book = db_fetch_object(db_query('SELECT parent, weight, log FROM {book} WHERE vid = %d', $node->vid)); if (arg(2) == 'edit' && !user_access('administer nodes')) { // If a user is about to update a book page, we overload some @@ -180,14 +180,19 @@ function book_load($node) { * Implementation of hook_insert(). */ function book_insert($node) { - db_query("INSERT INTO {book} (nid, parent, weight, log) VALUES (%d, %d, %d, '%s')", $node->nid, $node->parent, $node->weight, $node->log); + db_query("INSERT INTO {book} (nid, vid, parent, weight, log) VALUES (%d, %d, %d, %d, '%s')", $node->nid, $node->vid, $node->parent, $node->weight, $node->log); } /** * Implementation of hook_update(). */ function book_update($node) { - db_query("UPDATE {book} SET parent = %d, weight = %d, log = '%s' WHERE nid = %d", $node->parent, $node->weight, $node->log, $node->nid); + if ($node->is_new || $node->revision) { + db_query("INSERT INTO {book} (nid, vid, parent, weight, log) VALUES (%d, %d, %d, %d, '%s')", $node->nid, $node->vid, $node->parent, $node->weight, $node->log); + } + else { + db_query("UPDATE {book} SET parent = %d, weight = %d, log = '%s' WHERE vid = %d", $node->parent, $node->weight, $node->log, $node->nid); + } } /** @@ -251,13 +256,13 @@ function book_outline() { if ($node->nid) { switch ($op) { case t('Add to book outline'): - db_query('INSERT INTO {book} (nid, parent, weight) VALUES (%d, %d, %d)', $node->nid, $edit['parent'], $edit['weight']); + db_query('INSERT INTO {book} (nid, vid, parent, weight) VALUES (%d, %d, %d, %d)', $node->nid, $node->vid, $edit['parent'], $edit['weight']); drupal_set_message(t('Added the post to the book.')); drupal_goto("node/$node->nid"); break; case t('Update book outline'): - db_query('UPDATE {book} SET parent = %d, weight = %d WHERE nid = %d', $edit['parent'], $edit['weight'], $node->nid); + db_query('UPDATE {book} SET parent = %d, weight = %d WHERE vid = %d', $edit['parent'], $edit['weight'], $node->vid); drupal_set_message(t('Updated the book outline.')); drupal_goto("node/$node->nid"); break; @@ -269,7 +274,7 @@ function book_outline() { break; default: - $page = db_fetch_object(db_query('SELECT * FROM {book} WHERE nid = %d', $node->nid)); + $page = db_fetch_object(db_query('SELECT * FROM {book} WHERE vid = %d', $node->vid)); $output = form_select(t('Parent'), 'parent', $page->parent, book_toc($node->nid), t('The parent page in the book.')); $output .= form_weight(t('Weight'), 'weight', $node->weight, 15, t('Pages at a given level are ordered first by weight and then by title.')); @@ -320,7 +325,7 @@ function book_revision_load($page, $cond * Return the path (call stack) to a certain book page. */ function book_location($node, $nodes = array()) { - $parent = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.nid = %d'), $node->parent)); + $parent = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.nid = %d'), $node->parent)); if ($parent->title) { $nodes = book_location($parent, $nodes); array_push($nodes, $parent); @@ -329,7 +334,7 @@ function book_location($node, $nodes = a } function book_location_down($node, $nodes = array()) { - $last_direct_child = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d ORDER BY b.weight DESC, n.title DESC'), $node->nid)); + $last_direct_child = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = %d ORDER BY b.weight DESC, n.title DESC'), $node->nid)); if ($last_direct_child) { array_push($nodes, $last_direct_child); $nodes = book_location_down($last_direct_child, $nodes); @@ -347,7 +352,7 @@ function book_prev($node) { } // Previous on the same level: - $direct_above = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight < %d OR (b.weight = %d AND n.title < '%s')) ORDER BY b.weight DESC, n.title DESC"), $node->parent, $node->weight, $node->weight, $node->title)); + $direct_above = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight < %d OR (b.weight = %d AND n.title < '%s')) ORDER BY b.weight DESC, n.title DESC"), $node->parent, $node->weight, $node->weight, $node->title)); if ($direct_above) { // Get last leaf of $above. $path = book_location_down($direct_above); @@ -356,7 +361,7 @@ function book_prev($node) { } else { // Direct parent: - $prev = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.nid = %d AND n.status = 1 AND n.moderate = 0'), $node->parent)); + $prev = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.nid = %d AND n.status = 1 AND n.moderate = 0'), $node->parent)); return $prev; } } @@ -366,7 +371,7 @@ function book_prev($node) { */ function book_next($node) { // get first direct child - $child = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 ORDER BY b.weight ASC, n.title ASC'), $node->nid)); + $child = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 ORDER BY b.weight ASC, n.title ASC'), $node->nid)); if ($child) { return $child; } @@ -375,7 +380,7 @@ function book_next($node) { array_push($path = book_location($node), $node); // Path to top-level node including this one. while (($leaf = array_pop($path)) && count($path)) { - $next = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight > %d OR (b.weight = %d AND n.title > '%s')) ORDER BY b.weight ASC, n.title ASC"), $leaf->parent, $leaf->weight, $leaf->weight, $leaf->title)); + $next = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight > %d OR (b.weight = %d AND n.title > '%s')) ORDER BY b.weight ASC, n.title ASC"), $leaf->parent, $leaf->weight, $leaf->weight, $leaf->title)); if ($next) { return $next; } @@ -425,7 +430,7 @@ function book_nodeapi(&$node, $op, $teas switch ($op) { case 'view': if (!$teaser) { - $book = db_fetch_array(db_query('SELECT * FROM {book} WHERE nid = %d', $node->nid)); + $book = db_fetch_array(db_query('SELECT * FROM {book} WHERE vid = %d', $node->vid)); if ($book) { foreach ($book as $key => $value) { @@ -513,7 +518,7 @@ function book_toc_recurse($nid, $indent, } function book_toc($exclude = 0) { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.status = 1 ORDER BY b.weight, n.title')); + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.status = 1 ORDER BY b.weight, n.title')); while ($node = db_fetch_object($result)) { if (!$children[$node->parent]) { @@ -566,7 +571,7 @@ function book_tree_recurse($nid, $depth, } function book_tree($parent = 0, $depth = 3, $unfold = array()) { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.status = 1 AND n.moderate = 0 ORDER BY b.weight, n.title')); + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.status = 1 AND n.moderate = 0 ORDER BY b.weight, n.title')); while ($node = db_fetch_object($result)) { $list = $children[$node->parent] ? $children[$node->parent] : array(); @@ -583,7 +588,7 @@ function book_tree($parent = 0, $depth = * Menu callback; prints a listing of all books. */ function book_render() { - $result = db_query(db_rewrite_sql('SELECT n.nid FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = 0 AND n.status = 1 AND n.moderate = 0 ORDER BY b.weight, n.title')); + $result = db_query(db_rewrite_sql('SELECT n.nid FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = 0 AND n.status = 1 AND n.moderate = 0 ORDER BY b.weight, n.title')); while ($page = db_fetch_object($result)) { // Load the node: @@ -609,7 +614,7 @@ function book_render() { */ function book_print($nid = 0, $depth = 1) { global $base_url; - $result = db_query(db_rewrite_sql('SELECT DISTINCT(n.nid), n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.status = 1 AND n.nid = %d AND n.moderate = 0 ORDER BY b.weight, n.title'), $nid); + $result = db_query(db_rewrite_sql('SELECT DISTINCT(n.nid), n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.status = 1 AND n.nid = %d AND n.moderate = 0 ORDER BY b.weight, n.title'), $nid); while ($page = db_fetch_object($result)) { // load the node: @@ -642,7 +647,7 @@ function book_print($nid = 0, $depth = 1 } function book_print_recurse($parent = '', $depth = 1) { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.status = 1 AND b.parent = %d AND n.moderate = 0 ORDER BY b.weight, n.title'), $parent); + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.status = 1 AND b.parent = %d AND n.moderate = 0 ORDER BY b.weight, n.title'), $parent); while ($page = db_fetch_object($result)) { // Load the node: @@ -679,7 +684,7 @@ function book_admin_view_line($node, $de } function book_admin_view_book($nid, $depth = 1) { - $result = db_query(db_rewrite_sql('SELECT n.nid FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d ORDER BY b.weight, n.title'), $nid); + $result = db_query(db_rewrite_sql('SELECT n.nid FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = %d ORDER BY b.weight, n.title'), $nid); while ($node = db_fetch_object($result)) { $node = node_load(array('nid' => $node->nid)); @@ -716,15 +721,16 @@ function book_admin_save($nid, $edit = a foreach ($edit as $nid => $value) { // Check to see whether the title needs updating: - $title = db_result(db_query('SELECT title FROM {node} WHERE nid = %d', $nid)); - if ($title != $value['title']) { + $node = db_fetch_object(db_query('SELECT title, vid FROM {node} WHERE nid = %d', $nid)); + if ($node->title != $value['title']) { db_query("UPDATE {node} SET title = '%s' WHERE nid = %d", $value['title'], $nid); + db_query("UPDATE {book} SET title = '%s' WHERE vid = %d", $value['title'], $node->vid); } // Check to see whether the weight needs updating: - $weight = db_result(db_query('SELECT weight FROM {book} WHERE nid = %d', $nid)); - if ($weight != $value['weight']) { - db_query('UPDATE {book} SET weight = %d WHERE nid = %d', $value['weight'], $nid); + $node = db_fetch_object(db_query('SELECT b.vid, b.weight FROM {book} b INNER JOIN {node} n ON n.vid = b.vid WHERE n.nid = %d', $nid)); + if ($node->weight != $value['weight']) { + db_query('UPDATE {book} SET weight = %d WHERE vid = %d', $value['weight'], $node->vid); } } @@ -739,7 +745,7 @@ function book_admin_save($nid, $edit = a * Menu callback; displays a listing of all orphaned book pages. */ function book_admin_orphan() { - $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, n.status, b.parent FROM {node} n INNER JOIN {book} b ON n.nid = b.nid')); + $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, n.status, b.parent FROM {node} n INNER JOIN {book} b ON v.nid = b.vid')); while ($page = db_fetch_object($result)) { $pages[$page->nid] = $page; Index: modules/forum.module =================================================================== RCS file: /cvs/drupal/drupal/modules/forum.module,v retrieving revision 1.227 diff -u -F^f -r1.227 forum.module --- modules/forum.module 29 Jan 2005 22:02:36 -0000 1.227 +++ modules/forum.module 2 Feb 2005 20:18:22 -0000 @@ -287,7 +287,7 @@ function forum_settings() { * Implementation of hook_load(). */ function forum_load($node) { - $forum = db_fetch_object(db_query('SELECT * FROM {forum} WHERE nid = %d', $node->nid)); + $forum = db_fetch_object(db_query('SELECT * FROM {forum} WHERE vid = %d', $node->vid)); return $forum; } @@ -475,7 +475,12 @@ function forum_validate(&$node) { * Implementation of hook_update(). */ function forum_update($node) { - db_query('UPDATE {forum} SET tid = %d WHERE nid = %d', $node->tid, $node->nid); + if ($node->is_new || $node->revision) { + db_query("INSERT INTO {forum} (nid, vid, tid) VALUES (%d, %d, %d)", $node->nid, $node->vid, $node->tid); + } + else { + db_query('UPDATE {forum} SET tid = %d WHERE vid = %d', $node->tid, $node->vid); + } } /** @@ -508,7 +513,7 @@ function forum_form(&$node) { * Implementation of hook_insert(). */ function forum_insert($node) { - db_query('INSERT INTO {forum} (nid, tid) VALUES (%d, %d)', $node->nid, $node->tid); + db_query('INSERT INTO {forum} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $node->tid); } /** @@ -633,7 +638,7 @@ function forum_get_topics($tid, $sortby, $term = taxonomy_get_term($tid); - $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, l.last_comment_timestamp, IF(l.last_comment_uid, cu.name, l.last_comment_name) AS last_comment_name, l.last_comment_uid, l.comment_count AS num_comments FROM {node} n, {node_comment_statistics} l, {users} cu, {term_node} r, {users} u, {forum} f 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.nid = f.nid"); + $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, l.last_comment_timestamp, IF(l.last_comment_uid, cu.name, l.last_comment_name) AS last_comment_name, l.last_comment_uid, l.comment_count AS num_comments FROM {node} n, {node_comment_statistics} l, {users} cu, {term_node} r, {users} u, {forum} f 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 = f.vid"); $sql .= tablesort_sql($forum_topic_list_header, 'n.sticky DESC,'); $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 AND n.type = 'forum'"); Index: modules/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node.module,v retrieving revision 1.458 diff -u -F^f -r1.458 node.module --- modules/node.module 2 Feb 2005 01:03:25 -0000 1.458 +++ modules/node.module 2 Feb 2005 20:18:22 -0000 @@ -389,31 +389,27 @@ function node_load($conditions, $revisio } // Retrieve the node. - $node = db_fetch_object(db_query('SELECT n.*, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid WHERE '. implode(' AND ', $cond))); - $node = drupal_unpack($node); - - // Unserialize the revisions and user data fields. - if ($node->revisions) { - $node->revisions = unserialize($node->revisions); + if ($revision) { + $node = db_fetch_object(db_query('SELECT n.nid, n.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.moderate, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.nid = n.nid AND r.vid = %d WHERE '. implode(' AND ', $cond), $revision)); } - - // Call the node specific callback (if any) and piggy-back the - // results to the node or overwrite some values. - if ($extra = node_invoke($node, 'load')) { - foreach ($extra as $key => $value) { - $node->$key = $value; - } + else { + $node = db_fetch_object(db_query('SELECT n.nid, n.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.moderate, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid WHERE '. implode(' AND ', $cond))); } - if ($extra = node_invoke_nodeapi($node, 'load')) { - foreach ($extra as $key => $value) { - $node->$key = $value; + if ($node->nid) { + // Call the node specific callback (if any) and piggy-back the + // results to the node or overwrite some values. + if ($extra = node_invoke($node, 'load')) { + foreach ($extra as $key => $value) { + $node->$key = $value; + } + } + + if ($extra = node_invoke_nodeapi($node, 'load')) { + foreach ($extra as $key => $value) { + $node->$key = $value; + } } - } - - // Return the desired revision. - if (!is_null($revision) && is_array($node->revisions[$revision])) { - $node = $node->revisions[$revision]['node']; } if ($cachable) { @@ -427,65 +423,100 @@ function node_load($conditions, $revisio * Save a node object into the database. */ function node_save($node) { - // Fetch fields to save to node table: - $fields = node_invoke_nodeapi($node, 'fields'); + global $user; - // Serialize the revisions field: - if ($node->revisions) { - $node->revisions = serialize($node->revisions); - } + $node->is_new = false; // Apply filters to some default node fields: if (empty($node->nid)) { // Insert a new node. + $node->is_new = true; // Set some required fields: if (!$node->created) { $node->created = time(); } - if (!$node->changed) { - $node->changed = time(); - } $node->nid = db_next_id('{node}_nid'); + $node->vid = db_next_id('{node_revisions}_vid');; + } + else { + // We need to ensure that all node fields are filled. + $node_current = node_load(array('nid' => $node->nid)); + foreach ($node as $field => $data) { + $node_current->$field = $data; + } + $node = $node_current; - // Prepare the query: - foreach ($node as $key => $value) { - if (in_array((string) $key, $fields)) { - $k[] = db_escape_string($key); - $v[] = $value; - $s[] = "'%s'"; - } + if ($node->revision) { + $node->vid = db_next_id('{node_revisions}_vid');; } + } - $keysfmt = implode(', ', $s); - // We need to quote the placeholders for the values. - $valsfmt = "'". implode("', '", $s) ."'"; - // Insert the node into the database: - db_query("INSERT INTO {node} (". implode(", ", $k) .") VALUES(". implode(", ", $s) .")", $v); + if (!$node->changed) { + $node->changed = time(); + } - // Call the node specific callback (if any): - node_invoke($node, 'insert'); - node_invoke_nodeapi($node, 'insert'); + // Split off revisions data to another structure + $revisions_table_values = array('nid' => $node->nid, 'vid' => $node->vid, + 'title' => $node->title, 'body' => $node->body, + 'teaser' => $node->teaser, 'changed' => $node->changed, + 'uid' => $user->uid, 'format' => $node->format); + $revisions_table_types = array('nid' => '%d', 'vid' => '%d', + 'title' => "'%s'", 'body' => "'%s'", + 'teaser' => "'%s'", 'changed' => '%d', + 'uid' => '%d', 'format' => '%d'); + $node_table_values = array('nid' => $node->nid, 'vid' => $node->vid, + 'title' => $node->title, 'type' => $node->type, 'uid' => $node->uid, + 'status' => $node->status, 'created' => $node->created, + 'changed' => $node->changed, 'comment' => $node->comment, + 'promote' => $node->promote, 'moderate' => $node->moderate, + 'sticky' => $node->sticky); + $node_table_types = array('nid' => '%d', 'vid' => '%d', + 'title' => "'%s'", 'type' => "'%s'", 'uid' => '%d', + 'status' => '%d', 'created' => '%d', + 'changed' => '%d', 'comment' => '%d', + 'promote' => '%d', 'moderate' => '%d', + 'sticky' => '%d'); + + //Generate the node table query + if ($node->is_new) { + $node_query = 'INSERT INTO {node} ('. implode(', ', array_keys($node_table_types)) .') VALUES ('. implode(', ', $node_table_types) .')'; + $revisions_query = 'INSERT INTO {node_revisions} ('. implode(', ', array_keys($revisions_table_types)) .') VALUES ('. implode(', ', array_keys($revisions_table_types)) .')'; } else { - // Update an existing node. - - // Set some required fields: - $node->changed = time(); - - // Prepare the query: - foreach ($node as $key => $value) { - if (in_array($key, $fields)) { - $q[] = db_escape_string($key) ." = '%s'"; - $v[] = $value; + $arr = array(); + foreach ($node_table_types as $key => $value) { + $arr[] = $key .' = '. $value; + } + $node_table_values[] = $node->nid; + $node_query = 'UPDATE {node} SET '. implode(', ', $arr) .' WHERE nid = %d'; + if ($node->revision) { + $revisions_query = 'INSERT INTO {node_revisions} ('. implode(', ', array_keys($revisions_table_types)) .') VALUES ('. implode(', ', array_keys($revisions_table_types)) .')'; + } + else { + foreach ($revisions_table_types as $key => $value) { + $arr[] = $key .' = '. $value; } + $revisions_table_values[] = $node->vid; + $revisions_query = 'UPDATE {node_revisions} SET '. implode(', ', $arr) .' WHERE vid = %d'; } + } + + //Generate the node_revisions table query - // Update the node in the database: - db_query("UPDATE {node} SET ". implode(', ', $q) ." WHERE nid = '$node->nid'", $v); + // Insert the node into the database: + db_begin_transaction(array('node', 'node_revisions', 'watchdog', 'sessions')); + db_query($node_query, $node_table_values); + db_query($revisions_query, $revisions_table_values); + db_commit_transaction(); - // Call the node specific callback (if any): + // Call the node specific callback (if any): + if ($node->is_new) { + node_invoke($node, 'insert'); + node_invoke_nodeapi($node, 'insert'); + } + else { node_invoke($node, 'update'); node_invoke_nodeapi($node, 'update'); } @@ -708,14 +739,11 @@ function node_menu($may_cache) { 'access' => node_access('update', $node), 'weight' => 1, 'type' => MENU_LOCAL_TASK); - - if ($node->revisions) { - $items[] = array('path' => 'node/'. arg(1) .'/revisions', 'title' => t('revisions'), - 'callback' => 'node_page', - 'access' => user_access('administer nodes'), - 'weight' => 2, - 'type' => MENU_LOCAL_TASK); - } + $items[] = array('path' => 'node/'. arg(1) .'/revisions', 'title' => t('revisions'), + 'callback' => 'node_page', + 'access' => user_access('administer nodes'), + 'weight' => 2, + 'type' => MENU_LOCAL_TASK); } } else if (arg(0) == 'admin' && arg(1) == 'node' && arg(2) == 'configure' && arg(3) == 'types' && is_string(arg(4))) { @@ -983,11 +1011,18 @@ function node_revision_overview($nid) { drupal_set_title($node->title); - if ($node->revisions) { + if ($node->vid) { $header = array(t('Older revisions'), array('colspan' => '3', 'data' => t('Operations'))); - foreach ($node->revisions as $key => $revision) { - $rows[] = array(t('revision #%r revised by %u on %d', array('%r' => $key, '%u' => format_name(user_load(array('uid' => $revision['uid']))), '%d' => format_date($revision['timestamp'], 'small'))) . ($revision['history'] ? '
'. $revision['history'] .'' : ''), l(t('view'), "node/$node->nid", array(), "revision=$key"), l(t('rollback'), "node/$node->nid/rollback-revision/$key"), l(t('delete'), "node/$node->nid/delete-revision/$key")); + $revisions = node_revision_list($node); + + $i = 0; + foreach ($revisions as $key => $revision) { + $rows[] = array( + t('revision #%r revised by %u on %d', array('%r' => ++$i, '%u' => format_name($revision), '%d' => format_date($revision->timestamp, 'small'))) . ($revision->title ? '
'. $revision->title .'' : ''), + l(t('view'), "node/$node->nid/revision/". $revision->vid), + l(t('rollback'), "node/$node->nid/rollback-revision/". $revision->vid), + l(t('delete'), "node/$node->nid/delete-revision/". $revision->vid)); } $output .= theme('table', $header, $rows); } @@ -996,32 +1031,6 @@ function node_revision_overview($nid) { return $output; } - -/** - * Return the revision with the specified revision number. - */ -function node_revision_load($node, $revision) { - return $node->revisions[$revision]['node']; -} - -/** - * Create and return a new revision of the given node. - */ -function node_revision_create($node) { - global $user; - - // "Revision" is the name of the field used to indicate that we have to - // create a new revision of a node. - if ($node->nid && $node->revision) { - $prev = node_load(array('nid' => $node->nid)); - $node->revisions = $prev->revisions; - unset($prev->revisions); - $node->revisions[] = array('uid' => $user->uid, 'timestamp' => time(), 'node' => $prev, 'history' => $node->history); - } - - return $node; -} - /** * Roll back to the revision with the specified revision number. */ @@ -1029,29 +1038,13 @@ function node_revision_rollback($nid, $r global $user; if (user_access('administer nodes')) { - $node = node_load(array('nid' => $nid)); - - // Extract the specified revision: - $rev = $node->revisions[$revision]['node']; - - // Inherit all the past revisions: - $rev->revisions = $node->revisions; - // Save the original/current node: - $rev->revisions[] = array('uid' => $user->uid, 'timestamp' => time(), 'node' => $node); + $node = node_load(array('nid' => $nid), $revision); - // Remove the specified revision: - unset($rev->revisions[$revision]); + node_save($node); - // Save the node: - foreach ($node as $key => $value) { - $filter[] = $key; - } - - node_save($rev, $filter); - - drupal_set_message(t('Rolled back to revision %revision of %title', array('%revision' => "#$revision", '%title' => "$node->title"))); - drupal_goto('node/'. $nid .'/revisions'); + drupal_set_message(t('Rolled back to the revision with the ID %revision of %title', array('%revision' => "$revision", '%title' => "$node->title"))); + drupal_goto("node/$nid/revisions"); } } @@ -1060,14 +1053,22 @@ function node_revision_rollback($nid, $r */ function node_revision_delete($nid, $revision) { if (user_access('administer nodes')) { + // Start a transaction so that the current node and node count + // don't change between the time we load it from the database and + // delete the node + db_begin_transaction(array('node', 'node_revisions', 'watchdog', 'sessions')); $node = node_load(array('nid' => $nid)); + $revisions = node_revision_list($node); - unset($node->revisions[$revision]); + // Don't delete the last revision of the node or the current revision + if ((count($revisions) > 0) && ($revision != $node->vid)) { + db_query("DELETE FROM {node_revisions} WHERE nid = %d AND vid = %d", array($nid, $revision)); + } - node_save($node, array('nid', 'revisions')); + db_commit_transaction(); - drupal_set_message(t('Deleted revision %revision of %title', array('%revision' => "#$revision", '%title' => "$node->title"))); - drupal_goto('node/'. $nid . (count($node->revisions) ? '/revisions' : '')); + drupal_set_message(t('Deleted revision with the ID %revision of %title', array('%revision' => "$revision", '%title' => "$node->title"))); + drupal_goto("node/$nid/revisions"); } } @@ -1075,12 +1076,13 @@ function node_revision_delete($nid, $rev * Return a list of all the existing revision numbers. */ function node_revision_list($node) { - if (is_array($node->revisions)) { - return array_keys($node->revisions); - } - else { - return array(); + $revisions = array(); + $result = db_query('SELECT r.vid, r.title, r.uid, r.timestamp, u.name FROM {node_revisions} r INNER JOIN {users} u ON u.uid = r.uid WHERE r.nid = %d AND r.vid != %d ORDER BY r.timestamp ASC', $node->nid, $node->vid); + while ($revision = db_fetch_object($result)) { + $revisions[] = $revision; } + + return $revisions; } /** @@ -1212,9 +1214,6 @@ function node_validate($node) { form_set_error('changed', t('This content has been modified by another user, unable to save changes.')); } - // Create a new revision when required. - $node = node_revision_create($node); - if (user_access('administer nodes')) { // Set up default values, if required. if (!$node->created) { @@ -1570,8 +1569,12 @@ function node_delete($edit) { if (node_access('delete', $node)) { if ($edit['confirm']) { - // Delete the specified node: + // Delete the specified node: + // We don't need to lock this in a transaction because once the + // entry in node disappears, the entry in node_revisions won't be + // accessable db_query('DELETE FROM {node} WHERE nid = %d', $node->nid); + db_query('DELETE FROM {node_revisions} WHERE nid = %d', $node->nid); // Call the node-specific callback (if any): node_invoke($node, 'delete'); @@ -1657,9 +1660,21 @@ function node_page() { case 'delete-revision': node_revision_delete(arg(1), arg(3)); break; + case 'revision': + if (is_numeric(arg(1)) && is_numeric(arg(3))) { + $node = node_load(array('nid' => arg(1)), arg(3)); + if ($node->nid) { + drupal_set_title($node->title); + print theme('page', node_show($node, arg(2))); + } + else { + drupal_not_found(); + } + } + break; case 'view': if (is_numeric(arg(1))) { - $node = node_load(array('nid' => arg(1)), $_GET['revision']); + $node = node_load(array('nid' => arg(1))); if ($node->nid) { drupal_set_title($node->title); print theme('page', node_show($node, arg(2))); @@ -1747,9 +1762,6 @@ function node_nodeapi(&$node, $op, $arg switch ($op) { case 'settings': return form_checkboxes(t('Default options'), 'node_options_'. $node->type, variable_get('node_options_'. $node->type, array('status', 'promote')), array('status' => t('Published'), 'moderate' => t('In moderation queue'), 'promote' => t('Promoted to front page'), 'sticky' => t('Sticky at top of lists'), 'revision' => t('Create new revision')), t('Users with the administer nodes permission will be able to override these options.')); - - case 'fields': - return array('nid', 'uid', 'type', 'title', 'teaser', 'body', 'revisions', 'status', 'promote', 'moderate', 'sticky', 'created', 'changed', 'format'); } } Index: modules/taxonomy.module =================================================================== RCS file: /cvs/drupal/drupal/modules/taxonomy.module,v retrieving revision 1.175 diff -u -F^f -r1.175 taxonomy.module --- modules/taxonomy.module 2 Feb 2005 00:55:59 -0000 1.175 +++ modules/taxonomy.module 2 Feb 2005 20:18:22 -0000 @@ -473,15 +473,6 @@ function taxonomy_node_form($type, $node } /** - * Determine whether a node mentions the name of a term. - */ -function taxonomy_node_has_term($nid, $tid) { - $term_name = db_result(db_query('SELECT name FROM {term_data} WHERE tid = %d', $tid)); - - return db_result(db_query("SELECT COUNT(n.nid) FROM {node} n WHERE n.nid = %d AND ((n.title LIKE '%%%s%%') OR (n.body LIKE '%%%s%%'))", $nid, $term_name, $term_name)); -} - -/** * Find all terms associated to the given node, within one vocabulary. */ function taxonomy_node_get_terms_by_vocabulary($nid, $vid, $key = 'tid') {