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: 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: 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: } dbda8d6ce9 2007-07-21 drh: db_prepare(&q, dbda8d6ce9 2007-07-21 drh: "SELECT uuid, datetime(mtime,'unixepoch'), datetime(ctime,'unixepoch')," dbda8d6ce9 2007-07-21 drh: " uid, size, cksum, branch, comment, type" dbda8d6ce9 2007-07-21 drh: " 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) 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 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 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 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 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 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 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 file:</td><td></td><td> dbda8d6ce9 2007-07-21 drh: hyperlink_to_uuid(zUuid); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: @ %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 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: } dbda8d6ce9 2007-07-21 drh: 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