File Annotation
Not logged in
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** Copyright (c) 2007 D. Richard Hipp
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** This program is free software; you can redistribute it and/or
dbda8d6ce9 2007-07-21       drh: ** modify it under the terms of the GNU General Public
dbda8d6ce9 2007-07-21       drh: ** License version 2 as published by the Free Software Foundation.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** This program is distributed in the hope that it will be useful,
dbda8d6ce9 2007-07-21       drh: ** but WITHOUT ANY WARRANTY; without even the implied warranty of
dbda8d6ce9 2007-07-21       drh: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
dbda8d6ce9 2007-07-21       drh: ** General Public License for more details.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** You should have received a copy of the GNU General Public
dbda8d6ce9 2007-07-21       drh: ** License along with this library; if not, write to the
dbda8d6ce9 2007-07-21       drh: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
dbda8d6ce9 2007-07-21       drh: ** Boston, MA  02111-1307, USA.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** Author contact information:
dbda8d6ce9 2007-07-21       drh: **   drh@hwaci.com
dbda8d6ce9 2007-07-21       drh: **   http://www.hwaci.com/drh/
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: *******************************************************************************
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** This file contains code to implement the "info" command.  The
dbda8d6ce9 2007-07-21       drh: ** "info" command gives command-line access to information about
dbda8d6ce9 2007-07-21       drh: ** the current tree, or a particular file or version.
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: #include "config.h"
dbda8d6ce9 2007-07-21       drh: #include "info.h"
dbda8d6ce9 2007-07-21       drh: #include <assert.h>
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** Print common information about a particular record.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: **     *  The UUID
dbda8d6ce9 2007-07-21       drh: **     *  The record ID
dbda8d6ce9 2007-07-21       drh: **     *  mtime and ctime
dbda8d6ce9 2007-07-21       drh: **     *  who signed it
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: void show_common_info(int rid, const char *zUuidName, int showComment){
dbda8d6ce9 2007-07-21       drh:   Stmt q;
dbda8d6ce9 2007-07-21       drh:   char *zComment = 0;
dbda8d6ce9 2007-07-21       drh:   db_prepare(&q,
dbda8d6ce9 2007-07-21       drh:     "SELECT uuid"
dbda8d6ce9 2007-07-21       drh:     "  FROM blob WHERE rid=%d", rid
dbda8d6ce9 2007-07-21       drh:   );
dbda8d6ce9 2007-07-21       drh:   if( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:          /* 01234567890123 */
dbda8d6ce9 2007-07-21       drh:     printf("%-13s %s\n", zUuidName, db_column_text(&q, 0));
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh:   db_prepare(&q, "SELECT uuid FROM plink JOIN blob ON pid=rid "
dbda8d6ce9 2007-07-21       drh:                  " WHERE cid=%d", rid);
dbda8d6ce9 2007-07-21       drh:   while( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     const char *zUuid = db_column_text(&q, 0);
dbda8d6ce9 2007-07-21       drh:     printf("parent:       %s\n", zUuid);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh:   db_prepare(&q, "SELECT uuid FROM plink JOIN blob ON cid=rid "
dbda8d6ce9 2007-07-21       drh:                  " WHERE pid=%d", rid);
dbda8d6ce9 2007-07-21       drh:   while( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     const char *zUuid = db_column_text(&q, 0);
dbda8d6ce9 2007-07-21       drh:     printf("child:        %s\n", zUuid);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh:   if( zComment ){
dbda8d6ce9 2007-07-21       drh:     printf("comment:\n%s\n", zComment);
dbda8d6ce9 2007-07-21       drh:     free(zComment);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh: }
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** COMMAND: info
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** With no arguments, provide information about the current tree.
dbda8d6ce9 2007-07-21       drh: ** If an argument is given, provide information about the record
dbda8d6ce9 2007-07-21       drh: ** that the argument refers to.
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: void info_cmd(void){
dbda8d6ce9 2007-07-21       drh:   if( g.argc!=2 && g.argc!=3 ){
dbda8d6ce9 2007-07-21       drh:     usage("?FILEID|UUID?");
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_must_be_within_tree();
dbda8d6ce9 2007-07-21       drh:   if( g.argc==2 ){
dbda8d6ce9 2007-07-21       drh:     int vid;
dbda8d6ce9 2007-07-21       drh:          /* 012345678901234 */
dbda8d6ce9 2007-07-21       drh:     printf("repository:   %s\n", db_lget("repository", ""));
dbda8d6ce9 2007-07-21       drh:     printf("local-root:   %s\n", g.zLocalRoot);
dbda8d6ce9 2007-07-21       drh:     printf("project-code: %s\n", db_get("project-code", ""));
dbda8d6ce9 2007-07-21       drh:     printf("server-code:  %s\n", db_get("server-code", ""));
dbda8d6ce9 2007-07-21       drh:     vid = db_lget_int("checkout", 0);
dbda8d6ce9 2007-07-21       drh:     if( vid==0 ){
dbda8d6ce9 2007-07-21       drh:       printf("checkout:     nil\n");
dbda8d6ce9 2007-07-21       drh:     }else{
dbda8d6ce9 2007-07-21       drh:       show_common_info(vid, "checkout:", 1);
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:   }else{
dbda8d6ce9 2007-07-21       drh:     int rid = name_to_rid(g.argv[2]);
dbda8d6ce9 2007-07-21       drh:     if( rid==0 ){
dbda8d6ce9 2007-07-21       drh:       fossil_panic("no such object: %s\n", g.argv[2]);
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:     show_common_info(rid, "uuid:", 1);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh: }
dbda8d6ce9 2007-07-21       drh: 
30d7afe328 2007-08-01       drh: /*
30d7afe328 2007-08-01       drh: ** Show information about descendents of a version.  Do this recursively
30d7afe328 2007-08-01       drh: ** to a depth of N.  Return true if descendents are shown and false if not.
30d7afe328 2007-08-01       drh: */
30d7afe328 2007-08-01       drh: static int showDescendents(int pid, int depth){
30d7afe328 2007-08-01       drh:   Stmt q;
30d7afe328 2007-08-01       drh:   int cnt = 0;
30d7afe328 2007-08-01       drh:   db_prepare(&q,
30d7afe328 2007-08-01       drh:     "SELECT plink.cid, blob.uuid, datetime(plink.mtime),"
30d7afe328 2007-08-01       drh:     "       event.user, event.comment"
30d7afe328 2007-08-01       drh:     "  FROM plink, blob, event"
30d7afe328 2007-08-01       drh:     " WHERE plink.pid=%d"
30d7afe328 2007-08-01       drh:     "   AND blob.rid=plink.cid"
30d7afe328 2007-08-01       drh:     "   AND event.objid=plink.cid"
30d7afe328 2007-08-01       drh:     " ORDER BY plink.mtime ASC",
30d7afe328 2007-08-01       drh:     pid
30d7afe328 2007-08-01       drh:   );
30d7afe328 2007-08-01       drh:   while( db_step(&q)==SQLITE_ROW ){
30d7afe328 2007-08-01       drh:     int n;
30d7afe328 2007-08-01       drh:     int cid = db_column_int(&q, 0);
30d7afe328 2007-08-01       drh:     const char *zUuid = db_column_text(&q, 1);
30d7afe328 2007-08-01       drh:     const char *zDate = db_column_text(&q, 2);
30d7afe328 2007-08-01       drh:     const char *zUser = db_column_text(&q, 3);
30d7afe328 2007-08-01       drh:     const char *zCom = db_column_text(&q, 4);
30d7afe328 2007-08-01       drh:     cnt++;
30d7afe328 2007-08-01       drh:     if( cnt==1 ){
30d7afe328 2007-08-01       drh:       @ <ul>
30d7afe328 2007-08-01       drh:     }
30d7afe328 2007-08-01       drh:     @ <li>
30d7afe328 2007-08-01       drh:     hyperlink_to_uuid(zUuid);
30d7afe328 2007-08-01       drh:     @ %s(zCom) (by %s(zUser) on %s(zDate))
30d7afe328 2007-08-01       drh:     if( depth ){
30d7afe328 2007-08-01       drh:       n = showDescendents(cid, depth-1);
30d7afe328 2007-08-01       drh:     }else{
30d7afe328 2007-08-01       drh:       n = db_int(0, "SELECT 1 FROM plink WHERE pid=%d", cid);
30d7afe328 2007-08-01       drh:     }
30d7afe328 2007-08-01       drh:     if( n==0 ){
30d7afe328 2007-08-01       drh:       @ <b>leaf</b>
30d7afe328 2007-08-01       drh:     }
30d7afe328 2007-08-01       drh:   }
30d7afe328 2007-08-01       drh:   if( cnt ){
30d7afe328 2007-08-01       drh:     @ </ul>
30d7afe328 2007-08-01       drh:   }
30d7afe328 2007-08-01       drh:   return cnt;
30d7afe328 2007-08-01       drh: }
30d7afe328 2007-08-01       drh: 
30d7afe328 2007-08-01       drh: /*
30d7afe328 2007-08-01       drh: ** Show information about ancestors of a version.  Do this recursively
30d7afe328 2007-08-01       drh: ** to a depth of N.  Return true if ancestors are shown and false if not.
30d7afe328 2007-08-01       drh: */
30d7afe328 2007-08-01       drh: static int showAncestors(int pid, int depth){
30d7afe328 2007-08-01       drh:   Stmt q;
30d7afe328 2007-08-01       drh:   int cnt = 0;
30d7afe328 2007-08-01       drh:   db_prepare(&q,
30d7afe328 2007-08-01       drh:     "SELECT plink.pid, blob.uuid, datetime(event.mtime),"
30d7afe328 2007-08-01       drh:     "       event.user, event.comment"
30d7afe328 2007-08-01       drh:     "  FROM plink, blob, event"
30d7afe328 2007-08-01       drh:     " WHERE plink.cid=%d"
30d7afe328 2007-08-01       drh:     "   AND blob.rid=plink.pid"
30d7afe328 2007-08-01       drh:     "   AND event.objid=plink.pid"
30d7afe328 2007-08-01       drh:     " ORDER BY event.mtime DESC",
30d7afe328 2007-08-01       drh:     pid
30d7afe328 2007-08-01       drh:   );
30d7afe328 2007-08-01       drh:   @ <ul>
30d7afe328 2007-08-01       drh:   while( db_step(&q)==SQLITE_ROW ){
30d7afe328 2007-08-01       drh:     int n;
30d7afe328 2007-08-01       drh:     int cid = db_column_int(&q, 0);
30d7afe328 2007-08-01       drh:     const char *zUuid = db_column_text(&q, 1);
30d7afe328 2007-08-01       drh:     const char *zDate = db_column_text(&q, 2);
30d7afe328 2007-08-01       drh:     const char *zUser = db_column_text(&q, 3);
30d7afe328 2007-08-01       drh:     const char *zCom = db_column_text(&q, 4);
30d7afe328 2007-08-01       drh:     cnt++;
30d7afe328 2007-08-01       drh:     @ <li>
30d7afe328 2007-08-01       drh:     hyperlink_to_uuid(zUuid);
30d7afe328 2007-08-01       drh:     @ %s(zCom) (by %s(zUser) on %s(zDate))
30d7afe328 2007-08-01       drh:     if( depth ){
30d7afe328 2007-08-01       drh:       showAncestors(cid, depth-1);
30d7afe328 2007-08-01       drh:     }
30d7afe328 2007-08-01       drh:   }
30d7afe328 2007-08-01       drh:   @ </ul>
30d7afe328 2007-08-01       drh:   return cnt;
30d7afe328 2007-08-01       drh: }
30d7afe328 2007-08-01       drh: 
3dcaed8d86 2007-07-28       dan: /*
3dcaed8d86 2007-07-28       dan: ** WEBPAGE: vinfo
3dcaed8d86 2007-07-28       dan: **
3dcaed8d86 2007-07-28       dan: ** Return information about a version.  The version number is contained
3dcaed8d86 2007-07-28       dan: ** in g.zExtra.
3dcaed8d86 2007-07-28       dan: */
3dcaed8d86 2007-07-28       dan: void vinfo_page(void){
3dcaed8d86 2007-07-28       dan:   Stmt q;
3dcaed8d86 2007-07-28       dan:   int rid;
30d7afe328 2007-08-01       drh:   int isLeaf;
30d7afe328 2007-08-01       drh:   int cid, pid, n;
30d7afe328 2007-08-01       drh: 
30d7afe328 2007-08-01       drh:   login_check_credentials();
30d7afe328 2007-08-01       drh:   if( !g.okHistory ){ login_needed(); return; }
30d7afe328 2007-08-01       drh:   style_header("Version Information");
30d7afe328 2007-08-01       drh:   rid = name_to_rid(g.zExtra);
30d7afe328 2007-08-01       drh:   if( rid==0 ){
30d7afe328 2007-08-01       drh:     @ No such object: %h(g.argv[2])
30d7afe328 2007-08-01       drh:     style_footer();
30d7afe328 2007-08-01       drh:     return;
30d7afe328 2007-08-01       drh:   }
30d7afe328 2007-08-01       drh:   isLeaf = !db_exists("SELECT 1 FROM plink WHERE pid=%d", rid);
30d7afe328 2007-08-01       drh:   db_prepare(&q,
30d7afe328 2007-08-01       drh:      "SELECT uuid, datetime(mtime), user, comment"
30d7afe328 2007-08-01       drh:      "  FROM blob, event"
30d7afe328 2007-08-01       drh:      " WHERE blob.rid=%d"
30d7afe328 2007-08-01       drh:      "   AND event.objid=%d",
30d7afe328 2007-08-01       drh:      rid, rid
30d7afe328 2007-08-01       drh:   );
30d7afe328 2007-08-01       drh:   if( db_step(&q)==SQLITE_ROW ){
30d7afe328 2007-08-01       drh:     @ <h2>Version %s(db_column_text(&q,0))</h2>
30d7afe328 2007-08-01       drh:     @ <ul>
30d7afe328 2007-08-01       drh:     @ <li><b>Date:</b> %s(db_column_text(&q, 1))</li>
30d7afe328 2007-08-01       drh:     @ <li><b>User:</b> %s(db_column_text(&q, 2))</li>
30d7afe328 2007-08-01       drh:     @ <li><b>Comment:</b> %s(db_column_text(&q, 3))</li>
30d7afe328 2007-08-01       drh:     @ </ul>
30d7afe328 2007-08-01       drh:   }
30d7afe328 2007-08-01       drh:   db_finalize(&q);
30d7afe328 2007-08-01       drh:   @ <p><h2>Descendents:</h2>
30d7afe328 2007-08-01       drh:   n = showDescendents(rid, 2);
30d7afe328 2007-08-01       drh:   if( n==0 ){
30d7afe328 2007-08-01       drh:     @ <ul>None.  This is a leaf node.</ul>
30d7afe328 2007-08-01       drh:   }
30d7afe328 2007-08-01       drh:   @ <p><h2>Ancestors:</h2>
30d7afe328 2007-08-01       drh:   n = showAncestors(rid, 2);
30d7afe328 2007-08-01       drh:   if( n==0 ){
30d7afe328 2007-08-01       drh:     @ <ul>None.  This is the root of the tree.</ul>
30d7afe328 2007-08-01       drh:   }
30d7afe328 2007-08-01       drh:   @ <p><h2>Changes:</h2>
30d7afe328 2007-08-01       drh:   @ <ul>
30d7afe328 2007-08-01       drh:   db_prepare(&q,
30d7afe328 2007-08-01       drh:      "SELECT name, pid, fid"
30d7afe328 2007-08-01       drh:      "  FROM mlink, filename"
30d7afe328 2007-08-01       drh:      " WHERE mid=%d"
30d7afe328 2007-08-01       drh:      "   AND filename.fnid=mlink.fnid",
30d7afe328 2007-08-01       drh:      rid
30d7afe328 2007-08-01       drh:   );
30d7afe328 2007-08-01       drh:   while( db_step(&q)==SQLITE_ROW ){
30d7afe328 2007-08-01       drh:     const char *zName = db_column_text(&q, 0);
30d7afe328 2007-08-01       drh:     int pid = db_column_int(&q, 1);
30d7afe328 2007-08-01       drh:     int fid = db_column_int(&q, 2);
30d7afe328 2007-08-01       drh:     @ <li>
30d7afe328 2007-08-01       drh:     if( pid && fid ){
30d7afe328 2007-08-01       drh:       @ <b>Modified:</b>
30d7afe328 2007-08-01       drh:     }else if( fid ){
30d7afe328 2007-08-01       drh:       @ <b>Added:</b>
30d7afe328 2007-08-01       drh:     }else{
30d7afe328 2007-08-01       drh:       @ <b>Deleted:</b>
30d7afe328 2007-08-01       drh:     }
30d7afe328 2007-08-01       drh:     @ %h(zName)</li>
30d7afe328 2007-08-01       drh:   }
30d7afe328 2007-08-01       drh:   @ </ul>
30d7afe328 2007-08-01       drh:   style_footer();
30d7afe328 2007-08-01       drh: }
30d7afe328 2007-08-01       drh: 
30d7afe328 2007-08-01       drh: 
dbda8d6ce9 2007-07-21       drh: #if 0
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** WEB PAGE: vinfo
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** Return information about a version.  The version number is contained
dbda8d6ce9 2007-07-21       drh: ** in g.zExtra.
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: void vinfo_page(void){
dbda8d6ce9 2007-07-21       drh:   Stmt q;
dbda8d6ce9 2007-07-21       drh:   int rid;
dbda8d6ce9 2007-07-21       drh:   char cType;
dbda8d6ce9 2007-07-21       drh:   char *zType;
dbda8d6ce9 2007-07-21       drh: 
fd36718ad9 2007-07-31       drh:   login_check_credentials();
fd36718ad9 2007-07-31       drh:   if( !g.okHistory ){ login_needed(); return; }
66f4caa379 2007-07-23       drh:   style_header("Version Information");
dbda8d6ce9 2007-07-21       drh:   rid = name_to_rid(g.zExtra);
dbda8d6ce9 2007-07-21       drh:   if( rid==0 ){
dbda8d6ce9 2007-07-21       drh:     @ No such object: %h(g.argv[2])
dbda8d6ce9 2007-07-21       drh:     style_footer();
dbda8d6ce9 2007-07-21       drh:     return;
dbda8d6ce9 2007-07-21       drh:   }
3dcaed8d86 2007-07-28       dan:   db_row_to_table("SELECT "
3dcaed8d86 2007-07-28       dan:     "  blob.uuid               AS \"UUID\""
3dcaed8d86 2007-07-28       dan:     ", datetime(rcvfrom.mtime) AS \"Created\""
3dcaed8d86 2007-07-28       dan:     ", rcvfrom.uid             AS \"User Id\""
3dcaed8d86 2007-07-28       dan:     ", blob.size               AS \"Size\""
3dcaed8d86 2007-07-28       dan:     "FROM blob, rcvfrom "
3dcaed8d86 2007-07-28       dan:     "WHERE rid=%d", rid
3dcaed8d86 2007-07-28       dan:   );
3dcaed8d86 2007-07-28       dan:   style_footer();
3dcaed8d86 2007-07-28       dan:   return;
3dcaed8d86 2007-07-28       dan: 
dbda8d6ce9 2007-07-21       drh:   db_prepare(&q,
3dcaed8d86 2007-07-28       dan:     "SELECT "
3dcaed8d86 2007-07-28       dan:       "uuid, "                                         /* 0 */
3dcaed8d86 2007-07-28       dan:       "datetime(mtime,'unixepoch'),"                   /* 1 */
3dcaed8d86 2007-07-28       dan:       "datetime(ctime,'unixepoch'),"                   /* 2 */
3dcaed8d86 2007-07-28       dan:       "uid, size, cksum, branch, comment, type"        /* 3..8 */
3dcaed8d86 2007-07-28       dan:     "FROM record WHERE rid=%d", rid
dbda8d6ce9 2007-07-21       drh:   );
dbda8d6ce9 2007-07-21       drh:   if( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     const char *z;
dbda8d6ce9 2007-07-21       drh:     const char *zSignedBy = db_text("unknown",
dbda8d6ce9 2007-07-21       drh:                                      "SELECT login FROM repuser WHERE uid=%d",
dbda8d6ce9 2007-07-21       drh:                                      db_column_int(&q, 3));
dbda8d6ce9 2007-07-21       drh:     cType = db_column_text(&q,8)[0];
dbda8d6ce9 2007-07-21       drh:     switch( cType ){
dbda8d6ce9 2007-07-21       drh:       case 'f':  zType = "file";        break;
dbda8d6ce9 2007-07-21       drh:       case 'v':  zType = "version";     break;
dbda8d6ce9 2007-07-21       drh:       case 'c':  zType = "control";     break;
dbda8d6ce9 2007-07-21       drh:       case 'w':  zType = "wiki";        break;
dbda8d6ce9 2007-07-21       drh:       case 'a':  zType = "attachment";  break;
dbda8d6ce9 2007-07-21       drh:       case 't':  zType = "ticket";      break;
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:     @ <table border="0" cellpadding="0" cellspacing="0">
dbda8d6ce9 2007-07-21       drh:     @ <tr><td align="right">%s(zType)&nbsp;UUID:</td><td width="10"></td>
dbda8d6ce9 2007-07-21       drh:     @ <td>%s(db_column_text(&q,0))</td></tr>
dbda8d6ce9 2007-07-21       drh:     z = db_column_text(&q, 7);
dbda8d6ce9 2007-07-21       drh:     if( z ){
dbda8d6ce9 2007-07-21       drh:       @ <tr><td align="right" valign="top">comment:</td><td></td>
dbda8d6ce9 2007-07-21       drh:       @ <td valign="top">%h(z)</td></tr>
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:     @ <tr><td align="right">created:</td><td></td>
dbda8d6ce9 2007-07-21       drh:     @ <td>%s(db_column_text(&q,2))</td></tr>
dbda8d6ce9 2007-07-21       drh:     @ <tr><td align="right">received:</td><td></td>
dbda8d6ce9 2007-07-21       drh:     @ <td>%s(db_column_text(&q,1))</td></tr>
dbda8d6ce9 2007-07-21       drh:     @ <tr><td align="right">signed&nbsp;by:</td><td></td>
dbda8d6ce9 2007-07-21       drh:     @ <td>%h(zSignedBy)</td></tr>
dbda8d6ce9 2007-07-21       drh:     z = db_column_text(&q, 4);
dbda8d6ce9 2007-07-21       drh:     if( z && z[0] && (z[0]!='0' || z[1]!=0) ){
dbda8d6ce9 2007-07-21       drh:       @ <tr><td align="right">size:</td><td></td>
dbda8d6ce9 2007-07-21       drh:       @ <td>%s(z)</td></tr>
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:     z = db_column_text(&q, 5);
dbda8d6ce9 2007-07-21       drh:     if( z ){
dbda8d6ce9 2007-07-21       drh:       @ <tr><td align="right">MD5&nbsp;checksum:</td><td></td>
dbda8d6ce9 2007-07-21       drh:       @ <td>%s(z)</td></tr>
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:     z = db_column_text(&q, 6);
dbda8d6ce9 2007-07-21       drh:     if( z ){
dbda8d6ce9 2007-07-21       drh:       @ <tr><td align="right">branch:</td><td></td>
dbda8d6ce9 2007-07-21       drh:       @ <td>%h(z)</td></tr>
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh:   db_prepare(&q, "SELECT uuid, typecode FROM link JOIN record ON a=rid "
dbda8d6ce9 2007-07-21       drh:                  " WHERE b=%d", rid);
dbda8d6ce9 2007-07-21       drh:   while( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     const char *zType = db_column_text(&q, 1);
dbda8d6ce9 2007-07-21       drh:     const char *zUuid = db_column_text(&q, 0);
dbda8d6ce9 2007-07-21       drh:     if( zType[0]=='P' ){
dbda8d6ce9 2007-07-21       drh:       @ <tr><td align="right">parent:</td><td></td><td>
dbda8d6ce9 2007-07-21       drh:       hyperlink_to_uuid(zUuid);
dbda8d6ce9 2007-07-21       drh:       if( cType=='f' || cType=='w' ){
dbda8d6ce9 2007-07-21       drh:         hyperlink_to_diff(zUuid, g.zExtra);
dbda8d6ce9 2007-07-21       drh:       }
dbda8d6ce9 2007-07-21       drh:       @ </td></tr>
dbda8d6ce9 2007-07-21       drh:     }else if( zType[0]=='M' ){
dbda8d6ce9 2007-07-21       drh:       @ <tr><td align="right">merge&nbsp;parent:</td><td></td><td>
dbda8d6ce9 2007-07-21       drh:       hyperlink_to_uuid(zUuid);
dbda8d6ce9 2007-07-21       drh:       if( cType=='f' || cType=='w' ){
dbda8d6ce9 2007-07-21       drh:         hyperlink_to_diff(zUuid, g.zExtra);
dbda8d6ce9 2007-07-21       drh:       }
dbda8d6ce9 2007-07-21       drh:       @ </td></tr>
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh:   db_prepare(&q, "SELECT uuid, typecode FROM link JOIN record ON b=rid "
dbda8d6ce9 2007-07-21       drh:                  " WHERE a=%d ORDER BY typecode DESC", rid);
dbda8d6ce9 2007-07-21       drh:   while( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     const char *zType = db_column_text(&q, 1);
dbda8d6ce9 2007-07-21       drh:     const char *zUuid = db_column_text(&q, 0);
dbda8d6ce9 2007-07-21       drh:     if( zType[0]=='P' ){
dbda8d6ce9 2007-07-21       drh:       @ <tr><td align="right">child:</td><td></td><td>
dbda8d6ce9 2007-07-21       drh:       hyperlink_to_uuid(zUuid);
dbda8d6ce9 2007-07-21       drh:       if( cType=='f' || cType=='w' ){
dbda8d6ce9 2007-07-21       drh:         hyperlink_to_diff(g.zExtra, zUuid);
dbda8d6ce9 2007-07-21       drh:       }
dbda8d6ce9 2007-07-21       drh:       @ </td></tr>
dbda8d6ce9 2007-07-21       drh:     }else if( zType[0]=='M' ){
dbda8d6ce9 2007-07-21       drh:       @ <tr><td align="right">merge&nbsp;child:</td><td></td><td>
dbda8d6ce9 2007-07-21       drh:       hyperlink_to_uuid(zUuid);
dbda8d6ce9 2007-07-21       drh:       if( cType=='f' || cType=='w' ){
dbda8d6ce9 2007-07-21       drh:         hyperlink_to_diff(g.zExtra, zUuid);
dbda8d6ce9 2007-07-21       drh:       }
dbda8d6ce9 2007-07-21       drh:       @ </td></tr>
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh:   if( cType=='v' ){
dbda8d6ce9 2007-07-21       drh:     db_prepare(&q, "SELECT uuid, typecode, name "
dbda8d6ce9 2007-07-21       drh:                    " FROM link, record, fname"
dbda8d6ce9 2007-07-21       drh:                    " WHERE a=%d AND typecode IN ('D','E','I')"
dbda8d6ce9 2007-07-21       drh:                    "   AND b=record.rid AND fname.fnid=record.fnid"
dbda8d6ce9 2007-07-21       drh:                    " ORDER BY name", rid);
dbda8d6ce9 2007-07-21       drh:     while( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:       const char *zUuid = db_column_text(&q, 0);
dbda8d6ce9 2007-07-21       drh:       const char *zType = db_column_text(&q, 1);
dbda8d6ce9 2007-07-21       drh:       const char *zName = db_column_text(&q, 2);
dbda8d6ce9 2007-07-21       drh:       if( zType[0]=='D' ){
dbda8d6ce9 2007-07-21       drh:         @ <tr><td align="right">deleted&nbsp;file:</td><td></td><td>
dbda8d6ce9 2007-07-21       drh:         hyperlink_to_uuid(zUuid);
dbda8d6ce9 2007-07-21       drh:       }else if( zType[0]=='E' ){
dbda8d6ce9 2007-07-21       drh:         @ <tr><td align="right">changed&nbsp;file:</td><td></td><td>
dbda8d6ce9 2007-07-21       drh:         hyperlink_to_uuid(zUuid);
dbda8d6ce9 2007-07-21       drh:         hyperlink_to_diff(zUuid, 0);
dbda8d6ce9 2007-07-21       drh:       }else if( zType[0]=='I' ){
dbda8d6ce9 2007-07-21       drh:         @ <tr><td align="right">added&nbsp;file:</td><td></td><td>
dbda8d6ce9 2007-07-21       drh:         hyperlink_to_uuid(zUuid);
dbda8d6ce9 2007-07-21       drh:       }
dbda8d6ce9 2007-07-21       drh:       @ &nbsp;&nbsp;%h(zName)</td></tr>
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:     db_finalize(&q);
dbda8d6ce9 2007-07-21       drh:   }else if( cType=='f' ){
dbda8d6ce9 2007-07-21       drh:     db_prepare(&q, "SELECT uuid"
dbda8d6ce9 2007-07-21       drh:                    " FROM link, record"
dbda8d6ce9 2007-07-21       drh:                    " WHERE b=%d AND typecode IN ('E','I')"
dbda8d6ce9 2007-07-21       drh:                    "   AND a=record.rid", rid);
dbda8d6ce9 2007-07-21       drh:     while( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:       const char *zUuid = db_column_text(&q, 0);
dbda8d6ce9 2007-07-21       drh:       @ <tr><td align="right">associated&nbsp;version:</td><td></td><td>
dbda8d6ce9 2007-07-21       drh:       hyperlink_to_uuid(zUuid);
dbda8d6ce9 2007-07-21       drh:       @ </td></tr>
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:     db_finalize(&q);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   style_footer();
dbda8d6ce9 2007-07-21       drh: }
3dcaed8d86 2007-07-28       dan: #endif
dbda8d6ce9 2007-07-21       drh: 
3dcaed8d86 2007-07-28       dan: #if 0
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** WEB PAGE: diff
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** Display the difference between two files determined by the v1 and v2
dbda8d6ce9 2007-07-21       drh: ** query parameters.  If only v2 is given compute v1 as the parent of v2.
dbda8d6ce9 2007-07-21       drh: ** If v2 has no parent, then show the complete text of v2.
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: void diff_page(void){
dbda8d6ce9 2007-07-21       drh:   const char *zV1 = P("v1");
dbda8d6ce9 2007-07-21       drh:   const char *zV2 = P("v2");
dbda8d6ce9 2007-07-21       drh:   int vid1, vid2;
dbda8d6ce9 2007-07-21       drh:   Blob out;
dbda8d6ce9 2007-07-21       drh:   Record *p1, *p2;
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh:   if( zV2==0 ){
dbda8d6ce9 2007-07-21       drh:     cgi_redirect("index");
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   vid2 = uuid_to_rid(zV2, 0);
dbda8d6ce9 2007-07-21       drh:   p2 = record_from_rid(vid2);
66f4caa379 2007-07-23       drh:   style_header("File Diff");
dbda8d6ce9 2007-07-21       drh:   if( zV1==0 ){
dbda8d6ce9 2007-07-21       drh:     zV1 = db_text(0,
dbda8d6ce9 2007-07-21       drh:        "SELECT uuid FROM record WHERE rid="
dbda8d6ce9 2007-07-21       drh:        "  (SELECT a FROM link WHERE typecode='P' AND b=%d)", vid2);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   if( zV1==0 ){
dbda8d6ce9 2007-07-21       drh:     @ <p>Content of
dbda8d6ce9 2007-07-21       drh:     hyperlink_to_uuid(zV2);
dbda8d6ce9 2007-07-21       drh:     @ </p>
dbda8d6ce9 2007-07-21       drh:     @ <pre>
dbda8d6ce9 2007-07-21       drh:     @ %h(blob_str(record_get_content(p2)))
dbda8d6ce9 2007-07-21       drh:     @ </pre>
dbda8d6ce9 2007-07-21       drh:   }else{
dbda8d6ce9 2007-07-21       drh:     vid1 = uuid_to_rid(zV1, 0);
dbda8d6ce9 2007-07-21       drh:     p1 = record_from_rid(vid1);
dbda8d6ce9 2007-07-21       drh:     blob_zero(&out);
dbda8d6ce9 2007-07-21       drh:     unified_diff(record_get_content(p1), record_get_content(p2), 4, &out);
dbda8d6ce9 2007-07-21       drh:     @ <p>Differences between
dbda8d6ce9 2007-07-21       drh:     hyperlink_to_uuid(zV1);
dbda8d6ce9 2007-07-21       drh:     @ and
dbda8d6ce9 2007-07-21       drh:     hyperlink_to_uuid(zV2);
dbda8d6ce9 2007-07-21       drh:     @ </p>
dbda8d6ce9 2007-07-21       drh:     @ <pre>
dbda8d6ce9 2007-07-21       drh:     @ %h(blob_str(&out))
dbda8d6ce9 2007-07-21       drh:     @ </pre>
dbda8d6ce9 2007-07-21       drh:     record_destroy(p1);
dbda8d6ce9 2007-07-21       drh:     blob_reset(&out);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   record_destroy(p2);
dbda8d6ce9 2007-07-21       drh:   style_footer();
dbda8d6ce9 2007-07-21       drh: }
dbda8d6ce9 2007-07-21       drh: #endif