File Annotation
Not logged in
8c8f8616a6 2009-10-31       drh: /*
8c8f8616a6 2009-10-31       drh: ** Copyright (c) 2009 D. Richard Hipp
8c8f8616a6 2009-10-31       drh: **
8c8f8616a6 2009-10-31       drh: ** This program is free software; you can redistribute it and/or
8c8f8616a6 2009-10-31       drh: ** modify it under the terms of the GNU General Public
8c8f8616a6 2009-10-31       drh: ** License version 2 as published by the Free Software Foundation.
8c8f8616a6 2009-10-31       drh: **
8c8f8616a6 2009-10-31       drh: ** This program is distributed in the hope that it will be useful,
8c8f8616a6 2009-10-31       drh: ** but WITHOUT ANY WARRANTY; without even the implied warranty of
8c8f8616a6 2009-10-31       drh: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8c8f8616a6 2009-10-31       drh: ** General Public License for more details.
8c8f8616a6 2009-10-31       drh: **
8c8f8616a6 2009-10-31       drh: ** You should have received a copy of the GNU General Public
8c8f8616a6 2009-10-31       drh: ** License along with this library; if not, write to the
8c8f8616a6 2009-10-31       drh: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
8c8f8616a6 2009-10-31       drh: ** Boston, MA  02111-1307, USA.
8c8f8616a6 2009-10-31       drh: **
8c8f8616a6 2009-10-31       drh: ** Author contact information:
8c8f8616a6 2009-10-31       drh: **   drh@hwaci.com
8c8f8616a6 2009-10-31       drh: **   http://www.hwaci.com/drh/
8c8f8616a6 2009-10-31       drh: **
8c8f8616a6 2009-10-31       drh: *******************************************************************************
8c8f8616a6 2009-10-31       drh: **
8c8f8616a6 2009-10-31       drh: ** This file contains code to implement the "finfo" command.
8c8f8616a6 2009-10-31       drh: */
8c8f8616a6 2009-10-31       drh: #include "config.h"
8c8f8616a6 2009-10-31       drh: #include "finfo.h"
8c8f8616a6 2009-10-31       drh: 
8c8f8616a6 2009-10-31       drh: /*
8c8f8616a6 2009-10-31       drh: ** COMMAND: finfo
8c8f8616a6 2009-10-31       drh: **
8c8f8616a6 2009-10-31       drh: ** Usage: %fossil finfo FILENAME
8c8f8616a6 2009-10-31       drh: **
8c8f8616a6 2009-10-31       drh: ** Print the change history for a single file.
8c8f8616a6 2009-10-31       drh: **
8c8f8616a6 2009-10-31       drh: ** The "--limit N" and "--offset P" options limits the output to the first
8c8f8616a6 2009-10-31       drh: ** N changes after skipping P changes.
8c8f8616a6 2009-10-31       drh: */
8c8f8616a6 2009-10-31       drh: void finfo_cmd(void){
8c8f8616a6 2009-10-31       drh:   Stmt q;
8c8f8616a6 2009-10-31       drh:   int vid;
8c8f8616a6 2009-10-31       drh:   Blob dest;
8c8f8616a6 2009-10-31       drh:   const char *zFilename;
8c8f8616a6 2009-10-31       drh:   const char *zLimit;
8c8f8616a6 2009-10-31       drh:   const char *zOffset;
8c8f8616a6 2009-10-31       drh:   int iLimit, iOffset;
8c8f8616a6 2009-10-31       drh: 
8c8f8616a6 2009-10-31       drh:   db_must_be_within_tree();
8c8f8616a6 2009-10-31       drh:   vid = db_lget_int("checkout", 0);
8c8f8616a6 2009-10-31       drh:   if( vid==0 ){
8c8f8616a6 2009-10-31       drh:     fossil_panic("no checkout to finfo files in");
8c8f8616a6 2009-10-31       drh:   }
8c8f8616a6 2009-10-31       drh:   zLimit = find_option("limit",0,1);
8c8f8616a6 2009-10-31       drh:   iLimit = zLimit ? atoi(zLimit) : -1;
8c8f8616a6 2009-10-31       drh:   zOffset = find_option("offset",0,1);
8c8f8616a6 2009-10-31       drh:   iOffset = zOffset ? atoi(zOffset) : 0;
8c8f8616a6 2009-10-31       drh:   if (g.argc<3) {
8c8f8616a6 2009-10-31       drh:     usage("FILENAME");
8c8f8616a6 2009-10-31       drh:   }
8c8f8616a6 2009-10-31       drh:   file_tree_name(g.argv[2], &dest, 1);
8c8f8616a6 2009-10-31       drh:   zFilename = blob_str(&dest);
8c8f8616a6 2009-10-31       drh:   db_prepare(&q,
8c8f8616a6 2009-10-31       drh:     "SELECT b.uuid, ci.uuid, date(event.mtime,'localtime'),"
8c8f8616a6 2009-10-31       drh:     "       coalesce(event.ecomment, event.comment),"
8c8f8616a6 2009-10-31       drh:     "       coalesce(event.euser, event.user)"
8c8f8616a6 2009-10-31       drh:     "  FROM mlink, blob b, event, blob ci"
8c8f8616a6 2009-10-31       drh:     " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
8c8f8616a6 2009-10-31       drh:     "   AND b.rid=mlink.fid"
8c8f8616a6 2009-10-31       drh:     "   AND event.objid=mlink.mid"
8c8f8616a6 2009-10-31       drh:     "   AND event.objid=ci.rid"
8c8f8616a6 2009-10-31       drh:     " ORDER BY event.mtime DESC LIMIT %d OFFSET %d",
8c8f8616a6 2009-10-31       drh:     zFilename, iLimit, iOffset
8c8f8616a6 2009-10-31       drh:   );
8c8f8616a6 2009-10-31       drh: 
8c8f8616a6 2009-10-31       drh:   printf("History of %s\n", zFilename);
8c8f8616a6 2009-10-31       drh:   while( db_step(&q)==SQLITE_ROW ){
8c8f8616a6 2009-10-31       drh:     const char *zFileUuid = db_column_text(&q, 0);
8c8f8616a6 2009-10-31       drh:     const char *zCiUuid = db_column_text(&q, 1);
8c8f8616a6 2009-10-31       drh:     const char *zDate = db_column_text(&q, 2);
8c8f8616a6 2009-10-31       drh:     const char *zCom = db_column_text(&q, 3);
8c8f8616a6 2009-10-31       drh:     const char *zUser = db_column_text(&q, 4);
8c8f8616a6 2009-10-31       drh:     char *zOut;
8c8f8616a6 2009-10-31       drh:     printf("%s ", zDate);
8c8f8616a6 2009-10-31       drh:     zOut = sqlite3_mprintf("[%.10s] %s (user: %s, artifact: [%.10s])",
8c8f8616a6 2009-10-31       drh:                             zCiUuid, zCom, zUser, zFileUuid);
8c8f8616a6 2009-10-31       drh:     comment_print(zOut, 11, 79);
8c8f8616a6 2009-10-31       drh:     sqlite3_free(zOut);
8c8f8616a6 2009-10-31       drh:   }
8c8f8616a6 2009-10-31       drh:   db_finalize(&q);
8c8f8616a6 2009-10-31       drh:   blob_reset(&dest);
8c8f8616a6 2009-10-31       drh: }
8c8f8616a6 2009-10-31       drh: 
8c8f8616a6 2009-10-31       drh: 
8c8f8616a6 2009-10-31       drh: /*
8c8f8616a6 2009-10-31       drh: ** WEBPAGE: finfo
8c8f8616a6 2009-10-31       drh: ** URL: /finfo?name=FILENAME
8c8f8616a6 2009-10-31       drh: **
8c8f8616a6 2009-10-31       drh: ** Show the complete change history for a single file.
8c8f8616a6 2009-10-31       drh: */
8c8f8616a6 2009-10-31       drh: void finfo_page(void){
8c8f8616a6 2009-10-31       drh:   Stmt q;
8c8f8616a6 2009-10-31       drh:   const char *zFilename;
8c8f8616a6 2009-10-31       drh:   char zPrevDate[20];
8c8f8616a6 2009-10-31       drh:   Blob title;
8c8f8616a6 2009-10-31       drh: 
8c8f8616a6 2009-10-31       drh:   login_check_credentials();
8c8f8616a6 2009-10-31       drh:   if( !g.okRead ){ login_needed(); return; }
8c8f8616a6 2009-10-31       drh:   style_header("File History");
8c8f8616a6 2009-10-31       drh:   login_anonymous_available();
8c8f8616a6 2009-10-31       drh: 
8c8f8616a6 2009-10-31       drh:   zPrevDate[0] = 0;
8c8f8616a6 2009-10-31       drh:   zFilename = PD("name","");
8c8f8616a6 2009-10-31       drh:   db_prepare(&q,
8c8f8616a6 2009-10-31       drh:     "SELECT substr(b.uuid,1,10), datetime(event.mtime,'localtime'),"
8c8f8616a6 2009-10-31       drh:     "       coalesce(event.ecomment, event.comment),"
8c8f8616a6 2009-10-31       drh:     "       coalesce(event.euser, event.user),"
8c8f8616a6 2009-10-31       drh:     "       mlink.pid, mlink.fid, mlink.mid, mlink.fnid, ci.uuid"
8c8f8616a6 2009-10-31       drh:     "  FROM mlink, blob b, event, blob ci"
8c8f8616a6 2009-10-31       drh:     " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
8c8f8616a6 2009-10-31       drh:     "   AND b.rid=mlink.fid"
8c8f8616a6 2009-10-31       drh:     "   AND event.objid=mlink.mid"
8c8f8616a6 2009-10-31       drh:     "   AND event.objid=ci.rid"
8c8f8616a6 2009-10-31       drh:     " ORDER BY event.mtime DESC",
8c8f8616a6 2009-10-31       drh:     zFilename
8c8f8616a6 2009-10-31       drh:   );
8c8f8616a6 2009-10-31       drh:   blob_zero(&title);
8c8f8616a6 2009-10-31       drh:   blob_appendf(&title, "History of ");
8c8f8616a6 2009-10-31       drh:   hyperlinked_path(zFilename, &title);
8c8f8616a6 2009-10-31       drh:   @ <h2>%b(&title)</h2>
8c8f8616a6 2009-10-31       drh:   blob_reset(&title);
8c8f8616a6 2009-10-31       drh:   @ <table cellspacing=0 border=0 cellpadding=0>
8c8f8616a6 2009-10-31       drh:   while( db_step(&q)==SQLITE_ROW ){
8c8f8616a6 2009-10-31       drh:     const char *zUuid = db_column_text(&q, 0);
8c8f8616a6 2009-10-31       drh:     const char *zDate = db_column_text(&q, 1);
8c8f8616a6 2009-10-31       drh:     const char *zCom = db_column_text(&q, 2);
8c8f8616a6 2009-10-31       drh:     const char *zUser = db_column_text(&q, 3);
8c8f8616a6 2009-10-31       drh:     int fpid = db_column_int(&q, 4);
8c8f8616a6 2009-10-31       drh:     int frid = db_column_int(&q, 5);
8c8f8616a6 2009-10-31       drh:     int mid = db_column_int(&q, 6);
8c8f8616a6 2009-10-31       drh:     int fnid = db_column_int(&q, 7);
8c8f8616a6 2009-10-31       drh:     const char *zCkin = db_column_text(&q,8);
8c8f8616a6 2009-10-31       drh:     char zShort[20];
8c8f8616a6 2009-10-31       drh:     char zShortCkin[20];
8c8f8616a6 2009-10-31       drh:     if( memcmp(zDate, zPrevDate, 10) ){
8c8f8616a6 2009-10-31       drh:       sprintf(zPrevDate, "%.10s", zDate);
8c8f8616a6 2009-10-31       drh:       @ <tr><td colspan=3>
8c8f8616a6 2009-10-31       drh:       @   <div class="divider">%s(zPrevDate)</div>
8c8f8616a6 2009-10-31       drh:       @ </td></tr>
8c8f8616a6 2009-10-31       drh:     }
8c8f8616a6 2009-10-31       drh:     @ <tr><td valign="top">%s(&zDate[11])</td>
8c8f8616a6 2009-10-31       drh:     @ <td width="20"></td>
8c8f8616a6 2009-10-31       drh:     @ <td valign="top" align="left">
8c8f8616a6 2009-10-31       drh:     sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid);
8c8f8616a6 2009-10-31       drh:     sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin);
8c8f8616a6 2009-10-31       drh:     if( g.okHistory ){
8c8f8616a6 2009-10-31       drh:       @ <a href="%s(g.zTop)/artifact/%s(zUuid)">[%s(zShort)]</a>
8c8f8616a6 2009-10-31       drh:     }else{
8c8f8616a6 2009-10-31       drh:       @ [%s(zShort)]
8c8f8616a6 2009-10-31       drh:     }
8c8f8616a6 2009-10-31       drh:     @ part of check-in
8c8f8616a6 2009-10-31       drh:     hyperlink_to_uuid(zShortCkin);
8c8f8616a6 2009-10-31       drh:     @ %h(zCom) (By:
8c8f8616a6 2009-10-31       drh:     hyperlink_to_user(zUser, zDate, " on");
8c8f8616a6 2009-10-31       drh:     hyperlink_to_date(zDate, ")");
8c8f8616a6 2009-10-31       drh:     if( g.okHistory ){
8c8f8616a6 2009-10-31       drh:       if( fpid ){
8c8f8616a6 2009-10-31       drh:         @ <a href="%s(g.zBaseURL)/fdiff?v1=%d(fpid)&amp;v2=%d(frid)">[diff]</a>
8c8f8616a6 2009-10-31       drh:       }
8c8f8616a6 2009-10-31       drh:       @ <a href="%s(g.zBaseURL)/annotate?mid=%d(mid)&amp;fnid=%d(fnid)">
8c8f8616a6 2009-10-31       drh:       @ [annotate]</a>
8c8f8616a6 2009-10-31       drh:       @ </td>
8c8f8616a6 2009-10-31       drh:     }
8c8f8616a6 2009-10-31       drh:   }
8c8f8616a6 2009-10-31       drh:   db_finalize(&q);
8c8f8616a6 2009-10-31       drh:   @ </table>
8c8f8616a6 2009-10-31       drh:   style_footer();
8c8f8616a6 2009-10-31       drh: }