Fossil SCM

Add the a=, b=, and n= query parameters to the finfo web method. Show all duplicate entries in a timeline in the right-most rail.

drh 2011-05-12 00:02 trunk
Commit cbc84ad65cfcb8b138e750c1114934efc8af24c4
2 files changed +26 -4 +28 -13
+26 -4
--- src/finfo.c
+++ src/finfo.c
@@ -186,27 +186,38 @@
186186
187187
/*
188188
** WEBPAGE: finfo
189189
** URL: /finfo?name=FILENAME
190190
**
191
-** Show the complete change history for a single file.
191
+** Show the change history for a single file.
192
+**
193
+** Additional query parameters:
194
+**
195
+** a=DATE Only show changes after DATE
196
+** b=DATE Only show changes before DATE
197
+** n=NUM Show the first NUM changes only
192198
*/
193199
void finfo_page(void){
194200
Stmt q;
195201
const char *zFilename;
196202
char zPrevDate[20];
203
+ const char *zA;
204
+ const char *zB;
205
+ int n;
197206
Blob title;
207
+ Blob sql;
198208
GraphContext *pGraph;
199209
200210
login_check_credentials();
201211
if( !g.okRead ){ login_needed(); return; }
202212
style_header("File History");
203213
login_anonymous_available();
204214
205215
zPrevDate[0] = 0;
206216
zFilename = PD("name","");
207
- db_prepare(&q,
217
+ blob_zero(&sql);
218
+ blob_appendf(&sql,
208219
"SELECT"
209220
" datetime(event.mtime,'localtime')," /* Date of change */
210221
" coalesce(event.ecomment, event.comment)," /* Check-in comment */
211222
" coalesce(event.euser, event.user)," /* User who made chng */
212223
" mlink.pid," /* Parent rid */
@@ -217,15 +228,26 @@
217228
" event.bgcolor," /* Background color */
218229
" (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0"
219230
" AND tagxref.rid=mlink.mid)" /* Tags */
220231
" FROM mlink, event"
221232
" WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
222
- " AND event.objid=mlink.mid"
223
- " ORDER BY event.mtime DESC /*sort*/",
233
+ " AND event.objid=mlink.mid",
224234
TAG_BRANCH,
225235
zFilename
226236
);
237
+ if( (zA = P("a"))!=0 ){
238
+ blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA);
239
+ }
240
+ if( (zB = P("b"))!=0 ){
241
+ blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zB);
242
+ }
243
+ blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/");
244
+ if( (n = atoi(PD("n","0")))>0 ){
245
+ blob_appendf(&sql, " LIMIT %d", n);
246
+ }
247
+ db_prepare(&q, blob_str(&sql));
248
+ blob_reset(&sql);
227249
blob_zero(&title);
228250
blob_appendf(&title, "History of ");
229251
hyperlinked_path(zFilename, &title, 0);
230252
@ <h2>%b(&title)</h2>
231253
blob_reset(&title);
232254
--- src/finfo.c
+++ src/finfo.c
@@ -186,27 +186,38 @@
186
187 /*
188 ** WEBPAGE: finfo
189 ** URL: /finfo?name=FILENAME
190 **
191 ** Show the complete change history for a single file.
 
 
 
 
 
 
192 */
193 void finfo_page(void){
194 Stmt q;
195 const char *zFilename;
196 char zPrevDate[20];
 
 
 
197 Blob title;
 
198 GraphContext *pGraph;
199
200 login_check_credentials();
201 if( !g.okRead ){ login_needed(); return; }
202 style_header("File History");
203 login_anonymous_available();
204
205 zPrevDate[0] = 0;
206 zFilename = PD("name","");
207 db_prepare(&q,
 
208 "SELECT"
209 " datetime(event.mtime,'localtime')," /* Date of change */
210 " coalesce(event.ecomment, event.comment)," /* Check-in comment */
211 " coalesce(event.euser, event.user)," /* User who made chng */
212 " mlink.pid," /* Parent rid */
@@ -217,15 +228,26 @@
217 " event.bgcolor," /* Background color */
218 " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0"
219 " AND tagxref.rid=mlink.mid)" /* Tags */
220 " FROM mlink, event"
221 " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
222 " AND event.objid=mlink.mid"
223 " ORDER BY event.mtime DESC /*sort*/",
224 TAG_BRANCH,
225 zFilename
226 );
 
 
 
 
 
 
 
 
 
 
 
 
227 blob_zero(&title);
228 blob_appendf(&title, "History of ");
229 hyperlinked_path(zFilename, &title, 0);
230 @ <h2>%b(&title)</h2>
231 blob_reset(&title);
232
--- src/finfo.c
+++ src/finfo.c
@@ -186,27 +186,38 @@
186
187 /*
188 ** WEBPAGE: finfo
189 ** URL: /finfo?name=FILENAME
190 **
191 ** Show the change history for a single file.
192 **
193 ** Additional query parameters:
194 **
195 ** a=DATE Only show changes after DATE
196 ** b=DATE Only show changes before DATE
197 ** n=NUM Show the first NUM changes only
198 */
199 void finfo_page(void){
200 Stmt q;
201 const char *zFilename;
202 char zPrevDate[20];
203 const char *zA;
204 const char *zB;
205 int n;
206 Blob title;
207 Blob sql;
208 GraphContext *pGraph;
209
210 login_check_credentials();
211 if( !g.okRead ){ login_needed(); return; }
212 style_header("File History");
213 login_anonymous_available();
214
215 zPrevDate[0] = 0;
216 zFilename = PD("name","");
217 blob_zero(&sql);
218 blob_appendf(&sql,
219 "SELECT"
220 " datetime(event.mtime,'localtime')," /* Date of change */
221 " coalesce(event.ecomment, event.comment)," /* Check-in comment */
222 " coalesce(event.euser, event.user)," /* User who made chng */
223 " mlink.pid," /* Parent rid */
@@ -217,15 +228,26 @@
228 " event.bgcolor," /* Background color */
229 " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0"
230 " AND tagxref.rid=mlink.mid)" /* Tags */
231 " FROM mlink, event"
232 " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
233 " AND event.objid=mlink.mid",
 
234 TAG_BRANCH,
235 zFilename
236 );
237 if( (zA = P("a"))!=0 ){
238 blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA);
239 }
240 if( (zB = P("b"))!=0 ){
241 blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zB);
242 }
243 blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/");
244 if( (n = atoi(PD("n","0")))>0 ){
245 blob_appendf(&sql, " LIMIT %d", n);
246 }
247 db_prepare(&q, blob_str(&sql));
248 blob_reset(&sql);
249 blob_zero(&title);
250 blob_appendf(&title, "History of ");
251 hyperlinked_path(zFilename, &title, 0);
252 @ <h2>%b(&title)</h2>
253 blob_reset(&title);
254
+28 -13
--- src/graph.c
+++ src/graph.c
@@ -69,10 +69,15 @@
6969
int nRow; /* Number of rows */
7070
int nHash; /* Number of slots in apHash[] */
7171
GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
7272
};
7373
74
+/* Options for graph_finish():
75
+*/
76
+#define GRAPH_DISJOINT 0x0001 /* All elements disjoint */
77
+#define GRAPH_ISOLATE_MERGEIN 0x0002 /* Merge-in nodes isolated */
78
+
7479
#endif
7580
7681
/*
7782
** Malloc for zeroed space. Panic if unable to provide the
7883
** requested space.
@@ -306,20 +311,35 @@
306311
}
307312
}
308313
pChild->mergeIn[pParent->mergeOut/4] = (pParent->mergeOut&3)+1;
309314
}
310315
316
+/*
317
+** Compute the maximum rail number.
318
+*/
319
+static void find_max_rail(GraphContext *p){
320
+ GraphRow *pRow;
321
+ p->mxRail = 0;
322
+ for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
323
+ if( pRow->iRail>p->mxRail ) p->mxRail = pRow->iRail;
324
+ if( pRow->mergeOut/4>p->mxRail ) p->mxRail = pRow->mergeOut/4;
325
+ while( p->mxRail<GR_MAX_RAIL && pRow->mergeDown>((1<<(p->mxRail+1))-1) ){
326
+ p->mxRail++;
327
+ }
328
+ }
329
+}
330
+
311331
312332
/*
313333
** Compute the complete graph
314334
*/
315335
void graph_finish(GraphContext *p, int omitDescenders){
316336
GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
317337
int i;
318338
u32 mask;
319339
u32 inUse;
320
- int hasDup = 0; /* True if one or more isDup entries */
340
+ int hasDup = 0; /* True if one or more isDup entries */
321341
const char *zTrunk;
322342
323343
if( p==0 || p->pFirst==0 || p->nErr ) return;
324344
p->nErr = 1; /* Assume an error until proven otherwise */
325345
@@ -435,14 +455,11 @@
435455
}
436456
}
437457
continue;
438458
}
439459
if( pRow->isDup ){
440
- pRow->iRail = findFreeRail(p, pRow->idx, pRow->idx, inUse, 0);
441
- if( p->mxRail>=GR_MAX_RAIL ) return;
442
- pDesc = pRow;
443
- pParent = 0;
460
+ continue;
444461
}else{
445462
assert( pRow->nParent>0 );
446463
parentRid = pRow->aParent[0];
447464
pParent = hashFind(p, parentRid);
448465
if( pParent==0 ){
@@ -515,12 +532,17 @@
515532
516533
/*
517534
** Insert merge rails from primaries to duplicates.
518535
*/
519536
if( hasDup ){
537
+ int dupRail;
538
+ find_max_rail(p);
539
+ dupRail = ++p->mxRail;
540
+ if( p->mxRail>=GR_MAX_RAIL ) return;
520541
for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
521542
if( !pRow->isDup ) continue;
543
+ pRow->iRail = dupRail;
522544
pDesc = hashFind(p, pRow->rid);
523545
assert( pDesc!=0 && pDesc!=pRow );
524546
createMergeRiser(p, pDesc, pRow);
525547
}
526548
if( p->mxRail>=GR_MAX_RAIL ) return;
@@ -527,15 +549,8 @@
527549
}
528550
529551
/*
530552
** Find the maximum rail number.
531553
*/
532
- p->mxRail = 0;
533
- for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
534
- if( pRow->iRail>p->mxRail ) p->mxRail = pRow->iRail;
535
- if( pRow->mergeOut/4>p->mxRail ) p->mxRail = pRow->mergeOut/4;
536
- while( p->mxRail<GR_MAX_RAIL && pRow->mergeDown>((1<<(p->mxRail+1))-1) ){
537
- p->mxRail++;
538
- }
539
- }
554
+ find_max_rail(p);
540555
p->nErr = 0;
541556
}
542557
--- src/graph.c
+++ src/graph.c
@@ -69,10 +69,15 @@
69 int nRow; /* Number of rows */
70 int nHash; /* Number of slots in apHash[] */
71 GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
72 };
73
 
 
 
 
 
74 #endif
75
76 /*
77 ** Malloc for zeroed space. Panic if unable to provide the
78 ** requested space.
@@ -306,20 +311,35 @@
306 }
307 }
308 pChild->mergeIn[pParent->mergeOut/4] = (pParent->mergeOut&3)+1;
309 }
310
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
312 /*
313 ** Compute the complete graph
314 */
315 void graph_finish(GraphContext *p, int omitDescenders){
316 GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
317 int i;
318 u32 mask;
319 u32 inUse;
320 int hasDup = 0; /* True if one or more isDup entries */
321 const char *zTrunk;
322
323 if( p==0 || p->pFirst==0 || p->nErr ) return;
324 p->nErr = 1; /* Assume an error until proven otherwise */
325
@@ -435,14 +455,11 @@
435 }
436 }
437 continue;
438 }
439 if( pRow->isDup ){
440 pRow->iRail = findFreeRail(p, pRow->idx, pRow->idx, inUse, 0);
441 if( p->mxRail>=GR_MAX_RAIL ) return;
442 pDesc = pRow;
443 pParent = 0;
444 }else{
445 assert( pRow->nParent>0 );
446 parentRid = pRow->aParent[0];
447 pParent = hashFind(p, parentRid);
448 if( pParent==0 ){
@@ -515,12 +532,17 @@
515
516 /*
517 ** Insert merge rails from primaries to duplicates.
518 */
519 if( hasDup ){
 
 
 
 
520 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
521 if( !pRow->isDup ) continue;
 
522 pDesc = hashFind(p, pRow->rid);
523 assert( pDesc!=0 && pDesc!=pRow );
524 createMergeRiser(p, pDesc, pRow);
525 }
526 if( p->mxRail>=GR_MAX_RAIL ) return;
@@ -527,15 +549,8 @@
527 }
528
529 /*
530 ** Find the maximum rail number.
531 */
532 p->mxRail = 0;
533 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
534 if( pRow->iRail>p->mxRail ) p->mxRail = pRow->iRail;
535 if( pRow->mergeOut/4>p->mxRail ) p->mxRail = pRow->mergeOut/4;
536 while( p->mxRail<GR_MAX_RAIL && pRow->mergeDown>((1<<(p->mxRail+1))-1) ){
537 p->mxRail++;
538 }
539 }
540 p->nErr = 0;
541 }
542
--- src/graph.c
+++ src/graph.c
@@ -69,10 +69,15 @@
69 int nRow; /* Number of rows */
70 int nHash; /* Number of slots in apHash[] */
71 GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
72 };
73
74 /* Options for graph_finish():
75 */
76 #define GRAPH_DISJOINT 0x0001 /* All elements disjoint */
77 #define GRAPH_ISOLATE_MERGEIN 0x0002 /* Merge-in nodes isolated */
78
79 #endif
80
81 /*
82 ** Malloc for zeroed space. Panic if unable to provide the
83 ** requested space.
@@ -306,20 +311,35 @@
311 }
312 }
313 pChild->mergeIn[pParent->mergeOut/4] = (pParent->mergeOut&3)+1;
314 }
315
316 /*
317 ** Compute the maximum rail number.
318 */
319 static void find_max_rail(GraphContext *p){
320 GraphRow *pRow;
321 p->mxRail = 0;
322 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
323 if( pRow->iRail>p->mxRail ) p->mxRail = pRow->iRail;
324 if( pRow->mergeOut/4>p->mxRail ) p->mxRail = pRow->mergeOut/4;
325 while( p->mxRail<GR_MAX_RAIL && pRow->mergeDown>((1<<(p->mxRail+1))-1) ){
326 p->mxRail++;
327 }
328 }
329 }
330
331
332 /*
333 ** Compute the complete graph
334 */
335 void graph_finish(GraphContext *p, int omitDescenders){
336 GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
337 int i;
338 u32 mask;
339 u32 inUse;
340 int hasDup = 0; /* True if one or more isDup entries */
341 const char *zTrunk;
342
343 if( p==0 || p->pFirst==0 || p->nErr ) return;
344 p->nErr = 1; /* Assume an error until proven otherwise */
345
@@ -435,14 +455,11 @@
455 }
456 }
457 continue;
458 }
459 if( pRow->isDup ){
460 continue;
 
 
 
461 }else{
462 assert( pRow->nParent>0 );
463 parentRid = pRow->aParent[0];
464 pParent = hashFind(p, parentRid);
465 if( pParent==0 ){
@@ -515,12 +532,17 @@
532
533 /*
534 ** Insert merge rails from primaries to duplicates.
535 */
536 if( hasDup ){
537 int dupRail;
538 find_max_rail(p);
539 dupRail = ++p->mxRail;
540 if( p->mxRail>=GR_MAX_RAIL ) return;
541 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
542 if( !pRow->isDup ) continue;
543 pRow->iRail = dupRail;
544 pDesc = hashFind(p, pRow->rid);
545 assert( pDesc!=0 && pDesc!=pRow );
546 createMergeRiser(p, pDesc, pRow);
547 }
548 if( p->mxRail>=GR_MAX_RAIL ) return;
@@ -527,15 +549,8 @@
549 }
550
551 /*
552 ** Find the maximum rail number.
553 */
554 find_max_rail(p);
 
 
 
 
 
 
 
555 p->nErr = 0;
556 }
557

Keyboard Shortcuts

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