Fossil SCM

File differences and file viewer added to the www interface.

drh 2007-08-01 16:13 trunk
Commit 1a9c6dbfb7a85fd148c4def82a34c351e5309cfc
1 file changed +141 -57
+141 -57
--- src/info.c
+++ src/info.c
@@ -278,23 +278,30 @@
278278
if( !g.okHistory ){ login_needed(); return; }
279279
style_header("File History");
280280
281281
zPrevDate[0] = 0;
282282
db_prepare(&q,
283
- "SELECT blob.uuid, datetime(event.mtime,'localtime'),"
284
- " event.comment, event.user"
285
- " FROM mlink, blob, event"
283
+ "SELECT a.uuid, substr(b.uuid,1,10), datetime(event.mtime,'localtime'),"
284
+ " event.comment, event.user, mlink.pid, mlink.fid"
285
+ " FROM mlink, blob a, blob b, event"
286286
" WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
287
- " AND blob.rid=mlink.mid"
287
+ " AND a.rid=mlink.mid"
288
+ " AND b.rid=mlink.fid"
288289
" AND event.objid=mlink.mid"
289290
" ORDER BY event.mtime DESC",
290291
g.zExtra
291292
);
292293
@ <h2>History of %h(g.zExtra)</h2>
293294
@ <table cellspacing=0 border=0 cellpadding=0>
294295
while( db_step(&q)==SQLITE_ROW ){
295
- const char *zDate = db_column_text(&q, 1);
296
+ const char *zVers = db_column_text(&q, 0);
297
+ const char *zUuid = db_column_text(&q, 1);
298
+ const char *zDate = db_column_text(&q, 2);
299
+ const char *zCom = db_column_text(&q, 3);
300
+ const char *zUser = db_column_text(&q, 4);
301
+ int fpid = db_column_int(&q, 5);
302
+ int frid = db_column_int(&q, 6);
296303
if( memcmp(zDate, zPrevDate, 10) ){
297304
sprintf(zPrevDate, "%.10s", zDate);
298305
@ <tr><td colspan=3>
299306
@ <table cellpadding=2 border=0>
300307
@ <tr><td bgcolor="#a0b5f4" class="border1">
@@ -305,12 +312,16 @@
305312
@ </td></tr>
306313
}
307314
@ <tr><td valign="top">%s(&zDate[11])</td>
308315
@ <td width="20"></td>
309316
@ <td valign="top" align="left">
310
- hyperlink_to_uuid(db_column_text(&q,0));
311
- @ %h(db_column_text(&q,2)) (by %h(db_column_text(&q,3)))</td>
317
+ hyperlink_to_uuid(zVers);
318
+ @ %h(zCom) (By: %h(zUser))
319
+ @ Id: %s(zUuid)/%d(frid)
320
+ @ <a href="%s(g.zBaseURL)/fview/%d(frid)">[view]</a>
321
+ @ <a href="%s(g.zBaseURL)/fdiff?v1=%d(fpid)&amp;v2=%d(frid)">[diff]</a>
322
+ @ </td>
312323
}
313324
db_finalize(&q);
314325
@ </table>
315326
style_footer();
316327
}
@@ -335,14 +346,12 @@
335346
** WEBPAGE: vdiff
336347
**
337348
** Show all differences for a particular check-in specified by g.zExtra
338349
*/
339350
void vdiff_page(void){
340
- int rid, i;
351
+ int rid;
341352
Stmt q;
342
- Manifest m;
343
- Blob mfile, file;
344353
char *zUuid;
345354
346355
login_check_credentials();
347356
if( !g.okHistory ){ login_needed(); return; }
348357
style_header("Version Diff");
@@ -375,59 +384,134 @@
375384
db_finalize(&q);
376385
style_footer();
377386
}
378387
379388
389
+/*
390
+** Write a description of an object to the www reply.
391
+**
392
+** If the object is a file then mention:
393
+**
394
+** * It's uuid
395
+** * All its filenames
396
+** * The versions it was checked-in on, with times and users
397
+**
398
+** If the object is a manifest, then mention:
399
+**
400
+** * It's uuid
401
+** * date of check-in
402
+** * Comment & user
403
+*/
404
+static void object_description(int rid, int linkToView){
405
+ Stmt q;
406
+ int cnt = 0;
407
+ db_prepare(&q,
408
+ "SELECT filename.name, datetime(event.mtime), substr(a.uuid,1,10),"
409
+ " event.comment, event.user, b.uuid"
410
+ " FROM mlink, filename, event, blob a, blob b"
411
+ " WHERE filename.fnid=mlink.fnid"
412
+ " AND event.objid=mlink.mid"
413
+ " AND a.rid=mlink.fid"
414
+ " AND b.rid=mlink.mid"
415
+ " AND mlink.fid=%d",
416
+ rid
417
+ );
418
+ while( db_step(&q)==SQLITE_ROW ){
419
+ const char *zName = db_column_text(&q, 0);
420
+ const char *zDate = db_column_text(&q, 1);
421
+ const char *zFuuid = db_column_text(&q, 2);
422
+ const char *zCom = db_column_text(&q, 3);
423
+ const char *zUser = db_column_text(&q, 4);
424
+ const char *zVers = db_column_text(&q, 5);
425
+ @ File <a href="%s(g.zBaseURL)/finfo/%T(zName)">%h(zName)</a>
426
+ @ uuid %s(zFuuid) part of check-in
427
+ hyperlink_to_uuid(zVers);
428
+ @ %s(zCom) by %s(zUser) on %s(zDate).
429
+ cnt++;
430
+ }
431
+ db_finalize(&q);
432
+ db_prepare(&q,
433
+ "SELECT datetime(mtime), user, comment, uuid"
434
+ " FROM event, blob"
435
+ " WHERE event.objid=%d"
436
+ " AND blob.rid=%d",
437
+ rid, rid
438
+ );
439
+ while( db_step(&q)==SQLITE_ROW ){
440
+ const char *zDate = db_column_text(&q, 0);
441
+ const char *zUuid = db_column_text(&q, 3);
442
+ const char *zCom = db_column_text(&q, 2);
443
+ const char *zUser = db_column_text(&q, 1);
444
+ @ Version
445
+ hyperlink_to_uuid(zUuid);
446
+ @ %s(zCom) by %s(zUser) on %s(zDate).
447
+ cnt++;
448
+ }
449
+ db_finalize(&q);
450
+ if( cnt==0 ){
451
+ @ Empty file
452
+ }else if( linkToView ){
453
+ @ <a href="%s(g.zBaseURL)/fview/%d(rid)">[view]</a>
454
+ }
455
+}
380456
381
-#if 0
382457
/*
383
-** WEB PAGE: diff
458
+** WEBPAGE: fdiff
384459
**
385
-** Display the difference between two files determined by the v1 and v2
386
-** query parameters. If only v2 is given compute v1 as the parent of v2.
387
-** If v2 has no parent, then show the complete text of v2.
460
+** Two arguments, v1 and v2, are integers. Show the difference between
461
+** the two records.
388462
*/
389463
void diff_page(void){
390
- const char *zV1 = P("v1");
391
- const char *zV2 = P("v2");
392
- int vid1, vid2;
393
- Blob out;
394
- Record *p1, *p2;
395
-
396
- if( zV2==0 ){
397
- cgi_redirect("index");
398
- }
399
- vid2 = uuid_to_rid(zV2, 0);
400
- p2 = record_from_rid(vid2);
401
- style_header("File Diff");
402
- if( zV1==0 ){
403
- zV1 = db_text(0,
404
- "SELECT uuid FROM record WHERE rid="
405
- " (SELECT a FROM link WHERE typecode='P' AND b=%d)", vid2);
406
- }
407
- if( zV1==0 ){
408
- @ <p>Content of
409
- hyperlink_to_uuid(zV2);
410
- @ </p>
411
- @ <pre>
412
- @ %h(blob_str(record_get_content(p2)))
413
- @ </pre>
414
- }else{
415
- vid1 = uuid_to_rid(zV1, 0);
416
- p1 = record_from_rid(vid1);
417
- blob_zero(&out);
418
- unified_diff(record_get_content(p1), record_get_content(p2), 4, &out);
419
- @ <p>Differences between
420
- hyperlink_to_uuid(zV1);
421
- @ and
422
- hyperlink_to_uuid(zV2);
423
- @ </p>
424
- @ <pre>
425
- @ %h(blob_str(&out))
426
- @ </pre>
427
- record_destroy(p1);
428
- blob_reset(&out);
429
- }
430
- record_destroy(p2);
464
+ int v1 = atoi(PD("v1","0"));
465
+ int v2 = atoi(PD("v2","0"));
466
+ Blob c1, c2, diff;
467
+
468
+ login_check_credentials();
469
+ if( !g.okHistory ){ login_needed(); return; }
470
+ style_header("Diff");
471
+ @ <h2>Differences From:</h2>
472
+ @ <blockquote>
473
+ object_description(v1, 1);
474
+ @ </blockquote>
475
+ @ <h2>To:</h2>
476
+ @ <blockquote>
477
+ object_description(v2, 1);
478
+ @ </blockquote>
479
+ @ <hr>
480
+ @ <blockquote><pre>
481
+ content_get(v1, &c1);
482
+ content_get(v2, &c2);
483
+ blob_zero(&diff);
484
+ unified_diff(&c1, &c2, 4, &diff);
485
+ blob_reset(&c1);
486
+ blob_reset(&c2);
487
+ @ %h(blob_str(&diff))
488
+ @ </pre></blockquote>
489
+ blob_reset(&diff);
431490
style_footer();
432491
}
433
-#endif
492
+
493
+/*
494
+** WEBPAGE: fview
495
+**
496
+** Show the complete content of a file identified by g.zExtra
497
+*/
498
+void fview_page(void){
499
+ int rid;
500
+ Blob content;
501
+
502
+ rid = name_to_rid(g.zExtra);
503
+ login_check_credentials();
504
+ if( !g.okHistory ){ login_needed(); return; }
505
+ style_header("File Content");
506
+ @ <h2>Content Of:</h2>
507
+ @ <blockquote>
508
+ object_description(rid, 0);
509
+ @ </blockquote>
510
+ @ <hr>
511
+ @ <blockquote><pre>
512
+ content_get(rid, &content);
513
+ @ %h(blob_str(&content))
514
+ @ </pre></blockquote>
515
+ blob_reset(&content);
516
+ style_footer();
517
+}
434518
--- src/info.c
+++ src/info.c
@@ -278,23 +278,30 @@
278 if( !g.okHistory ){ login_needed(); return; }
279 style_header("File History");
280
281 zPrevDate[0] = 0;
282 db_prepare(&q,
283 "SELECT blob.uuid, datetime(event.mtime,'localtime'),"
284 " event.comment, event.user"
285 " FROM mlink, blob, event"
286 " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
287 " AND blob.rid=mlink.mid"
 
288 " AND event.objid=mlink.mid"
289 " ORDER BY event.mtime DESC",
290 g.zExtra
291 );
292 @ <h2>History of %h(g.zExtra)</h2>
293 @ <table cellspacing=0 border=0 cellpadding=0>
294 while( db_step(&q)==SQLITE_ROW ){
295 const char *zDate = db_column_text(&q, 1);
 
 
 
 
 
 
296 if( memcmp(zDate, zPrevDate, 10) ){
297 sprintf(zPrevDate, "%.10s", zDate);
298 @ <tr><td colspan=3>
299 @ <table cellpadding=2 border=0>
300 @ <tr><td bgcolor="#a0b5f4" class="border1">
@@ -305,12 +312,16 @@
305 @ </td></tr>
306 }
307 @ <tr><td valign="top">%s(&zDate[11])</td>
308 @ <td width="20"></td>
309 @ <td valign="top" align="left">
310 hyperlink_to_uuid(db_column_text(&q,0));
311 @ %h(db_column_text(&q,2)) (by %h(db_column_text(&q,3)))</td>
 
 
 
 
312 }
313 db_finalize(&q);
314 @ </table>
315 style_footer();
316 }
@@ -335,14 +346,12 @@
335 ** WEBPAGE: vdiff
336 **
337 ** Show all differences for a particular check-in specified by g.zExtra
338 */
339 void vdiff_page(void){
340 int rid, i;
341 Stmt q;
342 Manifest m;
343 Blob mfile, file;
344 char *zUuid;
345
346 login_check_credentials();
347 if( !g.okHistory ){ login_needed(); return; }
348 style_header("Version Diff");
@@ -375,59 +384,134 @@
375 db_finalize(&q);
376 style_footer();
377 }
378
379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380
381 #if 0
382 /*
383 ** WEB PAGE: diff
384 **
385 ** Display the difference between two files determined by the v1 and v2
386 ** query parameters. If only v2 is given compute v1 as the parent of v2.
387 ** If v2 has no parent, then show the complete text of v2.
388 */
389 void diff_page(void){
390 const char *zV1 = P("v1");
391 const char *zV2 = P("v2");
392 int vid1, vid2;
393 Blob out;
394 Record *p1, *p2;
395
396 if( zV2==0 ){
397 cgi_redirect("index");
398 }
399 vid2 = uuid_to_rid(zV2, 0);
400 p2 = record_from_rid(vid2);
401 style_header("File Diff");
402 if( zV1==0 ){
403 zV1 = db_text(0,
404 "SELECT uuid FROM record WHERE rid="
405 " (SELECT a FROM link WHERE typecode='P' AND b=%d)", vid2);
406 }
407 if( zV1==0 ){
408 @ <p>Content of
409 hyperlink_to_uuid(zV2);
410 @ </p>
411 @ <pre>
412 @ %h(blob_str(record_get_content(p2)))
413 @ </pre>
414 }else{
415 vid1 = uuid_to_rid(zV1, 0);
416 p1 = record_from_rid(vid1);
417 blob_zero(&out);
418 unified_diff(record_get_content(p1), record_get_content(p2), 4, &out);
419 @ <p>Differences between
420 hyperlink_to_uuid(zV1);
421 @ and
422 hyperlink_to_uuid(zV2);
423 @ </p>
424 @ <pre>
425 @ %h(blob_str(&out))
426 @ </pre>
427 record_destroy(p1);
428 blob_reset(&out);
429 }
430 record_destroy(p2);
431 style_footer();
432 }
433 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
--- src/info.c
+++ src/info.c
@@ -278,23 +278,30 @@
278 if( !g.okHistory ){ login_needed(); return; }
279 style_header("File History");
280
281 zPrevDate[0] = 0;
282 db_prepare(&q,
283 "SELECT a.uuid, substr(b.uuid,1,10), datetime(event.mtime,'localtime'),"
284 " event.comment, event.user, mlink.pid, mlink.fid"
285 " FROM mlink, blob a, blob b, event"
286 " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
287 " AND a.rid=mlink.mid"
288 " AND b.rid=mlink.fid"
289 " AND event.objid=mlink.mid"
290 " ORDER BY event.mtime DESC",
291 g.zExtra
292 );
293 @ <h2>History of %h(g.zExtra)</h2>
294 @ <table cellspacing=0 border=0 cellpadding=0>
295 while( db_step(&q)==SQLITE_ROW ){
296 const char *zVers = db_column_text(&q, 0);
297 const char *zUuid = db_column_text(&q, 1);
298 const char *zDate = db_column_text(&q, 2);
299 const char *zCom = db_column_text(&q, 3);
300 const char *zUser = db_column_text(&q, 4);
301 int fpid = db_column_int(&q, 5);
302 int frid = db_column_int(&q, 6);
303 if( memcmp(zDate, zPrevDate, 10) ){
304 sprintf(zPrevDate, "%.10s", zDate);
305 @ <tr><td colspan=3>
306 @ <table cellpadding=2 border=0>
307 @ <tr><td bgcolor="#a0b5f4" class="border1">
@@ -305,12 +312,16 @@
312 @ </td></tr>
313 }
314 @ <tr><td valign="top">%s(&zDate[11])</td>
315 @ <td width="20"></td>
316 @ <td valign="top" align="left">
317 hyperlink_to_uuid(zVers);
318 @ %h(zCom) (By: %h(zUser))
319 @ Id: %s(zUuid)/%d(frid)
320 @ <a href="%s(g.zBaseURL)/fview/%d(frid)">[view]</a>
321 @ <a href="%s(g.zBaseURL)/fdiff?v1=%d(fpid)&amp;v2=%d(frid)">[diff]</a>
322 @ </td>
323 }
324 db_finalize(&q);
325 @ </table>
326 style_footer();
327 }
@@ -335,14 +346,12 @@
346 ** WEBPAGE: vdiff
347 **
348 ** Show all differences for a particular check-in specified by g.zExtra
349 */
350 void vdiff_page(void){
351 int rid;
352 Stmt q;
 
 
353 char *zUuid;
354
355 login_check_credentials();
356 if( !g.okHistory ){ login_needed(); return; }
357 style_header("Version Diff");
@@ -375,59 +384,134 @@
384 db_finalize(&q);
385 style_footer();
386 }
387
388
389 /*
390 ** Write a description of an object to the www reply.
391 **
392 ** If the object is a file then mention:
393 **
394 ** * It's uuid
395 ** * All its filenames
396 ** * The versions it was checked-in on, with times and users
397 **
398 ** If the object is a manifest, then mention:
399 **
400 ** * It's uuid
401 ** * date of check-in
402 ** * Comment & user
403 */
404 static void object_description(int rid, int linkToView){
405 Stmt q;
406 int cnt = 0;
407 db_prepare(&q,
408 "SELECT filename.name, datetime(event.mtime), substr(a.uuid,1,10),"
409 " event.comment, event.user, b.uuid"
410 " FROM mlink, filename, event, blob a, blob b"
411 " WHERE filename.fnid=mlink.fnid"
412 " AND event.objid=mlink.mid"
413 " AND a.rid=mlink.fid"
414 " AND b.rid=mlink.mid"
415 " AND mlink.fid=%d",
416 rid
417 );
418 while( db_step(&q)==SQLITE_ROW ){
419 const char *zName = db_column_text(&q, 0);
420 const char *zDate = db_column_text(&q, 1);
421 const char *zFuuid = db_column_text(&q, 2);
422 const char *zCom = db_column_text(&q, 3);
423 const char *zUser = db_column_text(&q, 4);
424 const char *zVers = db_column_text(&q, 5);
425 @ File <a href="%s(g.zBaseURL)/finfo/%T(zName)">%h(zName)</a>
426 @ uuid %s(zFuuid) part of check-in
427 hyperlink_to_uuid(zVers);
428 @ %s(zCom) by %s(zUser) on %s(zDate).
429 cnt++;
430 }
431 db_finalize(&q);
432 db_prepare(&q,
433 "SELECT datetime(mtime), user, comment, uuid"
434 " FROM event, blob"
435 " WHERE event.objid=%d"
436 " AND blob.rid=%d",
437 rid, rid
438 );
439 while( db_step(&q)==SQLITE_ROW ){
440 const char *zDate = db_column_text(&q, 0);
441 const char *zUuid = db_column_text(&q, 3);
442 const char *zCom = db_column_text(&q, 2);
443 const char *zUser = db_column_text(&q, 1);
444 @ Version
445 hyperlink_to_uuid(zUuid);
446 @ %s(zCom) by %s(zUser) on %s(zDate).
447 cnt++;
448 }
449 db_finalize(&q);
450 if( cnt==0 ){
451 @ Empty file
452 }else if( linkToView ){
453 @ <a href="%s(g.zBaseURL)/fview/%d(rid)">[view]</a>
454 }
455 }
456
 
457 /*
458 ** WEBPAGE: fdiff
459 **
460 ** Two arguments, v1 and v2, are integers. Show the difference between
461 ** the two records.
 
462 */
463 void diff_page(void){
464 int v1 = atoi(PD("v1","0"));
465 int v2 = atoi(PD("v2","0"));
466 Blob c1, c2, diff;
467
468 login_check_credentials();
469 if( !g.okHistory ){ login_needed(); return; }
470 style_header("Diff");
471 @ <h2>Differences From:</h2>
472 @ <blockquote>
473 object_description(v1, 1);
474 @ </blockquote>
475 @ <h2>To:</h2>
476 @ <blockquote>
477 object_description(v2, 1);
478 @ </blockquote>
479 @ <hr>
480 @ <blockquote><pre>
481 content_get(v1, &c1);
482 content_get(v2, &c2);
483 blob_zero(&diff);
484 unified_diff(&c1, &c2, 4, &diff);
485 blob_reset(&c1);
486 blob_reset(&c2);
487 @ %h(blob_str(&diff))
488 @ </pre></blockquote>
489 blob_reset(&diff);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
490 style_footer();
491 }
492
493 /*
494 ** WEBPAGE: fview
495 **
496 ** Show the complete content of a file identified by g.zExtra
497 */
498 void fview_page(void){
499 int rid;
500 Blob content;
501
502 rid = name_to_rid(g.zExtra);
503 login_check_credentials();
504 if( !g.okHistory ){ login_needed(); return; }
505 style_header("File Content");
506 @ <h2>Content Of:</h2>
507 @ <blockquote>
508 object_description(rid, 0);
509 @ </blockquote>
510 @ <hr>
511 @ <blockquote><pre>
512 content_get(rid, &content);
513 @ %h(blob_str(&content))
514 @ </pre></blockquote>
515 blob_reset(&content);
516 style_footer();
517 }
518

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button