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? 6607844a01 2007-08-18 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: */ 4ac16995e8 2007-08-19 drh: static int showDescendents(int pid, int depth, const char *zTitle){ dbda8d6ce9 2007-07-21 drh: Stmt q; 30d7afe328 2007-08-01 drh: int cnt = 0; dbda8d6ce9 2007-07-21 drh: db_prepare(&q, 86c8768475 2007-08-01 drh: "SELECT plink.cid, blob.uuid, datetime(plink.mtime, 'localtime')," 3b5514ed82 2007-09-22 drh: " coalesce(event.euser,event.user)," 3b5514ed82 2007-09-22 drh: " coalesce(event.comment,event.ecomment)" 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 dbda8d6ce9 2007-07-21 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 ){ 4ac16995e8 2007-08-19 drh: if( zTitle ){ 34af72801d 2007-11-23 drh: @ <div class="section">%s(zTitle)</div> 4ac16995e8 2007-08-19 drh: } 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); 2859293737 2007-11-22 drh: @ %w(zCom) (by %s(zUser) on %s(zDate)) 30d7afe328 2007-08-01 drh: if( depth ){ 4ac16995e8 2007-08-19 drh: n = showDescendents(cid, depth-1, 0); 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 ){ 4ac16995e8 2007-08-19 drh: db_multi_exec("DELETE FROM leaves WHERE rid=%d", cid); 30d7afe328 2007-08-01 drh: @ <b>leaf</b> dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: db_finalize(&q); 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: */ 4ac16995e8 2007-08-19 drh: static void showAncestors(int pid, int depth, const char *zTitle){ 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')," 3b5514ed82 2007-09-22 drh: " coalesce(event.euser,event.user)," 3b5514ed82 2007-09-22 drh: " coalesce(event.comment,event.ecomment)" 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: ); dbda8d6ce9 2007-07-21 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++; 4ac16995e8 2007-08-19 drh: if( cnt==1 ){ 4ac16995e8 2007-08-19 drh: if( zTitle ){ 34af72801d 2007-11-23 drh: @ <div class="section">%s(zTitle)</div> dbda8d6ce9 2007-07-21 drh: } 4ac16995e8 2007-08-19 drh: @ <ul> 4ac16995e8 2007-08-19 drh: } 30d7afe328 2007-08-01 drh: @ <li> 30d7afe328 2007-08-01 drh: hyperlink_to_uuid(zUuid); 2859293737 2007-11-22 drh: @ %w(zCom) (by %s(zUser) on %s(zDate)) 30d7afe328 2007-08-01 drh: if( depth ){ 4ac16995e8 2007-08-19 drh: showAncestors(cid, depth-1, 0); 4ac16995e8 2007-08-19 drh: } 4ac16995e8 2007-08-19 drh: } 3b5514ed82 2007-09-22 drh: db_finalize(&q); 4ac16995e8 2007-08-19 drh: if( cnt ){ 4ac16995e8 2007-08-19 drh: @ </ul> 4ac16995e8 2007-08-19 drh: } 4ac16995e8 2007-08-19 drh: } 4ac16995e8 2007-08-19 drh: 4ac16995e8 2007-08-19 drh: 4ac16995e8 2007-08-19 drh: /* 4ac16995e8 2007-08-19 drh: ** Show information about versions mentioned in the "leaves" table. 4ac16995e8 2007-08-19 drh: */ 4ac16995e8 2007-08-19 drh: static void showLeaves(void){ 4ac16995e8 2007-08-19 drh: Stmt q; 4ac16995e8 2007-08-19 drh: int cnt = 0; 4ac16995e8 2007-08-19 drh: db_prepare(&q, 4ac16995e8 2007-08-19 drh: "SELECT blob.uuid, datetime(event.mtime, 'localtime')," 3b5514ed82 2007-09-22 drh: " coalesce(event.euser, event.user)," 3b5514ed82 2007-09-22 drh: " coalesce(event.ecomment,event.comment)" 72b3b1ad47 2007-09-22 drh: " FROM leaves, blob, event" 72b3b1ad47 2007-09-22 drh: " WHERE blob.rid=leaves.rid" abce5105e2 2007-09-01 drh: " AND event.objid=leaves.rid" 4ac16995e8 2007-08-19 drh: " ORDER BY event.mtime DESC" 4ac16995e8 2007-08-19 drh: ); 4ac16995e8 2007-08-19 drh: while( db_step(&q)==SQLITE_ROW ){ 4ac16995e8 2007-08-19 drh: const char *zUuid = db_column_text(&q, 0); 4ac16995e8 2007-08-19 drh: const char *zDate = db_column_text(&q, 1); 4ac16995e8 2007-08-19 drh: const char *zUser = db_column_text(&q, 2); 4ac16995e8 2007-08-19 drh: const char *zCom = db_column_text(&q, 3); 4ac16995e8 2007-08-19 drh: cnt++; 4ac16995e8 2007-08-19 drh: if( cnt==1 ){ 34af72801d 2007-11-23 drh: @ <div class="section">Leaves</div> 4ac16995e8 2007-08-19 drh: @ <ul> 4ac16995e8 2007-08-19 drh: } 4ac16995e8 2007-08-19 drh: @ <li> 4ac16995e8 2007-08-19 drh: hyperlink_to_uuid(zUuid); 2859293737 2007-11-22 drh: @ %w(zCom) (by %s(zUser) on %s(zDate)) dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: db_finalize(&q); 3b5514ed82 2007-09-22 drh: if( cnt ){ 3b5514ed82 2007-09-22 drh: @ </ul> 3b5514ed82 2007-09-22 drh: } 3b5514ed82 2007-09-22 drh: } 3b5514ed82 2007-09-22 drh: 3b5514ed82 2007-09-22 drh: /* 3b5514ed82 2007-09-22 drh: ** Show information about all tags on a given node. 3b5514ed82 2007-09-22 drh: */ 3b5514ed82 2007-09-22 drh: static void showTags(int rid){ 3b5514ed82 2007-09-22 drh: Stmt q; 3b5514ed82 2007-09-22 drh: int cnt = 0; 3b5514ed82 2007-09-22 drh: db_prepare(&q, 3b5514ed82 2007-09-22 drh: "SELECT tag.tagid, tagname, srcid, blob.uuid, value," 09c4adeb6f 2007-09-22 drh: " datetime(tagxref.mtime,'localtime'), tagtype" 3b5514ed82 2007-09-22 drh: " FROM tagxref JOIN tag ON tagxref.tagid=tag.tagid" 3b5514ed82 2007-09-22 drh: " LEFT JOIN blob ON blob.rid=tagxref.srcid" 3b5514ed82 2007-09-22 drh: " WHERE tagxref.rid=%d" 3b5514ed82 2007-09-22 drh: " ORDER BY tagname", rid 3b5514ed82 2007-09-22 drh: ); dbda8d6ce9 2007-07-21 drh: while( db_step(&q)==SQLITE_ROW ){ 3b5514ed82 2007-09-22 drh: const char *zTagname = db_column_text(&q, 1); 3b5514ed82 2007-09-22 drh: int srcid = db_column_int(&q, 2); 3b5514ed82 2007-09-22 drh: const char *zUuid = db_column_text(&q, 3); 3b5514ed82 2007-09-22 drh: const char *zValue = db_column_text(&q, 4); 3b5514ed82 2007-09-22 drh: const char *zDate = db_column_text(&q, 5); 09c4adeb6f 2007-09-22 drh: int tagtype = db_column_int(&q, 6); 3b5514ed82 2007-09-22 drh: cnt++; 3b5514ed82 2007-09-22 drh: if( cnt==1 ){ 34af72801d 2007-11-23 drh: @ <div class="section">Tags And Properties</div> 3b5514ed82 2007-09-22 drh: @ <ul> 3b5514ed82 2007-09-22 drh: } 3b5514ed82 2007-09-22 drh: @ <li> 3b5514ed82 2007-09-22 drh: @ <b>%h(zTagname)</b> 3b5514ed82 2007-09-22 drh: if( zValue ){ 3b5514ed82 2007-09-22 drh: @ = %h(zValue)<i> 09c4adeb6f 2007-09-22 drh: }else if( tagtype==0 ){ 3b5514ed82 2007-09-22 drh: @ <i>Cancelled 3b5514ed82 2007-09-22 drh: }else{ 3b5514ed82 2007-09-22 drh: @ <i> 3b5514ed82 2007-09-22 drh: } 3b5514ed82 2007-09-22 drh: if( srcid==0 ){ 3b5514ed82 2007-09-22 drh: @ Inherited 3b5514ed82 2007-09-22 drh: }else if( zUuid ){ 3b5514ed82 2007-09-22 drh: @ From 3b5514ed82 2007-09-22 drh: hyperlink_to_uuid(zUuid); 30d7afe328 2007-08-01 drh: } 3b5514ed82 2007-09-22 drh: @ on %s(zDate)</i> 3b5514ed82 2007-09-22 drh: } 3b5514ed82 2007-09-22 drh: db_finalize(&q); 4ac16995e8 2007-08-19 drh: if( cnt ){ 4ac16995e8 2007-08-19 drh: @ </ul> 4ac16995e8 2007-08-19 drh: } 30d7afe328 2007-08-01 drh: } 4ac16995e8 2007-08-19 drh: 30d7afe328 2007-08-01 drh: 30d7afe328 2007-08-01 drh: /* 30d7afe328 2007-08-01 drh: ** WEBPAGE: vinfo 677aa71bca 2007-10-12 drh: ** URL: /vinfo?name=RID|UUID 30d7afe328 2007-08-01 drh: ** 677aa71bca 2007-10-12 drh: ** Return information about a version. 30d7afe328 2007-08-01 drh: */ 30d7afe328 2007-08-01 drh: void vinfo_page(void){ 30d7afe328 2007-08-01 drh: Stmt q; 30d7afe328 2007-08-01 drh: int rid; 30d7afe328 2007-08-01 drh: int isLeaf; 30d7afe328 2007-08-01 drh: 30d7afe328 2007-08-01 drh: login_check_credentials(); 30d7afe328 2007-08-01 drh: if( !g.okHistory ){ login_needed(); return; } 677aa71bca 2007-10-12 drh: rid = name_to_rid(PD("name","0")); 30d7afe328 2007-08-01 drh: if( rid==0 ){ cfc7984ede 2007-09-25 jnc: style_header("Version Information Error"); 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, 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 30d7afe328 2007-08-01 drh: ); 30d7afe328 2007-08-01 drh: if( db_step(&q)==SQLITE_ROW ){ dbda8d6ce9 2007-07-21 drh: const char *zUuid = db_column_text(&q, 0); cfc7984ede 2007-09-25 jnc: char *zTitle = mprintf("Version: [%.10s]", zUuid); cfc7984ede 2007-09-25 jnc: style_header(zTitle); cfc7984ede 2007-09-25 jnc: free(zTitle); cfc7984ede 2007-09-25 jnc: /*@ <h2>Version %s(zUuid)</h2>*/ 34af72801d 2007-11-23 drh: @ <div class="section">Overview</div> cfc7984ede 2007-09-25 jnc: @ <p><table class="label-value"> cfc7984ede 2007-09-25 jnc: @ <tr><th>Version:</th><td>%s(zUuid)</td></tr> cfc7984ede 2007-09-25 jnc: @ <tr><th>Date:</th><td>%s(db_column_text(&q, 1))</td></tr> 4ac16995e8 2007-08-19 drh: if( g.okSetup ){ cfc7984ede 2007-09-25 jnc: @ <tr><th>Record ID:</th><td>%d(rid)</td></tr> dbda8d6ce9 2007-07-21 drh: } 2859293737 2007-11-22 drh: @ <tr><th>Original User:</th><td>%h(db_column_text(&q, 2))</td></tr> 2859293737 2007-11-22 drh: @ <tr><th>Original Comment:</th><td>%w(db_column_text(&q,3))</td></tr> 3afcc4388c 2007-11-22 drh: @ </td></tr> cfc7984ede 2007-09-25 jnc: @ <tr><th>Commands:</th> cfc7984ede 2007-09-25 jnc: @ <td> cfc7984ede 2007-09-25 jnc: @ <a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a> cfc7984ede 2007-09-25 jnc: @ | <a href="%s(g.zBaseURL)/zip/%s(zUuid).zip">ZIP archive</a> cfc7984ede 2007-09-25 jnc: @ | <a href="%s(g.zBaseURL)/fview/%d(rid)">manifest</a> cfc7984ede 2007-09-25 jnc: @ </td> cfc7984ede 2007-09-25 jnc: @ </tr> cfc7984ede 2007-09-25 jnc: @ </table></p> cfc7984ede 2007-09-25 jnc: }else{ cfc7984ede 2007-09-25 jnc: style_header("Version Information"); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: db_finalize(&q); 3b5514ed82 2007-09-22 drh: showTags(rid); 34af72801d 2007-11-23 drh: @ <div class="section">Changes</div> 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: } 677aa71bca 2007-10-12 drh: @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a></li> 30d7afe328 2007-08-01 drh: } 30d7afe328 2007-08-01 drh: @ </ul> 4ac16995e8 2007-08-19 drh: compute_leaves(rid); 4ac16995e8 2007-08-19 drh: showDescendents(rid, 2, "Descendents"); 4ac16995e8 2007-08-19 drh: showLeaves(); 4ac16995e8 2007-08-19 drh: showAncestors(rid, 2, "Ancestors"); dbda8d6ce9 2007-07-21 drh: style_footer(); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dfea940da8 2007-10-09 drh: ** WEBPAGE: winfo 677aa71bca 2007-10-12 drh: ** URL: /winfo?name=RID dbda8d6ce9 2007-07-21 drh: ** 677aa71bca 2007-10-12 drh: ** Return information about a wiki page. dbda8d6ce9 2007-07-21 drh: */ dfea940da8 2007-10-09 drh: void winfo_page(void){ 30d7afe328 2007-08-01 drh: Stmt q; 30d7afe328 2007-08-01 drh: int rid; 30d7afe328 2007-08-01 drh: 30d7afe328 2007-08-01 drh: login_check_credentials(); 30d7afe328 2007-08-01 drh: if( !g.okHistory ){ login_needed(); return; } 677aa71bca 2007-10-12 drh: rid = name_to_rid(PD("name","0")); 30d7afe328 2007-08-01 drh: if( rid==0 ){ dfea940da8 2007-10-09 drh: style_header("Wiki Page Information Error"); 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: db_prepare(&q, dfea940da8 2007-10-09 drh: "SELECT substr(tagname, 6, 1000), uuid," dfea940da8 2007-10-09 drh: " datetime(event.mtime, 'localtime'), user" dfea940da8 2007-10-09 drh: " FROM tagxref, tag, blob, event" dfea940da8 2007-10-09 drh: " WHERE tagxref.rid=%d" dfea940da8 2007-10-09 drh: " AND tag.tagid=tagxref.tagid" dfea940da8 2007-10-09 drh: " AND tag.tagname LIKE 'wiki-%%'" dfea940da8 2007-10-09 drh: " AND blob.rid=%d" dfea940da8 2007-10-09 drh: " AND event.objid=%d", dfea940da8 2007-10-09 drh: rid, rid, rid 30d7afe328 2007-08-01 drh: ); 30d7afe328 2007-08-01 drh: if( db_step(&q)==SQLITE_ROW ){ dfea940da8 2007-10-09 drh: const char *zName = db_column_text(&q, 0); dfea940da8 2007-10-09 drh: const char *zUuid = db_column_text(&q, 1); dfea940da8 2007-10-09 drh: char *zTitle = mprintf("Wiki Page %s", zName); dfea940da8 2007-10-09 drh: style_header(zTitle); dfea940da8 2007-10-09 drh: free(zTitle); 34af72801d 2007-11-23 drh: @ <div class="section">Overview</div> dfea940da8 2007-10-09 drh: @ <p><table class="label-value"> dfea940da8 2007-10-09 drh: @ <tr><th>Version:</th><td>%s(zUuid)</td></tr> dfea940da8 2007-10-09 drh: @ <tr><th>Date:</th><td>%s(db_column_text(&q, 2))</td></tr> dfea940da8 2007-10-09 drh: if( g.okSetup ){ dfea940da8 2007-10-09 drh: @ <tr><th>Record ID:</th><td>%d(rid)</td></tr> 30d7afe328 2007-08-01 drh: } dfea940da8 2007-10-09 drh: @ <tr><th>Original User:</th><td>%s(db_column_text(&q, 3))</td></tr> dfea940da8 2007-10-09 drh: @ <tr><th>Commands:</th> dfea940da8 2007-10-09 drh: @ <td> dfea940da8 2007-10-09 drh: /* @ <a href="%s(g.zBaseURL)/wdiff/%d(rid)">diff</a> | */ 677aa71bca 2007-10-12 drh: @ <a href="%s(g.zBaseURL)/whistory?page=%t(zName)">history</a> dfea940da8 2007-10-09 drh: @ | <a href="%s(g.zBaseURL)/fview/%d(rid)">raw-text</a> dfea940da8 2007-10-09 drh: @ </td> dfea940da8 2007-10-09 drh: @ </tr> dfea940da8 2007-10-09 drh: @ </table></p> dbda8d6ce9 2007-07-21 drh: }else{ dfea940da8 2007-10-09 drh: style_header("Wiki Information"); 30d7afe328 2007-08-01 drh: } 30d7afe328 2007-08-01 drh: db_finalize(&q); dfea940da8 2007-10-09 drh: showTags(rid); 86c8768475 2007-08-01 drh: style_footer(); 86c8768475 2007-08-01 drh: } 86c8768475 2007-08-01 drh: 86c8768475 2007-08-01 drh: /* 86c8768475 2007-08-01 drh: ** WEBPAGE: finfo 677aa71bca 2007-10-12 drh: ** URL: /finfo?name=FILENAME 86c8768475 2007-08-01 drh: ** 677aa71bca 2007-10-12 drh: ** Show the complete change history for a single file. 86c8768475 2007-08-01 drh: */ 86c8768475 2007-08-01 drh: void finfo_page(void){ 86c8768475 2007-08-01 drh: Stmt q; 677aa71bca 2007-10-12 drh: const char *zFilename; 86c8768475 2007-08-01 drh: char zPrevDate[20]; 86c8768475 2007-08-01 drh: login_check_credentials(); 86c8768475 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; 677aa71bca 2007-10-12 drh: zFilename = PD("name",""); 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')," 3b5514ed82 2007-09-22 drh: " coalesce(event.ecomment, event.comment)," 3b5514ed82 2007-09-22 drh: " coalesce(event.euser, event.user)," 3b5514ed82 2007-09-22 drh: " 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", 677aa71bca 2007-10-12 drh: zFilename 86c8768475 2007-08-01 drh: ); 677aa71bca 2007-10-12 drh: @ <h2>History of %h(zFilename)</h2> 86c8768475 2007-08-01 drh: @ <table cellspacing=0 border=0 cellpadding=0> 30d7afe328 2007-08-01 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> 30d7afe328 2007-08-01 drh: @ </td></tr> 30d7afe328 2007-08-01 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> 677aa71bca 2007-10-12 drh: if( fpid ){ 677aa71bca 2007-10-12 drh: @ <a href="%s(g.zBaseURL)/fdiff?v1=%d(fpid)&v2=%d(frid)">[diff]</a> 30d7afe328 2007-08-01 drh: } 1a9c6dbfb7 2007-08-01 drh: @ </td> 30d7afe328 2007-08-01 drh: } 30d7afe328 2007-08-01 drh: db_finalize(&q); 86c8768475 2007-08-01 drh: @ </table> 86c8768475 2007-08-01 drh: style_footer(); 86c8768475 2007-08-01 drh: } 86c8768475 2007-08-01 drh: 86c8768475 2007-08-01 drh: 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); 57b2735ebd 2007-11-15 drh: text_diff(&from, &to, &out, 5); 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: 9df32e2808 2007-08-01 drh: /* 9df32e2808 2007-08-01 drh: ** WEBPAGE: vdiff 677aa71bca 2007-10-12 drh: ** URL: /vdiff?name=RID 9df32e2808 2007-08-01 drh: ** 677aa71bca 2007-10-12 drh: ** Show all differences for a particular check-in. 9df32e2808 2007-08-01 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"); 9df32e2808 2007-08-01 drh: 677aa71bca 2007-10-12 drh: rid = name_to_rid(PD("name","")); 9df32e2808 2007-08-01 drh: if( rid==0 ){ 9df32e2808 2007-08-01 drh: cgi_redirect("index"); 9df32e2808 2007-08-01 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); 677aa71bca 2007-10-12 drh: @ <p><a href="%s(g.zBaseURL)/finfo?name=%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> 30d7afe328 2007-08-01 drh: } 9df32e2808 2007-08-01 drh: db_finalize(&q); 30d7afe328 2007-08-01 drh: style_footer(); 30d7afe328 2007-08-01 drh: } 9df32e2808 2007-08-01 drh: 30d7afe328 2007-08-01 drh: 1a9c6dbfb7 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: 1a9c6dbfb7 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 1a9c6dbfb7 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; dfea940da8 2007-10-09 drh: int nWiki = 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)," 3b5514ed82 2007-09-22 drh: " coalesce(event.comment,event.ecomment)," 3b5514ed82 2007-09-22 drh: " coalesce(event.euser,event.user)," 3b5514ed82 2007-09-22 drh: " 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); 677aa71bca 2007-10-12 drh: @ File <a href="%s(g.zBaseURL)/finfo?name=%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); 2859293737 2007-11-22 drh: @ %w(zCom) by %h(zUser) on %s(zDate) 1a9c6dbfb7 2007-08-01 drh: cnt++; 1a9c6dbfb7 2007-08-01 drh: } 1a9c6dbfb7 2007-08-01 drh: db_finalize(&q); 1a9c6dbfb7 2007-08-01 drh: db_prepare(&q, dfea940da8 2007-10-09 drh: "SELECT substr(tagname, 6, 10000), datetime(event.mtime)," dfea940da8 2007-10-09 drh: " coalesce(event.euser, event.user), uuid" dfea940da8 2007-10-09 drh: " FROM tagxref, tag, event, blob" dfea940da8 2007-10-09 drh: " WHERE tagxref.rid=%d" dfea940da8 2007-10-09 drh: " AND tag.tagid=tagxref.tagid" dfea940da8 2007-10-09 drh: " AND tag.tagname LIKE 'wiki-%%'" dfea940da8 2007-10-09 drh: " AND event.objid=tagxref.rid" dfea940da8 2007-10-09 drh: " AND blob.rid=tagxref.rid", dfea940da8 2007-10-09 drh: rid 1a9c6dbfb7 2007-08-01 drh: ); 1a9c6dbfb7 2007-08-01 drh: while( db_step(&q)==SQLITE_ROW ){ dfea940da8 2007-10-09 drh: const char *zPagename = db_column_text(&q, 0); dfea940da8 2007-10-09 drh: const char *zDate = db_column_text(&q, 1); dfea940da8 2007-10-09 drh: const char *zUser = db_column_text(&q, 2); 1a9c6dbfb7 2007-08-01 drh: const char *zUuid = db_column_text(&q, 3); 677aa71bca 2007-10-12 drh: @ Wiki page 677aa71bca 2007-10-12 drh: @ [<a href="%s(g.zBaseURL)/wiki?page=%t(zPagename)">%h(zPagename)</a>] dfea940da8 2007-10-09 drh: @ uuid %s(zUuid) by %h(zUser) on %s(zDate) dfea940da8 2007-10-09 drh: nWiki++; 1a9c6dbfb7 2007-08-01 drh: cnt++; 1a9c6dbfb7 2007-08-01 drh: } 1a9c6dbfb7 2007-08-01 drh: db_finalize(&q); dfea940da8 2007-10-09 drh: if( nWiki==0 ){ dfea940da8 2007-10-09 drh: db_prepare(&q, dfea940da8 2007-10-09 drh: "SELECT datetime(mtime), user, comment, uuid" dfea940da8 2007-10-09 drh: " FROM event, blob" dfea940da8 2007-10-09 drh: " WHERE event.objid=%d" dfea940da8 2007-10-09 drh: " AND blob.rid=%d", dfea940da8 2007-10-09 drh: rid, rid dfea940da8 2007-10-09 drh: ); dfea940da8 2007-10-09 drh: while( db_step(&q)==SQLITE_ROW ){ dfea940da8 2007-10-09 drh: const char *zDate = db_column_text(&q, 0); dfea940da8 2007-10-09 drh: const char *zUuid = db_column_text(&q, 3); dfea940da8 2007-10-09 drh: const char *zUser = db_column_text(&q, 1); 2859293737 2007-11-22 drh: const char *zCom = db_column_text(&q, 2); dfea940da8 2007-10-09 drh: @ Manifest of version dfea940da8 2007-10-09 drh: hyperlink_to_uuid(zUuid); 2859293737 2007-11-22 drh: @ %w(zCom) by %h(zUser) on %s(zDate) dfea940da8 2007-10-09 drh: cnt++; dfea940da8 2007-10-09 drh: } dfea940da8 2007-10-09 drh: db_finalize(&q); dfea940da8 2007-10-09 drh: } 1a9c6dbfb7 2007-08-01 drh: if( cnt==0 ){ 72b3b1ad47 2007-09-22 drh: char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); 72b3b1ad47 2007-09-22 drh: @ Control file %s(zUuid). 1a9c6dbfb7 2007-08-01 drh: }else if( linkToView ){ 1a9c6dbfb7 2007-08-01 drh: @ <a href="%s(g.zBaseURL)/fview/%d(rid)">[view]</a> 1a9c6dbfb7 2007-08-01 drh: } 1a9c6dbfb7 2007-08-01 drh: } 1a9c6dbfb7 2007-08-01 drh: 30d7afe328 2007-08-01 drh: /* 1a9c6dbfb7 2007-08-01 drh: ** WEBPAGE: fdiff 30d7afe328 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. 30d7afe328 2007-08-01 drh: */ 30d7afe328 2007-08-01 drh: void diff_page(void){ 72b3b1ad47 2007-09-22 drh: int v1 = name_to_rid(PD("v1","0")); 72b3b1ad47 2007-09-22 drh: int v2 = name_to_rid(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); 57b2735ebd 2007-11-15 drh: text_diff(&c1, &c2, &diff, 4); 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); 1a9c6dbfb7 2007-08-01 drh: style_footer(); 1a9c6dbfb7 2007-08-01 drh: } 1a9c6dbfb7 2007-08-01 drh: 1a9c6dbfb7 2007-08-01 drh: /* 1a9c6dbfb7 2007-08-01 drh: ** WEBPAGE: fview 677aa71bca 2007-10-12 drh: ** URL: /fview?name=UUID 1a9c6dbfb7 2007-08-01 drh: ** b2e55c0d4d 2007-09-01 drh: ** Show the complete content of a file identified by UUID b2e55c0d4d 2007-09-01 drh: ** as preformatted text. 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; 30d7afe328 2007-08-01 drh: 677aa71bca 2007-10-12 drh: rid = name_to_rid(PD("name","0")); 1a9c6dbfb7 2007-08-01 drh: login_check_credentials(); 1a9c6dbfb7 2007-08-01 drh: if( !g.okHistory ){ login_needed(); return; } dfea940da8 2007-10-09 drh: if( g.zPath[0]=='i' ){ dfea940da8 2007-10-09 drh: if( db_exists("SELECT 1 FROM tagxref JOIN tag USING(tagid)" dfea940da8 2007-10-09 drh: " WHERE rid=%d AND tagname LIKE 'wiki-%%'", rid) ){ dfea940da8 2007-10-09 drh: winfo_page(); dfea940da8 2007-10-09 drh: return; dfea940da8 2007-10-09 drh: } dfea940da8 2007-10-09 drh: if( db_exists("SELECT 1 FROM plink WHERE cid=%d", rid) ){ dfea940da8 2007-10-09 drh: vinfo_page(); dfea940da8 2007-10-09 drh: return; dfea940da8 2007-10-09 drh: } dbda8d6ce9 2007-07-21 drh: } 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); dbda8d6ce9 2007-07-21 drh: style_footer(); dbda8d6ce9 2007-07-21 drh: } f394d84560 2007-11-25 drh: f394d84560 2007-11-25 drh: /* f394d84560 2007-11-25 drh: ** WEBPAGE: info f394d84560 2007-11-25 drh: ** URL: info/UUID f394d84560 2007-11-25 drh: ** f394d84560 2007-11-25 drh: ** The argument is a UUID which might be a baseline or a file or f394d84560 2007-11-25 drh: ** a ticket or something else. It might also be a wiki page name. f394d84560 2007-11-25 drh: ** Figure out what the UUID is an jump to it. If there is ambiguity, f394d84560 2007-11-25 drh: ** draw a page and let the user select the interpretation. f394d84560 2007-11-25 drh: */ f394d84560 2007-11-25 drh: void info_page(void){ f394d84560 2007-11-25 drh: const char *zName; f394d84560 2007-11-25 drh: int rc, nName, cnt; f394d84560 2007-11-25 drh: Stmt q; f394d84560 2007-11-25 drh: f394d84560 2007-11-25 drh: zName = P("name"); f394d84560 2007-11-25 drh: if( zName==0 ) cgi_redirect("index"); f394d84560 2007-11-25 drh: nName = strlen(zName); f394d84560 2007-11-25 drh: if( nName<4 || nName>UUID_SIZE || !validate16(zName, nName) ){ f394d84560 2007-11-25 drh: cgi_redirect("index"); f394d84560 2007-11-25 drh: } f394d84560 2007-11-25 drh: db_multi_exec( f394d84560 2007-11-25 drh: "CREATE TEMP TABLE refs(type,link);" f394d84560 2007-11-25 drh: "INSERT INTO refs " f394d84560 2007-11-25 drh: " SELECT 'f', rid FROM blob WHERE uuid GLOB '%s*'" f394d84560 2007-11-25 drh: " UNION ALL" f394d84560 2007-11-25 drh: " SELECT 'w', substr(tagname,6) FROM tag" f394d84560 2007-11-25 drh: " WHERE tagname='wiki-%q'" f394d84560 2007-11-25 drh: " UNION ALL" f394d84560 2007-11-25 drh: " SELECT 't', tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*';", f394d84560 2007-11-25 drh: zName, zName, zName f394d84560 2007-11-25 drh: ); f394d84560 2007-11-25 drh: cnt = db_int(0, "SELECT count(*) FROM refs"); f394d84560 2007-11-25 drh: if( cnt==0 ){ f394d84560 2007-11-25 drh: style_header("Broken Link"); f394d84560 2007-11-25 drh: @ <p>No such object: %h(zName)</p> f394d84560 2007-11-25 drh: style_footer(); f394d84560 2007-11-25 drh: return; f394d84560 2007-11-25 drh: } f394d84560 2007-11-25 drh: db_prepare(&q, "SELECT type, link FROM refs"); f394d84560 2007-11-25 drh: db_step(&q); f394d84560 2007-11-25 drh: if( cnt==1 ){ f394d84560 2007-11-25 drh: int type = *db_column_text(&q, 0); f394d84560 2007-11-25 drh: int rid = db_column_int(&q, 1); f394d84560 2007-11-25 drh: db_finalize(&q); f394d84560 2007-11-25 drh: if( type=='w' ){ f394d84560 2007-11-25 drh: wiki_page(); f394d84560 2007-11-25 drh: }else if( type=='t' ){ f394d84560 2007-11-25 drh: tktview_page(); f394d84560 2007-11-25 drh: }else{ f394d84560 2007-11-25 drh: cgi_replace_parameter("name", mprintf("%d", rid)); f394d84560 2007-11-25 drh: if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){ f394d84560 2007-11-25 drh: vinfo_page(); f394d84560 2007-11-25 drh: }else{ f394d84560 2007-11-25 drh: finfo_page(); f394d84560 2007-11-25 drh: } f394d84560 2007-11-25 drh: } f394d84560 2007-11-25 drh: return; f394d84560 2007-11-25 drh: } f394d84560 2007-11-25 drh: /* Multiple objects */ f394d84560 2007-11-25 drh: style_header("Ambiguous Link"); f394d84560 2007-11-25 drh: @ <h2>Ambiguous Link: %h(zName)</h2> f394d84560 2007-11-25 drh: @ <ul> f394d84560 2007-11-25 drh: while( rc==SQLITE_ROW ){ f394d84560 2007-11-25 drh: int type = *db_column_text(&q, 0); f394d84560 2007-11-25 drh: if( type=='f' ){ f394d84560 2007-11-25 drh: @ <li><p> f394d84560 2007-11-25 drh: object_description(db_column_int(&q, 1), 1); f394d84560 2007-11-25 drh: @ </p></li> f394d84560 2007-11-25 drh: }else if( type=='w' ){ f394d84560 2007-11-25 drh: @ <li><p> f394d84560 2007-11-25 drh: @ Wiki page <a href="%s(g.zBaseURL)/wiki?name=%s(zName)">%s(zName)</a>. f394d84560 2007-11-25 drh: @ </li><p> f394d84560 2007-11-25 drh: }else if( type=='t' ){ f394d84560 2007-11-25 drh: const char *zUuid = db_column_text(&q, 1); f394d84560 2007-11-25 drh: @ <li><p> f394d84560 2007-11-25 drh: @ Ticket <a href="%s(g.zBaseURL)/tktview?name=%s(zUuid)">%s(zUuid)</a>. f394d84560 2007-11-25 drh: @ </li><p> f394d84560 2007-11-25 drh: } f394d84560 2007-11-25 drh: rc = db_step(&q); f394d84560 2007-11-25 drh: } f394d84560 2007-11-25 drh: @ </ul> f394d84560 2007-11-25 drh: style_footer(); f394d84560 2007-11-25 drh: db_finalize(&q); 1a9c6dbfb7 2007-08-01 drh: }