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: **
6607844a01 2007-08-18       drh: ** Usage: %fossil info ?UUID?
1a9c6dbfb7 2007-08-01       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,
86c8768475 2007-08-01       drh:     "SELECT plink.cid, blob.uuid, datetime(plink.mtime, 'localtime'),"
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,
86c8768475 2007-08-01       drh:     "SELECT plink.pid, blob.uuid, datetime(event.mtime, 'localtime'),"
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 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: 
dbda8d6ce9 2007-07-21       drh: /*
3dcaed8d86 2007-07-28       dan: ** WEBPAGE: 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;
30d7afe328 2007-08-01       drh:   int isLeaf;
86c8768475 2007-08-01       drh:   int n;
fd36718ad9 2007-07-31       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:   }
30d7afe328 2007-08-01       drh:   isLeaf = !db_exists("SELECT 1 FROM plink WHERE pid=%d", rid);
dbda8d6ce9 2007-07-21       drh:   db_prepare(&q,
86c8768475 2007-08-01       drh:      "SELECT uuid, datetime(mtime, 'localtime'), 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
dbda8d6ce9 2007-07-21       drh:   );
dbda8d6ce9 2007-07-21       drh:   if( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     const char *zUuid = db_column_text(&q, 0);
6dab6149b1 2007-08-01       drh:     @ <h2>Version %s(zUuid)</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>
9df32e2808 2007-08-01       drh:     @ <li><a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a></li>
6dab6149b1 2007-08-01       drh:     @ <li><a href="%s(g.zBaseURL)/zip/%s(zUuid).zip">ZIP archive</a></li>
30d7afe328 2007-08-01       drh:     @ </ul>
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       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>
dbda8d6ce9 2007-07-21       drh:     }
86c8768475 2007-08-01       drh:     @ <a href="%s(g.zBaseURL)/finfo/%T(zName)">%h(zName)</a></li>
fd36718ad9 2007-07-31       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: /*
86c8768475 2007-08-01       drh: ** WEBPAGE: finfo
30d7afe328 2007-08-01       drh: **
86c8768475 2007-08-01       drh: ** Show the complete change history for a single file.  The name
86c8768475 2007-08-01       drh: ** of the file is in g.zExtra
30d7afe328 2007-08-01       drh: */
86c8768475 2007-08-01       drh: void finfo_page(void){
30d7afe328 2007-08-01       drh:   Stmt q;
86c8768475 2007-08-01       drh:   char zPrevDate[20];
30d7afe328 2007-08-01       drh:   login_check_credentials();
30d7afe328 2007-08-01       drh:   if( !g.okHistory ){ login_needed(); return; }
86c8768475 2007-08-01       drh:   style_header("File History");
86c8768475 2007-08-01       drh: 
86c8768475 2007-08-01       drh:   zPrevDate[0] = 0;
86c8768475 2007-08-01       drh:   db_prepare(&q,
1a9c6dbfb7 2007-08-01       drh:     "SELECT a.uuid, substr(b.uuid,1,10), datetime(event.mtime,'localtime'),"
1a9c6dbfb7 2007-08-01       drh:     "       event.comment, event.user, mlink.pid, mlink.fid"
1a9c6dbfb7 2007-08-01       drh:     "  FROM mlink, blob a, blob b, event"
86c8768475 2007-08-01       drh:     " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
1a9c6dbfb7 2007-08-01       drh:     "   AND a.rid=mlink.mid"
1a9c6dbfb7 2007-08-01       drh:     "   AND b.rid=mlink.fid"
86c8768475 2007-08-01       drh:     "   AND event.objid=mlink.mid"
86c8768475 2007-08-01       drh:     " ORDER BY event.mtime DESC",
86c8768475 2007-08-01       drh:     g.zExtra
30d7afe328 2007-08-01       drh:   );
86c8768475 2007-08-01       drh:   @ <h2>History of %h(g.zExtra)</h2>
86c8768475 2007-08-01       drh:   @ <table cellspacing=0 border=0 cellpadding=0>
fd36718ad9 2007-07-31       drh:   while( db_step(&q)==SQLITE_ROW ){
1a9c6dbfb7 2007-08-01       drh:     const char *zVers = db_column_text(&q, 0);
1a9c6dbfb7 2007-08-01       drh:     const char *zUuid = db_column_text(&q, 1);
1a9c6dbfb7 2007-08-01       drh:     const char *zDate = db_column_text(&q, 2);
1a9c6dbfb7 2007-08-01       drh:     const char *zCom = db_column_text(&q, 3);
1a9c6dbfb7 2007-08-01       drh:     const char *zUser = db_column_text(&q, 4);
1a9c6dbfb7 2007-08-01       drh:     int fpid = db_column_int(&q, 5);
1a9c6dbfb7 2007-08-01       drh:     int frid = db_column_int(&q, 6);
86c8768475 2007-08-01       drh:     if( memcmp(zDate, zPrevDate, 10) ){
86c8768475 2007-08-01       drh:       sprintf(zPrevDate, "%.10s", zDate);
86c8768475 2007-08-01       drh:       @ <tr><td colspan=3>
86c8768475 2007-08-01       drh:       @ <table cellpadding=2 border=0>
86c8768475 2007-08-01       drh:       @ <tr><td bgcolor="#a0b5f4" class="border1">
86c8768475 2007-08-01       drh:       @ <table cellpadding=2 cellspacing=0 border=0><tr>
86c8768475 2007-08-01       drh:       @ <td bgcolor="#d0d9f4" class="bkgnd1">%s(zPrevDate)</td>
86c8768475 2007-08-01       drh:       @ </tr></table>
86c8768475 2007-08-01       drh:       @ </td></tr></table>
dbda8d6ce9 2007-07-21       drh:       @ </td></tr>
dbda8d6ce9 2007-07-21       drh:     }
86c8768475 2007-08-01       drh:     @ <tr><td valign="top">%s(&zDate[11])</td>
86c8768475 2007-08-01       drh:     @ <td width="20"></td>
86c8768475 2007-08-01       drh:     @ <td valign="top" align="left">
1a9c6dbfb7 2007-08-01       drh:     hyperlink_to_uuid(zVers);
1a9c6dbfb7 2007-08-01       drh:     @ %h(zCom) (By: %h(zUser))
1a9c6dbfb7 2007-08-01       drh:     @ Id: %s(zUuid)/%d(frid)
1a9c6dbfb7 2007-08-01       drh:     @ <a href="%s(g.zBaseURL)/fview/%d(frid)">[view]</a>
1a9c6dbfb7 2007-08-01       drh:     @ <a href="%s(g.zBaseURL)/fdiff?v1=%d(fpid)&amp;v2=%d(frid)">[diff]</a>
1a9c6dbfb7 2007-08-01       drh:     @ </td>
dbda8d6ce9 2007-07-21       drh:   }
fd36718ad9 2007-07-31       drh:   db_finalize(&q);
86c8768475 2007-08-01       drh:   @ </table>
dbda8d6ce9 2007-07-21       drh:   style_footer();
dbda8d6ce9 2007-07-21       drh: }
dbda8d6ce9 2007-07-21       drh: 
3dcaed8d86 2007-07-28       dan: 
9df32e2808 2007-08-01       drh: /*
9df32e2808 2007-08-01       drh: ** Append the difference between two RIDs to the output
9df32e2808 2007-08-01       drh: */
9df32e2808 2007-08-01       drh: static void append_diff(int fromid, int toid){
9df32e2808 2007-08-01       drh:   Blob from, to, out;
9df32e2808 2007-08-01       drh:   content_get(fromid, &from);
9df32e2808 2007-08-01       drh:   content_get(toid, &to);
9df32e2808 2007-08-01       drh:   blob_zero(&out);
9df32e2808 2007-08-01       drh:   unified_diff(&from, &to, 5, &out);
9df32e2808 2007-08-01       drh:   @ %h(blob_str(&out))
9df32e2808 2007-08-01       drh:   blob_reset(&from);
9df32e2808 2007-08-01       drh:   blob_reset(&to);
9df32e2808 2007-08-01       drh:   blob_reset(&out);
9df32e2808 2007-08-01       drh: }
9df32e2808 2007-08-01       drh: 
dbda8d6ce9 2007-07-21       drh: /*
9df32e2808 2007-08-01       drh: ** WEBPAGE: vdiff
dbda8d6ce9 2007-07-21       drh: **
9df32e2808 2007-08-01       drh: ** Show all differences for a particular check-in specified by g.zExtra
dbda8d6ce9 2007-07-21       drh: */
9df32e2808 2007-08-01       drh: void vdiff_page(void){
1a9c6dbfb7 2007-08-01       drh:   int rid;
1a9c6dbfb7 2007-08-01       drh:   Stmt q;
9df32e2808 2007-08-01       drh:   char *zUuid;
9df32e2808 2007-08-01       drh: 
9df32e2808 2007-08-01       drh:   login_check_credentials();
9df32e2808 2007-08-01       drh:   if( !g.okHistory ){ login_needed(); return; }
9df32e2808 2007-08-01       drh:   style_header("Version Diff");
dbda8d6ce9 2007-07-21       drh: 
9df32e2808 2007-08-01       drh:   rid = name_to_rid(g.zExtra);
9df32e2808 2007-08-01       drh:   if( rid==0 ){
dbda8d6ce9 2007-07-21       drh:     cgi_redirect("index");
dbda8d6ce9 2007-07-21       drh:   }
9df32e2808 2007-08-01       drh:   db_prepare(&q,
9df32e2808 2007-08-01       drh:      "SELECT pid, fid, name"
9df32e2808 2007-08-01       drh:      "  FROM mlink, filename"
9df32e2808 2007-08-01       drh:      " WHERE mlink.mid=%d"
9df32e2808 2007-08-01       drh:      "   AND filename.fnid=mlink.fnid"
9df32e2808 2007-08-01       drh:      " ORDER BY name",
9df32e2808 2007-08-01       drh:      rid
9df32e2808 2007-08-01       drh:   );
9df32e2808 2007-08-01       drh:   zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
9df32e2808 2007-08-01       drh:   @ <h2>All Changes In Version
9df32e2808 2007-08-01       drh:   hyperlink_to_uuid(zUuid);
9df32e2808 2007-08-01       drh:   @ </h2>
9df32e2808 2007-08-01       drh:   while( db_step(&q)==SQLITE_ROW ){
9df32e2808 2007-08-01       drh:     int pid = db_column_int(&q,0);
9df32e2808 2007-08-01       drh:     int fid = db_column_int(&q,1);
9df32e2808 2007-08-01       drh:     const char *zName = db_column_text(&q,2);
9df32e2808 2007-08-01       drh:     @ <p><a href="%s(g.zBaseURL)/finfo/%T(zName)">%h(zName)</a></p>
9df32e2808 2007-08-01       drh:     @ <blockquote><pre>
9df32e2808 2007-08-01       drh:     append_diff(pid, fid);
9df32e2808 2007-08-01       drh:     @ </pre></blockquote>
9df32e2808 2007-08-01       drh:   }
9df32e2808 2007-08-01       drh:   db_finalize(&q);
9df32e2808 2007-08-01       drh:   style_footer();
9df32e2808 2007-08-01       drh: }
9df32e2808 2007-08-01       drh: 
9df32e2808 2007-08-01       drh: 
9df32e2808 2007-08-01       drh: /*
1a9c6dbfb7 2007-08-01       drh: ** Write a description of an object to the www reply.
1a9c6dbfb7 2007-08-01       drh: **
1a9c6dbfb7 2007-08-01       drh: ** If the object is a file then mention:
1a9c6dbfb7 2007-08-01       drh: **
1a9c6dbfb7 2007-08-01       drh: **     * It's uuid
1a9c6dbfb7 2007-08-01       drh: **     * All its filenames
1a9c6dbfb7 2007-08-01       drh: **     * The versions it was checked-in on, with times and users
1a9c6dbfb7 2007-08-01       drh: **
1a9c6dbfb7 2007-08-01       drh: ** If the object is a manifest, then mention:
9df32e2808 2007-08-01       drh: **
1a9c6dbfb7 2007-08-01       drh: **     * It's uuid
1a9c6dbfb7 2007-08-01       drh: **     * date of check-in
1a9c6dbfb7 2007-08-01       drh: **     * Comment & user
9df32e2808 2007-08-01       drh: */
1a9c6dbfb7 2007-08-01       drh: static void object_description(int rid, int linkToView){
1a9c6dbfb7 2007-08-01       drh:   Stmt q;
1a9c6dbfb7 2007-08-01       drh:   int cnt = 0;
1a9c6dbfb7 2007-08-01       drh:   db_prepare(&q,
1a9c6dbfb7 2007-08-01       drh:     "SELECT filename.name, datetime(event.mtime), substr(a.uuid,1,10),"
1a9c6dbfb7 2007-08-01       drh:     "       event.comment, event.user, b.uuid"
1a9c6dbfb7 2007-08-01       drh:     "  FROM mlink, filename, event, blob a, blob b"
1a9c6dbfb7 2007-08-01       drh:     " WHERE filename.fnid=mlink.fnid"
1a9c6dbfb7 2007-08-01       drh:     "   AND event.objid=mlink.mid"
1a9c6dbfb7 2007-08-01       drh:     "   AND a.rid=mlink.fid"
1a9c6dbfb7 2007-08-01       drh:     "   AND b.rid=mlink.mid"
1a9c6dbfb7 2007-08-01       drh:     "   AND mlink.fid=%d",
1a9c6dbfb7 2007-08-01       drh:     rid
1a9c6dbfb7 2007-08-01       drh:   );
1a9c6dbfb7 2007-08-01       drh:   while( db_step(&q)==SQLITE_ROW ){
1a9c6dbfb7 2007-08-01       drh:     const char *zName = db_column_text(&q, 0);
1a9c6dbfb7 2007-08-01       drh:     const char *zDate = db_column_text(&q, 1);
1a9c6dbfb7 2007-08-01       drh:     const char *zFuuid = db_column_text(&q, 2);
1a9c6dbfb7 2007-08-01       drh:     const char *zCom = db_column_text(&q, 3);
1a9c6dbfb7 2007-08-01       drh:     const char *zUser = db_column_text(&q, 4);
1a9c6dbfb7 2007-08-01       drh:     const char *zVers = db_column_text(&q, 5);
1a9c6dbfb7 2007-08-01       drh:     @ File <a href="%s(g.zBaseURL)/finfo/%T(zName)">%h(zName)</a>
1a9c6dbfb7 2007-08-01       drh:     @ uuid %s(zFuuid) part of check-in
1a9c6dbfb7 2007-08-01       drh:     hyperlink_to_uuid(zVers);
1a9c6dbfb7 2007-08-01       drh:     @ %s(zCom) by %s(zUser) on %s(zDate).
1a9c6dbfb7 2007-08-01       drh:     cnt++;
9df32e2808 2007-08-01       drh:   }
1a9c6dbfb7 2007-08-01       drh:   db_finalize(&q);
1a9c6dbfb7 2007-08-01       drh:   db_prepare(&q,
1a9c6dbfb7 2007-08-01       drh:     "SELECT datetime(mtime), user, comment, uuid"
1a9c6dbfb7 2007-08-01       drh:     "  FROM event, blob"
1a9c6dbfb7 2007-08-01       drh:     " WHERE event.objid=%d"
1a9c6dbfb7 2007-08-01       drh:     "   AND blob.rid=%d",
1a9c6dbfb7 2007-08-01       drh:     rid, rid
1a9c6dbfb7 2007-08-01       drh:   );
1a9c6dbfb7 2007-08-01       drh:   while( db_step(&q)==SQLITE_ROW ){
1a9c6dbfb7 2007-08-01       drh:     const char *zDate = db_column_text(&q, 0);
1a9c6dbfb7 2007-08-01       drh:     const char *zUuid = db_column_text(&q, 3);
1a9c6dbfb7 2007-08-01       drh:     const char *zCom = db_column_text(&q, 2);
1a9c6dbfb7 2007-08-01       drh:     const char *zUser = db_column_text(&q, 1);
1a9c6dbfb7 2007-08-01       drh:     @ Version
1a9c6dbfb7 2007-08-01       drh:     hyperlink_to_uuid(zUuid);
1a9c6dbfb7 2007-08-01       drh:     @ %s(zCom) by %s(zUser) on %s(zDate).
1a9c6dbfb7 2007-08-01       drh:     cnt++;
dbda8d6ce9 2007-07-21       drh:   }
1a9c6dbfb7 2007-08-01       drh:   db_finalize(&q);
1a9c6dbfb7 2007-08-01       drh:   if( cnt==0 ){
1a9c6dbfb7 2007-08-01       drh:     @ Empty file
1a9c6dbfb7 2007-08-01       drh:   }else if( linkToView ){
1a9c6dbfb7 2007-08-01       drh:     @ <a href="%s(g.zBaseURL)/fview/%d(rid)">[view]</a>
dbda8d6ce9 2007-07-21       drh:   }
1a9c6dbfb7 2007-08-01       drh: }
1a9c6dbfb7 2007-08-01       drh: 
1a9c6dbfb7 2007-08-01       drh: /*
1a9c6dbfb7 2007-08-01       drh: ** WEBPAGE: fdiff
1a9c6dbfb7 2007-08-01       drh: **
1a9c6dbfb7 2007-08-01       drh: ** Two arguments, v1 and v2, are integers.  Show the difference between
1a9c6dbfb7 2007-08-01       drh: ** the two records.
1a9c6dbfb7 2007-08-01       drh: */
1a9c6dbfb7 2007-08-01       drh: void diff_page(void){
1a9c6dbfb7 2007-08-01       drh:   int v1 = atoi(PD("v1","0"));
1a9c6dbfb7 2007-08-01       drh:   int v2 = atoi(PD("v2","0"));
1a9c6dbfb7 2007-08-01       drh:   Blob c1, c2, diff;
1a9c6dbfb7 2007-08-01       drh: 
1a9c6dbfb7 2007-08-01       drh:   login_check_credentials();
1a9c6dbfb7 2007-08-01       drh:   if( !g.okHistory ){ login_needed(); return; }
1a9c6dbfb7 2007-08-01       drh:   style_header("Diff");
1a9c6dbfb7 2007-08-01       drh:   @ <h2>Differences From:</h2>
1a9c6dbfb7 2007-08-01       drh:   @ <blockquote>
1a9c6dbfb7 2007-08-01       drh:   object_description(v1, 1);
1a9c6dbfb7 2007-08-01       drh:   @ </blockquote>
1a9c6dbfb7 2007-08-01       drh:   @ <h2>To:</h2>
1a9c6dbfb7 2007-08-01       drh:   @ <blockquote>
1a9c6dbfb7 2007-08-01       drh:   object_description(v2, 1);
1a9c6dbfb7 2007-08-01       drh:   @ </blockquote>
1a9c6dbfb7 2007-08-01       drh:   @ <hr>
1a9c6dbfb7 2007-08-01       drh:   @ <blockquote><pre>
1a9c6dbfb7 2007-08-01       drh:   content_get(v1, &c1);
1a9c6dbfb7 2007-08-01       drh:   content_get(v2, &c2);
1a9c6dbfb7 2007-08-01       drh:   blob_zero(&diff);
1a9c6dbfb7 2007-08-01       drh:   unified_diff(&c1, &c2, 4, &diff);
1a9c6dbfb7 2007-08-01       drh:   blob_reset(&c1);
1a9c6dbfb7 2007-08-01       drh:   blob_reset(&c2);
1a9c6dbfb7 2007-08-01       drh:   @ %h(blob_str(&diff))
1a9c6dbfb7 2007-08-01       drh:   @ </pre></blockquote>
1a9c6dbfb7 2007-08-01       drh:   blob_reset(&diff);
dbda8d6ce9 2007-07-21       drh:   style_footer();
dbda8d6ce9 2007-07-21       drh: }
1a9c6dbfb7 2007-08-01       drh: 
1a9c6dbfb7 2007-08-01       drh: /*
1a9c6dbfb7 2007-08-01       drh: ** WEBPAGE: fview
1a9c6dbfb7 2007-08-01       drh: **
1a9c6dbfb7 2007-08-01       drh: ** Show the complete content of a file identified by g.zExtra
1a9c6dbfb7 2007-08-01       drh: */
1a9c6dbfb7 2007-08-01       drh: void fview_page(void){
1a9c6dbfb7 2007-08-01       drh:   int rid;
1a9c6dbfb7 2007-08-01       drh:   Blob content;
1a9c6dbfb7 2007-08-01       drh: 
1a9c6dbfb7 2007-08-01       drh:   rid = name_to_rid(g.zExtra);
1a9c6dbfb7 2007-08-01       drh:   login_check_credentials();
1a9c6dbfb7 2007-08-01       drh:   if( !g.okHistory ){ login_needed(); return; }
1a9c6dbfb7 2007-08-01       drh:   style_header("File Content");
1a9c6dbfb7 2007-08-01       drh:   @ <h2>Content Of:</h2>
1a9c6dbfb7 2007-08-01       drh:   @ <blockquote>
1a9c6dbfb7 2007-08-01       drh:   object_description(rid, 0);
1a9c6dbfb7 2007-08-01       drh:   @ </blockquote>
1a9c6dbfb7 2007-08-01       drh:   @ <hr>
1a9c6dbfb7 2007-08-01       drh:   @ <blockquote><pre>
1a9c6dbfb7 2007-08-01       drh:   content_get(rid, &content);
1a9c6dbfb7 2007-08-01       drh:   @ %h(blob_str(&content))
1a9c6dbfb7 2007-08-01       drh:   @ </pre></blockquote>
1a9c6dbfb7 2007-08-01       drh:   blob_reset(&content);
1a9c6dbfb7 2007-08-01       drh:   style_footer();
1a9c6dbfb7 2007-08-01       drh: }