Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Add the "circa" capability to the timeline. Check-in hyperlinks go to the "diff" page by default, rather than the "detail" page. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
5a539f82dc57e0a6794def3d1cbc367c |
| User & Date: | drh 2009-08-15 16:47:42.000 |
Context
|
2009-08-15
| ||
| 16:50 | Fix faulty SQL in the "db_unset()" routine. Ticket [31bd22c31fcc] ... (check-in: 74f7f6e6ad user: drh tags: trunk) | |
| 16:47 | Add the "circa" capability to the timeline. Check-in hyperlinks go to the "diff" page by default, rather than the "detail" page. ... (check-in: 5a539f82dc user: drh tags: trunk) | |
| 13:21 | Fix a memory allocation bug in the ZIP archive generator. Ticket [8d6efe4f927] ... (check-in: 5b91887495 user: drh tags: trunk) | |
Changes
Changes to src/info.c.
| ︙ | ︙ | |||
423 424 425 426 427 428 429 |
const char *zTagName = db_column_text(&q, 0);
@ | <a href="%s(g.zBaseURL)/timeline?t=%T(zTagName)">%h(zTagName)</a>
}
db_finalize(&q);
@ </td></tr>
@ <tr><th>Commands:</th>
@ <td>
| | | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 |
const char *zTagName = db_column_text(&q, 0);
@ | <a href="%s(g.zBaseURL)/timeline?t=%T(zTagName)">%h(zTagName)</a>
}
db_finalize(&q);
@ </td></tr>
@ <tr><th>Commands:</th>
@ <td>
@ <a href="%s(g.zBaseURL)/vdiff/%s(zShortUuid)">diff</a>
@ | <a href="%s(g.zBaseURL)/dir?ci=%s(zShortUuid)">files</a>
@ | <a href="%s(g.zBaseURL)/zip/%s(zProjName)-%s(zShortUuid).zip?uuid=%s(zUuid)">
@ ZIP archive</a>
@ | <a href="%s(g.zBaseURL)/artifact/%d(rid)">manifest</a>
if( g.okWrite ){
@ | <a href="%s(g.zBaseURL)/ci_edit?r=%d(rid)">edit</a>
}
|
| ︙ | ︙ | |||
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 |
blob_zero(&out);
text_diff(&from, &to, &out, 5);
@ %h(blob_str(&out))
blob_reset(&from);
blob_reset(&to);
blob_reset(&out);
}
/*
** WEBPAGE: vdiff
** URL: /vdiff?name=RID
**
** Show all differences for a particular check-in.
*/
void vdiff_page(void){
int rid;
Stmt q;
char *zUuid;
login_check_credentials();
if( !g.okRead ){ login_needed(); return; }
| > < > > > > > > > > > > > > > > > > > > > > < < < < < | 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 |
blob_zero(&out);
text_diff(&from, &to, &out, 5);
@ %h(blob_str(&out))
blob_reset(&from);
blob_reset(&to);
blob_reset(&out);
}
/*
** WEBPAGE: vdiff
** URL: /vdiff?name=RID
**
** Show all differences for a particular check-in.
*/
void vdiff_page(void){
int rid;
Stmt q;
char *zUuid;
login_check_credentials();
if( !g.okRead ){ login_needed(); return; }
login_anonymous_available();
rid = name_to_rid(PD("name",""));
if( rid==0 ){
fossil_redirect_home();
}
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
style_header("Check-in [%.10s]", zUuid);
db_prepare(&q,
"SELECT datetime(mtime), "
" coalesce(event.ecomment,event.comment),"
" coalesce(event.euser,event.user)"
" FROM event WHERE type='ci' AND objid=%d",
rid
);
while( db_step(&q)==SQLITE_ROW ){
const char *zDate = db_column_text(&q, 0);
const char *zUser = db_column_text(&q, 2);
const char *zComment = db_column_text(&q, 1);
@ <h2>Check-in %s(zUuid)</h2>
@ <p>Made by %h(zUser) on
link_to_date(zDate, ":");
@ %w(zComment). <a href="%s(g.zBaseURL)/ci/%s(zUuid)">[details]</a></p>
@ <hr>
}
db_finalize(&q);
db_prepare(&q,
"SELECT pid, fid, name"
" FROM mlink, filename"
" WHERE mlink.mid=%d"
" AND filename.fnid=mlink.fnid"
" ORDER BY name",
rid
);
while( db_step(&q)==SQLITE_ROW ){
int pid = db_column_int(&q,0);
int fid = db_column_int(&q,1);
const char *zName = db_column_text(&q,2);
@ <p><a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a></p>
@ <blockquote><pre>
append_diff(pid, fid);
@ </pre></blockquote>
}
db_finalize(&q);
style_footer();
}
/*
** Write a description of an object to the www reply.
**
** If the object is a file then mention:
**
** * It's artifact ID
|
| ︙ | ︙ | |||
849 850 851 852 853 854 855 856 857 858 859 860 861 862 |
if( pDownloadName && blob_size(pDownloadName)==0 ){
blob_append(pDownloadName, zUuid, -1);
}
}else if( linkToView ){
@ <a href="%s(g.zBaseURL)/artifact/%d(rid)">[view]</a>
}
}
/*
** WEBPAGE: fdiff
**
** Two arguments, v1 and v2, are integers. Show the difference between
** the two records.
*/
| > | 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 |
if( pDownloadName && blob_size(pDownloadName)==0 ){
blob_append(pDownloadName, zUuid, -1);
}
}else if( linkToView ){
@ <a href="%s(g.zBaseURL)/artifact/%d(rid)">[view]</a>
}
}
/*
** WEBPAGE: fdiff
**
** Two arguments, v1 and v2, are integers. Show the difference between
** the two records.
*/
|
| ︙ | ︙ | |||
1190 1191 1192 1193 1194 1195 1196 |
if( rid==0 ){
style_header("Broken Link");
@ <p>No such object: %h(zName)</p>
style_footer();
return;
}
if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
| | | 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 |
if( rid==0 ){
style_header("Broken Link");
@ <p>No such object: %h(zName)</p>
style_footer();
return;
}
if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
vdiff_page();
}else
if( db_exists("SELECT 1 FROM tagxref JOIN tag USING(tagid)"
" WHERE rid=%d AND tagname LIKE 'wiki-%%'", rid) ){
winfo_page();
}else
if( db_exists("SELECT 1 FROM tagxref JOIN tag USING(tagid)"
" WHERE rid=%d AND tagname LIKE 'tkt-%%'", rid) ){
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
52 53 54 55 56 57 58 |
const char *zOut, /* Javascript proc for mouseout */
int id /* Argument to javascript procs */
){
char zShortUuid[UUID_SIZE+1];
sprintf(zShortUuid, "%.10s", zUuid);
if( g.okHistory ){
@ <a onmouseover='%s(zIn)("m%d(id)")' onmouseout='%s(zOut)("m%d(id)")'
| | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
const char *zOut, /* Javascript proc for mouseout */
int id /* Argument to javascript procs */
){
char zShortUuid[UUID_SIZE+1];
sprintf(zShortUuid, "%.10s", zUuid);
if( g.okHistory ){
@ <a onmouseover='%s(zIn)("m%d(id)")' onmouseout='%s(zOut)("m%d(id)")'
@ href="%s(g.zBaseURL)/vdiff/%s(zUuid)">[%s(zShortUuid)]</a>
}else{
@ <b onmouseover='%s(zIn)("m%d(id)")' onmouseout='%s(zOut)("m%d(id)")'>
@ [%s(zShortUuid)]</b>
}
}
/*
|
| ︙ | ︙ | |||
306 307 308 309 310 311 312 313 314 315 316 317 318 319 | /* ** WEBPAGE: timeline ** ** Query parameters: ** ** a=TIMESTAMP after this date ** b=TIMESTAMP before this date. ** n=COUNT number of events in output ** p=RID artifact RID and up to COUNT parents and ancestors ** d=RID artifact RID and up to COUNT descendants ** t=TAGID show only check-ins with the given tagid ** u=USER only if belonging to this user ** y=TYPE 'ci', 'w', 't' ** | > | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | /* ** WEBPAGE: timeline ** ** Query parameters: ** ** a=TIMESTAMP after this date ** b=TIMESTAMP before this date. ** c=TIMESTAMP "circa" this date. ** n=COUNT number of events in output ** p=RID artifact RID and up to COUNT parents and ancestors ** d=RID artifact RID and up to COUNT descendants ** t=TAGID show only check-ins with the given tagid ** u=USER only if belonging to this user ** y=TYPE 'ci', 'w', 't' ** |
| ︙ | ︙ | |||
332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
int nEntry = atoi(PD("n","20")); /* Max number of entries on timeline */
int p_rid = atoi(PD("p","0")); /* artifact p and its parents */
int d_rid = atoi(PD("d","0")); /* artifact d and its descendants */
const char *zUser = P("u"); /* All entries by this user if not NULL */
const char *zType = PD("y","all"); /* Type of events. All if NULL */
const char *zAfter = P("a"); /* Events after this time */
const char *zBefore = P("b"); /* Events before this time */
const char *zTagName = P("t"); /* Show events with this tag */
HQuery url; /* URL for various branch links */
int tagid; /* Tag ID */
/* To view the timeline, must have permission to read project data.
*/
login_check_credentials();
| > | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
int nEntry = atoi(PD("n","20")); /* Max number of entries on timeline */
int p_rid = atoi(PD("p","0")); /* artifact p and its parents */
int d_rid = atoi(PD("d","0")); /* artifact d and its descendants */
const char *zUser = P("u"); /* All entries by this user if not NULL */
const char *zType = PD("y","all"); /* Type of events. All if NULL */
const char *zAfter = P("a"); /* Events after this time */
const char *zBefore = P("b"); /* Events before this time */
const char *zCirca = P("c"); /* Events near this time */
const char *zTagName = P("t"); /* Show events with this tag */
HQuery url; /* URL for various branch links */
int tagid; /* Tag ID */
/* To view the timeline, must have permission to read project data.
*/
login_check_credentials();
|
| ︙ | ︙ | |||
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 |
blob_appendf(&sql,
" AND event.mtime<=(SELECT julianday(%Q, 'utc'))"
" ORDER BY event.mtime DESC", zBefore);
url_add_parameter(&url, "b", zBefore);
}else{
zBefore = 0;
}
}else{
blob_appendf(&sql, " ORDER BY event.mtime DESC");
}
blob_appendf(&sql, " LIMIT %d", nEntry);
db_multi_exec("%s", blob_str(&sql));
n = db_int(0, "SELECT count(*) FROM timeline");
if( n<nEntry && zAfter ){
cgi_redirect(url_render(&url, "a", 0, "b", 0));
}
| > > > > > > > > > > > > > > > > > > > > > | > > | 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 |
blob_appendf(&sql,
" AND event.mtime<=(SELECT julianday(%Q, 'utc'))"
" ORDER BY event.mtime DESC", zBefore);
url_add_parameter(&url, "b", zBefore);
}else{
zBefore = 0;
}
}else if( zCirca ){
while( isspace(zCirca[0]) ){ zCirca++; }
if( zCirca[0] ){
double rCirca = db_double(0.0, "SELECT julianday(%Q, 'utc')", zCirca);
Blob sql2;
blob_init(&sql2, blob_str(&sql), -1);
blob_appendf(&sql2,
" AND event.mtime<=%f ORDER BY event.mtime DESC LIMIT %d",
rCirca, (nEntry+1)/2
);
db_multi_exec("%s", blob_str(&sql2));
blob_reset(&sql2);
blob_appendf(&sql,
" AND event.mtime>=%f ORDER BY event.mtime ASC",
rCirca
);
nEntry -= (nEntry+1)/2;
url_add_parameter(&url, "c", zCirca);
}else{
zCirca = 0;
}
}else{
blob_appendf(&sql, " ORDER BY event.mtime DESC");
}
blob_appendf(&sql, " LIMIT %d", nEntry);
db_multi_exec("%s", blob_str(&sql));
n = db_int(0, "SELECT count(*) FROM timeline");
if( n<nEntry && zAfter ){
cgi_redirect(url_render(&url, "a", 0, "b", 0));
}
if( zAfter==0 && zBefore==0 && zCirca==0 ){
blob_appendf(&desc, "%d most recent %ss", n, zEType);
}else{
blob_appendf(&desc, "%d %ss", n, zEType);
}
if( zUser ){
blob_appendf(&desc, " by user %h", zUser);
}
if( tagid>0 ){
blob_appendf(&desc, " tagged with \"%h\"", zTagName);
}
if( zAfter ){
blob_appendf(&desc, " occurring on or after %h.<br>", zAfter);
}else if( zBefore ){
blob_appendf(&desc, " occurring on or before %h.<br>", zBefore);
}else if( zCirca ){
blob_appendf(&desc, " occurring around %h.<br>", zCirca);
}
if( g.okHistory ){
if( zAfter || n==nEntry ){
zDate = db_text(0, "SELECT min(timestamp) FROM timeline");
timeline_submenu(&url, "Older", "b", zDate, "a");
free(zDate);
}
|
| ︙ | ︙ | |||
599 600 601 602 603 604 605 606 607 608 609 610 611 612 | @ set_children(cid,clr); @ } @ } @ } @ </script> style_footer(); } /* ** The input query q selects various records. Print a human-readable ** summary of those records. ** ** Limit the number of entries printed to nLine. ** | > > > > > > > | 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 |
@ set_children(cid,clr);
@ }
@ }
@ }
@ </script>
style_footer();
}
/*
** Render the date string given as a hyperlink to a "circa" timeline.
*/
void link_to_date(const char *zDate, const char *zSuffix){
@ <a href="%s(g.zBaseURL)/timeline?c=%t(zDate)">%h(zDate)</a>%s(zSuffix)
}
/*
** The input query q selects various records. Print a human-readable
** summary of those records.
**
** Limit the number of entries printed to nLine.
**
|
| ︙ | ︙ |