Fossil

Check-in [b7f32a71ab]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add web-based branch color changer. Add the "branch list" command. Simplifications to color propagation logic.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b7f32a71ab78f3e9813e685fda37c0fc5937b05a
User & Date: drh 2009-01-20 22:21:24.000
Context
2009-01-20
22:38
Require that the "branch new" command specify a basis. Do not let it use the current check-out. Otherwise it gets confusing to users. check-in: 4d39bbac10 user: drh tags: trunk
22:21
Add web-based branch color changer. Add the "branch list" command. Simplifications to color propagation logic. check-in: b7f32a71ab user: drh tags: trunk
16:51
Attempting to rationalize the tagging and branching logic. The "branch" command has been resurrected and appears to work now. The "tag branch" command has been removed. Special tags "newbranch" and "closed" used to manage branches. New changes are not well-tested - use with caution. You must "rebuild" when upgrading through this version. check-in: b6e22e62cf user: drh tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/branch.c.
202
203
204
205
206
207
208
209









210
211
212
213
214
  if( g.argc<3 ){
    usage("new|list ...");
  }
  n = strlen(g.argv[2]);
  if( n>=2 && strncmp(g.argv[2],"new",n)==0 ){
    branch_new();
  }else if( n>=2 && strncmp(g.argv[2],"list",n)==0 ){
    fossil_panic("branch list is not yet completed");









  }else{
    fossil_panic("branch subcommand should be one of: "
                 "new list");
  }
}







|
>
>
>
>
>
>
>
>
>





202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
  if( g.argc<3 ){
    usage("new|list ...");
  }
  n = strlen(g.argv[2]);
  if( n>=2 && strncmp(g.argv[2],"new",n)==0 ){
    branch_new();
  }else if( n>=2 && strncmp(g.argv[2],"list",n)==0 ){
    Stmt q;
    db_prepare(&q,
      "%s"
      "   AND blob.rid IN (SELECT rid FROM tagxref"
      "                     WHERE tagid=%d AND tagtype==1)"
      " ORDER BY event.mtime DESC",
      timeline_query_for_tty(), TAG_NEWBRANCH
    );
    print_timeline(&q, 2000);
    db_finalize(&q);
  }else{
    fossil_panic("branch subcommand should be one of: "
                 "new list");
  }
}
Changes to src/checkin.c.
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
      blob_reset(&b);
    }
    g.aCommitFile[ii-2] = 0;
  }
}

/*
** Return true if the check-in with RID=rid has one or more child
** check-ins which are not tagged with "newbranch".  In other words,
** return true if the check-in is not a leaf.
*/
int is_not_a_leaf(int rid){
  return db_exists(
    "SELECT 1 FROM plink"
    " WHERE pid=%d"
      " AND NOT EXIST("
                     "SELECT 1 FROM tagxref"
                     " WHERE tagxref.rid=plink.cid"
                     "   AND tagxref.tagid=%d"
                     "   AND tagxref.tagtype=1"







|

|

|
|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
      blob_reset(&b);
    }
    g.aCommitFile[ii-2] = 0;
  }
}

/*
** Return true if the check-in with RID=rid has no child
** check-ins which are not tagged with "newbranch".  In other words,
** return true if the check-in is a leaf.
*/
int is_a_leaf(int rid){
  return !db_exists(
    "SELECT 1 FROM plink"
    " WHERE pid=%d"
      " AND NOT EXIST("
                     "SELECT 1 FROM tagxref"
                     " WHERE tagxref.rid=plink.cid"
                     "   AND tagxref.tagid=%d"
                     "   AND tagxref.tagtype=1"
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
    );
    if( strlen(blob_str(&unmodified)) ){
      fossil_panic("file %s has not changed", blob_str(&unmodified));
    }
  }

  vid = db_lget_int("checkout", 0);
  if( is_not_a_leaf(vid) ){
    wouldFork=1;
    if( forceFlag==0 ){
      fossil_fatal("would fork.  \"update\" first or use -f or --force.");
    }
  }
  vfile_aggregate_checksum_disk(vid, &cksum1);
  if( zComment ){







|







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
    );
    if( strlen(blob_str(&unmodified)) ){
      fossil_panic("file %s has not changed", blob_str(&unmodified));
    }
  }

  vid = db_lget_int("checkout", 0);
  if( !is_a_leaf(vid) ){
    wouldFork=1;
    if( forceFlag==0 ){
      fossil_fatal("would fork.  \"update\" first or use -f or --force.");
    }
  }
  vfile_aggregate_checksum_disk(vid, &cksum1);
  if( zComment ){
Changes to src/descendants.c.
271
272
273
274
275
276
277











278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300
  }
  if( showClosed || showAll ){
    style_submenu_element("Open", "Open", "leaves");
  }
  style_header("Leaves");
  login_anonymous_available();
  compute_leaves(0, showAll ? 0 : showClosed ? 2 : 1);











  if( showAll ){
    @ <h1>All leaves, both open and closed</h1>
  }else if( showClosed ){
    @ <h1>Closed leaves only</h1>
  }else{
    @ <h1>All open leaves</h1>
  }
  db_prepare(&q,
    "%s"
    "   AND blob.rid IN leaves"
    " ORDER BY event.mtime DESC",
    timeline_query_for_www()
  );
  www_print_timeline(&q);
  db_finalize(&q);

  @ <script>
  @ function xin(id){
  @ }
  @ function xout(id){
  @ }
  @ </script>
  style_footer();
}







>
>
>
>
>
>
>
>
>
>
>















>








271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
  }
  if( showClosed || showAll ){
    style_submenu_element("Open", "Open", "leaves");
  }
  style_header("Leaves");
  login_anonymous_available();
  compute_leaves(0, showAll ? 0 : showClosed ? 2 : 1);
  @ <table width="33%%" align="right" border="1">
  @ <tr><td>
  @ <b>Nomenclature:</b>
  @ <ol>
  @ <li> A <b>leaf</b> is a check-in with no descendants.</li>
  @ <li> An <b>open leaf</b> is a leaf that does not have a "closed" tag
  @ and is thus assumed to still be in use.</li>
  @ <li> A <b>closed leaf</b> has a "closed" tag and is thus assumed to
  @ be historical and no longer in active use.</li>
  @ </ol>
  @ </td></tr></table>
  if( showAll ){
    @ <h1>All leaves, both open and closed</h1>
  }else if( showClosed ){
    @ <h1>Closed leaves only</h1>
  }else{
    @ <h1>All open leaves</h1>
  }
  db_prepare(&q,
    "%s"
    "   AND blob.rid IN leaves"
    " ORDER BY event.mtime DESC",
    timeline_query_for_www()
  );
  www_print_timeline(&q);
  db_finalize(&q);
  @ <br clear="both">
  @ <script>
  @ function xin(id){
  @ }
  @ function xout(id){
  @ }
  @ </script>
  style_footer();
}
Changes to src/info.c.
1125
1126
1127
1128
1129
1130
1131



1132
1133















1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145




1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159








1160
1161
1162
1163
1164
1165
1166
1167




1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184















1185
1186
1187
1188
1189
1190

1191


1192
1193
1194
1195

1196

1197




























1198
1199
1200

1201
1202
1203
1204
*/
void vedit_page(void){
  int rid;
  const char *zComment;
  const char *zNewComment;
  const char *zUser;
  const char *zNewUser;



  char *zUuid;
  Blob comment;















  
  login_check_credentials();
  if( !g.okWrite ){ login_needed(); return; }
  rid = atoi(PD("r","0"));
  zComment = db_text(0, "SELECT coalesce(ecomment,comment)"
                        "  FROM event WHERE objid=%d", rid);
  if( zComment==0 ) fossil_redirect_home();
  zNewComment = PD("c",zComment);
  zUser = db_text(0, "SELECT coalesce(euser,user)"
                     "  FROM event WHERE objid=%d", rid);
  if( zUser==0 ) fossil_redirect_home();
  zNewUser = PD("u",zUser);




  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
  if( P("cancel") ){
    cgi_redirectf("vinfo?name=%d", rid);
  }
  if( P("apply") ){
    Blob ctrl;
    char *zDate;
    int nChng = 0;

    login_verify_csrf_secret();
    blob_zero(&ctrl);
    zDate = db_text(0, "SELECT datetime('now')");
    zDate[10] = 'T';
    blob_appendf(&ctrl, "D %s\n", zDate);








    if( strcmp(zComment,zNewComment)!=0 ){
      nChng++;
      blob_appendf(&ctrl, "T +comment %s %F\n", zUuid, zNewComment);
    }
    if( strcmp(zUser,zNewUser)!=0 ){
      nChng++;
      blob_appendf(&ctrl, "T +user %s %F\n", zUuid, zNewUser);
    }




    if( nChng>0 ){
      int nrid;
      Blob cksum;
      blob_appendf(&ctrl, "U %F\n", g.zLogin);
      md5sum_blob(&ctrl, &cksum);
      blob_appendf(&ctrl, "Z %b\n", &cksum);
      db_begin_transaction();
      nrid = content_put(&ctrl, 0, 0);
      manifest_crosslink(nrid, &ctrl);
      db_end_transaction(0);
    }
    cgi_redirectf("vinfo?name=%d", rid);
  }
  blob_zero(&comment);
  blob_append(&comment, zNewComment, -1);
  zUuid[10] = 0;
  style_header("Edit Baseline [%s]", zUuid);















  @ <p>Make changes to the User and Comment for baseline 
  @ [<a href="vinfo?name=%d(rid)">%s(zUuid)</a>] then press the
  @ "Apply Changes" button.</p>
  @ <form action="%s(g.zBaseURL)/vedit" method="POST">
  login_insert_csrf_secret();
  @ <input type="hidden" name="r" value="%d(rid)">

  @ <p>


  @ <b>User:</b> <input type="text" name="u" size="20" value="%h(zNewUser)">
  @ </p>
  @ <p><b>Comment:</b></b><br />
  wiki_convert(&comment, 0, WIKI_INLINE);

  @ <br /><textarea name="c" rows="10" cols="80">%h(zNewComment)</textarea></p>

  @ <blockquote>




























  @ <input type="submit" name="preview" value="Preview">
  @ <input type="submit" name="apply" value="Apply Changes">
  @ <input type="submit" name="cancel" value="Cancel">

  @ </blockquote>
  @ </form>
  style_footer();
}







>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












>
>
>
>














>
>
>
>
>
>
>
>








>
>
>
>

















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<



>
|
>
>
|
|
|
|
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>
|



1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235

1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
*/
void vedit_page(void){
  int rid;
  const char *zComment;
  const char *zNewComment;
  const char *zUser;
  const char *zNewUser;
  const char *zColor;
  const char *zNewColor;
  int fPropagateColor;
  char *zUuid;
  Blob comment;
  static const struct SampleColors {
     const char *zCName;
     const char *zColor;
  } aColor[] = {
     { "(none)",  "" },
     { "#c0ffc0", "#c0ffc0" },
     { "#c0fff0", "#c0fff0" },
     { "#c0f0ff", "#c0f0ff" },
     { "#d0c0ff", "#d0c0ff" },
     { "#ffc0ff", "#ffc0ff" },
     { "#ffc0d0", "#ffc0d0" },
     { "#fff0c0", "#fff0c0" },
     { "#f0ffc0", "#f0ffc0" },
  };
  int i;
  
  login_check_credentials();
  if( !g.okWrite ){ login_needed(); return; }
  rid = atoi(PD("r","0"));
  zComment = db_text(0, "SELECT coalesce(ecomment,comment)"
                        "  FROM event WHERE objid=%d", rid);
  if( zComment==0 ) fossil_redirect_home();
  zNewComment = PD("c",zComment);
  zUser = db_text(0, "SELECT coalesce(euser,user)"
                     "  FROM event WHERE objid=%d", rid);
  if( zUser==0 ) fossil_redirect_home();
  zNewUser = PD("u",zUser);
  zColor = db_text("", "SELECT bgcolor"
                        "  FROM event WHERE objid=%d", rid);
  zNewColor = PD("clr",zColor);
  fPropagateColor = P("pclr")!=0;
  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
  if( P("cancel") ){
    cgi_redirectf("vinfo?name=%d", rid);
  }
  if( P("apply") ){
    Blob ctrl;
    char *zDate;
    int nChng = 0;

    login_verify_csrf_secret();
    blob_zero(&ctrl);
    zDate = db_text(0, "SELECT datetime('now')");
    zDate[10] = 'T';
    blob_appendf(&ctrl, "D %s\n", zDate);
    if( zNewColor[0] && strcmp(zColor,zNewColor)!=0 ){
      nChng++;
      if( fPropagateColor ){
        blob_appendf(&ctrl, "T *bgcolor %s %F\n", zUuid, zNewColor);
      }else{
        blob_appendf(&ctrl, "T +bgcolor %s %F\n", zUuid, zNewColor);
      }
    }
    if( strcmp(zComment,zNewComment)!=0 ){
      nChng++;
      blob_appendf(&ctrl, "T +comment %s %F\n", zUuid, zNewComment);
    }
    if( strcmp(zUser,zNewUser)!=0 ){
      nChng++;
      blob_appendf(&ctrl, "T +user %s %F\n", zUuid, zNewUser);
    }
    if( zNewColor[0]==0 && zColor[0]!=0 ){
      nChng++;
      blob_appendf(&ctrl, "T -bgcolor %s\n", zUuid);
    }
    if( nChng>0 ){
      int nrid;
      Blob cksum;
      blob_appendf(&ctrl, "U %F\n", g.zLogin);
      md5sum_blob(&ctrl, &cksum);
      blob_appendf(&ctrl, "Z %b\n", &cksum);
      db_begin_transaction();
      nrid = content_put(&ctrl, 0, 0);
      manifest_crosslink(nrid, &ctrl);
      db_end_transaction(0);
    }
    cgi_redirectf("vinfo?name=%d", rid);
  }
  blob_zero(&comment);
  blob_append(&comment, zNewComment, -1);
  zUuid[10] = 0;
  style_header("Edit Baseline [%s]", zUuid);
  if( P("preview") ){
    @ <b>Preview:</b>
    @ <blockquote>
    @ <table border=0>
    if( zNewColor && zNewColor[0] ){
      @ <tr><td bgcolor="%h(zNewColor)">
    }else{
      @ <tr><td>
    }
    wiki_convert(&comment, 0, WIKI_INLINE);
    @ (user: %h(zNewUser))
    @ </td></tr></table>
    @ </blockquote>
    @ <hr>
  }
  @ <p>Make changes to attributes of check-in
  @ [<a href="vinfo?name=%d(rid)">%s(zUuid)</a>]:</p>

  @ <form action="%s(g.zBaseURL)/vedit" method="POST">
  login_insert_csrf_secret();
  @ <input type="hidden" name="r" value="%d(rid)">
  @ <table border="0" cellspacing="10">

  @ <tr><td align="right" valign="top"><b>User:</b></td>
  @ <td valign="top">
  @   <input type="text" name="u" size="20" value="%h(zNewUser)">
  @ </td></tr>

  @ <tr><td align="right" valign="top"><b>Comment:</b></td>
  @ <td valign="top">
  @ <textarea name="c" rows="10" cols="80">%h(zNewComment)</textarea>
  @ </td></tr>

  @ <tr><td align="right" valign="top"><b>Background Color:</b></td>
  @ <td valign="top">
  @ <table border=0 cellpadding=0 cellspacing=1>
  @ <tr>
  for(i=0; i<sizeof(aColor)/sizeof(aColor[0]); i++){
    if( aColor[i].zColor[0] ){
      @ <td bgcolor="%h(aColor[i].zColor)">
    }else{
      @ <td>
    }
    if( strcmp(zNewColor, aColor[i].zColor)==0 ){
      @ <input type="radio" name="clr" value="%h(aColor[i].zColor)" checked>
    }else{
      @ <input type="radio" name="clr" value="%h(aColor[i].zColor)">
    }
    @ %h(aColor[i].zCName)</input></td>
  }
  @ </tr><tr><td colspan="9" align="left">
  if( fPropagateColor ){
    @ <input type="checkbox" name="pclr" checked>
  }else{
    @ <input type="checkbox" name="pclr">
  }
  @ Propagate color to descendants</input></td></tr>
  @ </table>
  @ </td></tr>

  @ <tr><td colspan="2">
  @ <input type="submit" name="preview" value="Preview">
  @ <input type="submit" name="apply" value="Apply Changes">
  @ <input type="submit" name="cancel" value="Cancel">
  @ </td></tr>
  @ </table>
  @ </form>
  style_footer();
}
Changes to src/manifest.c.
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
      while( db_step(&q)==SQLITE_ROW ){
        int cid = db_column_int(&q, 0);
        add_mlink(rid, &m, cid, 0);
      }
      db_finalize(&q);
      db_multi_exec(
        "REPLACE INTO event(type,mtime,objid,user,comment,"
        "                  bgcolor,brbgcolor,euser,ecomment)"
        "VALUES('ci',%.17g,%d,%Q,%Q,"
        " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype=1),"
        "(SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype!=1),"
        "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
        "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
        m.rDate, rid, m.zUser, m.zComment, 
        TAG_BGCOLOR, rid,
        TAG_BGCOLOR, rid,
        TAG_USER, rid,
        TAG_COMMENT, rid
      );
    }
  }
  if( m.type==CFTYPE_CLUSTER ){
    tag_insert("cluster", 1, 0, rid, m.rDate, rid);







|

|
<




|







913
914
915
916
917
918
919
920
921
922

923
924
925
926
927
928
929
930
931
932
933
934
      while( db_step(&q)==SQLITE_ROW ){
        int cid = db_column_int(&q, 0);
        add_mlink(rid, &m, cid, 0);
      }
      db_finalize(&q);
      db_multi_exec(
        "REPLACE INTO event(type,mtime,objid,user,comment,"
        "                  bgcolor,euser,ecomment)"
        "VALUES('ci',%.17g,%d,%Q,%Q,"
        " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>0),"

        "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
        "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
        m.rDate, rid, m.zUser, m.zComment, 
        TAG_BGCOLOR, rid,
        TAG_BRBGCOLOR, rid,
        TAG_USER, rid,
        TAG_COMMENT, rid
      );
    }
  }
  if( m.type==CFTYPE_CLUSTER ){
    tag_insert("cluster", 1, 0, rid, m.rDate, rid);
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
    );
    if( prior ){
      content_deltify(prior, rid, 0);
    }
    zComment = mprintf("Changes to wiki page [%h]", m.zWikiTitle);
    db_multi_exec(
      "REPLACE INTO event(type,mtime,objid,user,comment,"
      "                  bgcolor,brbgcolor,euser,ecomment)"
      "VALUES('w',%.17g,%d,%Q,%Q,"
      "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype=1),"
      "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype!=1),"
      "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
      "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
      m.rDate, rid, m.zUser, zComment, 
      TAG_BGCOLOR, rid,
      TAG_BGCOLOR, rid,
      TAG_USER, rid,
      TAG_COMMENT, rid







|

|
<







981
982
983
984
985
986
987
988
989
990

991
992
993
994
995
996
997
    );
    if( prior ){
      content_deltify(prior, rid, 0);
    }
    zComment = mprintf("Changes to wiki page [%h]", m.zWikiTitle);
    db_multi_exec(
      "REPLACE INTO event(type,mtime,objid,user,comment,"
      "                  bgcolor,euser,ecomment)"
      "VALUES('w',%.17g,%d,%Q,%Q,"
      "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d AND tagtype>1),"

      "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d),"
      "  (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d));",
      m.rDate, rid, m.zUser, zComment, 
      TAG_BGCOLOR, rid,
      TAG_BGCOLOR, rid,
      TAG_USER, rid,
      TAG_COMMENT, rid
Changes to src/schema.c.
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
@ --
@ CREATE TABLE event(
@   type TEXT,                      -- Type of event
@   mtime DATETIME,                 -- Date and time when the event occurs
@   objid INTEGER PRIMARY KEY,      -- Associated record ID
@   uid INTEGER REFERENCES user,    -- User who caused the event
@   bgcolor TEXT,                   -- Color set by 'bgcolor' property
@   brbgcolor TEXT,                 -- Color set by 'br-bgcolor' property
@   euser TEXT,                     -- User set by 'user' property
@   user TEXT,                      -- Name of the user
@   ecomment TEXT,                  -- Comment set by 'comment' property
@   comment TEXT                    -- Comment describing the event
@ );
@ CREATE INDEX event_i1 ON event(mtime);
@







<







223
224
225
226
227
228
229

230
231
232
233
234
235
236
@ --
@ CREATE TABLE event(
@   type TEXT,                      -- Type of event
@   mtime DATETIME,                 -- Date and time when the event occurs
@   objid INTEGER PRIMARY KEY,      -- Associated record ID
@   uid INTEGER REFERENCES user,    -- User who caused the event
@   bgcolor TEXT,                   -- Color set by 'bgcolor' property

@   euser TEXT,                     -- User set by 'user' property
@   user TEXT,                      -- Name of the user
@   ecomment TEXT,                  -- Comment set by 'comment' property
@   comment TEXT                    -- Comment describing the event
@ );
@ CREATE INDEX event_i1 ON event(mtime);
@
326
327
328
329
330
331
332

333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
;

/*
** Predefined tagid values
*/
#if INTERFACE
# define TAG_BGCOLOR    1     /* Set the background color for display */

# define TAG_COMMENT    2     /* The check-in comment */
# define TAG_USER       3     /* User who made a checking */
# define TAG_HIDDEN     4     /* Do not display or sync */
# define TAG_PRIVATE    5     /* Display but do not sync */
# define TAG_CLUSTER    6     /* A cluster */
# define TAG_NEWBRANCH  7     /* First check-in of a new named branch */
# define TAG_CLOSED     8     /* Do not display this check-in as a leaf */
#endif
#if EXPORT_INTERFACE
# define MAX_INT_TAG    8     /* The largest pre-assigned tag id */
#endif

/*
** The schema for the locate FOSSIL database file found at the root
** of very check-out.  This database contains the complete state of
** the checkout.
*/







>
|
|
|
|
|
|
|


|







325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
;

/*
** Predefined tagid values
*/
#if INTERFACE
# define TAG_BGCOLOR    1     /* Set the background color for display */
# define TAG_BRBGCOLOR  2     /* Background color for branches */
# define TAG_COMMENT    3     /* The check-in comment */
# define TAG_USER       4     /* User who made a checking */
# define TAG_HIDDEN     5     /* Do not display or sync */
# define TAG_PRIVATE    6     /* Display but do not sync */
# define TAG_CLUSTER    7     /* A cluster */
# define TAG_NEWBRANCH  8     /* First check-in of a new named branch */
# define TAG_CLOSED     9     /* Do not display this check-in as a leaf */
#endif
#if EXPORT_INTERFACE
# define MAX_INT_TAG    9     /* The largest pre-assigned tag id */
#endif

/*
** The schema for the locate FOSSIL database file found at the root
** of very check-out.  This database contains the complete state of
** the checkout.
*/
Changes to src/tag.c.
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
    zValue = 0;
    db_prepare(&ins,
       "DELETE FROM tagxref WHERE tagid=%d AND rid=:rid", tagid
    );
  }
  if( tagid==TAG_BGCOLOR ){
    db_prepare(&eventupdate,
      "UPDATE event SET brbgcolor=%Q WHERE objid=:rid", zValue
    );
  }
  while( (pid = pqueue_extract(&queue))!=0 ){
    db_bind_int(&s, ":pid", pid);
    while( db_step(&s)==SQLITE_ROW ){
      int doit = db_column_int(&s, 2);
      if( doit ){







|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
    zValue = 0;
    db_prepare(&ins,
       "DELETE FROM tagxref WHERE tagid=%d AND rid=:rid", tagid
    );
  }
  if( tagid==TAG_BGCOLOR ){
    db_prepare(&eventupdate,
      "UPDATE event SET bgcolor=%Q WHERE objid=:rid", zValue
    );
  }
  while( (pid = pqueue_extract(&queue))!=0 ){
    db_bind_int(&s, ":pid", pid);
    while( db_step(&s)==SQLITE_ROW ){
      int doit = db_column_int(&s, 2);
      if( doit ){
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
  db_finalize(&s);
  if( tagtype==0 ){
    zValue = 0;
  }
  zCol = 0;
  switch( tagid ){
    case TAG_BGCOLOR: {
      if( tagtype==1 ){
        zCol = "bgcolor";
      }else{
        zCol = "brbgcolor";
      }
      break;
    }
    case TAG_COMMENT: {
      zCol = "ecomment";
      break;
    }
    case TAG_USER: {







<
|
<
<
<







182
183
184
185
186
187
188

189



190
191
192
193
194
195
196
  db_finalize(&s);
  if( tagtype==0 ){
    zValue = 0;
  }
  zCol = 0;
  switch( tagid ){
    case TAG_BGCOLOR: {

      zCol = "bgcolor";



      break;
    }
    case TAG_COMMENT: {
      zCol = "ecomment";
      break;
    }
    case TAG_USER: {
Changes to src/tagview.c.
166
167
168
169
170
171
172
173
174
175


176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
}

#undef TAGVIEW_DEFAULT_FILTER

/*
** Generate a timeline for the chosen tag
*/
void tagview_print_timeline(char const *pName, char const *pPrefix){
  char *zSql;
  Stmt q;


  zSql = mprintf("%s AND EXISTS (SELECT 1"
         " FROM tagxref"
         "  WHERE tagxref.rid = event.objid"
         "  AND tagxref.tagtype > 0"
         "  AND tagxref.tagid = (SELECT tagid FROM tag"
         "      WHERE tagname = %Q||%Q))"
         " ORDER BY 3 desc",
         timeline_query_for_www(), pPrefix, pName);

  db_prepare(&q, zSql);
  free(zSql);
  www_print_timeline(&q);
  db_finalize(&q);
}

/*







|


>
>




|
<

|
>







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190
191
192
}

#undef TAGVIEW_DEFAULT_FILTER

/*
** Generate a timeline for the chosen tag
*/
void tagview_print_timeline(char const *zName, char const *zPrefix){
  char *zSql;
  Stmt q;
  int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='%q%q'",
                        zPrefix, zName);
  zSql = mprintf("%s AND EXISTS (SELECT 1"
         " FROM tagxref"
         "  WHERE tagxref.rid = event.objid"
         "  AND tagxref.tagtype > 0"
         "  AND tagxref.tagid = %d"

         " ORDER BY 3 desc",
         timeline_query_for_www(), tagid
  );
  db_prepare(&q, zSql);
  free(zSql);
  www_print_timeline(&q);
  db_finalize(&q);
}

/*
Changes to src/timeline.c.
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
**    6.  Number of parents
**    7.  True if is a leaf
**    8.  background color
**    9.  type ("ci", "w")
**   10.  list of symbolic tags.
*/
void www_print_timeline(
  Stmt *pQuery
){
  int wikiFlags;
  int mxWikiLen;
  Blob comment;
  char zPrevDate[20];
  zPrevDate[0] = 0;








|







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
**    6.  Number of parents
**    7.  True if is a leaf
**    8.  background color
**    9.  type ("ci", "w")
**   10.  list of symbolic tags.
*/
void www_print_timeline(
  Stmt *pQuery          /* Query to implement the timeline */
){
  int wikiFlags;
  int mxWikiLen;
  Blob comment;
  char zPrevDate[20];
  zPrevDate[0] = 0;

233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
    @   uuid,
    @   datetime(event.mtime,'localtime') AS timestamp,
    @   coalesce(ecomment, comment),
    @   coalesce(euser, user),
    @   (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim=1),
    @   (SELECT count(*) FROM plink WHERE cid=blob.rid),
    @   NOT EXISTS (SELECT 1 FROM plink WHERE pid=blob.rid),
    @   coalesce(bgcolor, brbgcolor),
    @   event.type,
    @   (SELECT group_concat(substr(tagname,5), ', ') FROM tag, tagxref
    @     WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid
    @       AND tagxref.rid=blob.rid AND tagxref.tagtype>0)
    @  FROM event JOIN blob 
    @ WHERE blob.rid=event.objid
  ;







|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
    @   uuid,
    @   datetime(event.mtime,'localtime') AS timestamp,
    @   coalesce(ecomment, comment),
    @   coalesce(euser, user),
    @   (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim=1),
    @   (SELECT count(*) FROM plink WHERE cid=blob.rid),
    @   NOT EXISTS (SELECT 1 FROM plink WHERE pid=blob.rid),
    @   bgcolor,
    @   event.type,
    @   (SELECT group_concat(substr(tagname,5), ', ') FROM tag, tagxref
    @     WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid
    @       AND tagxref.rid=blob.rid AND tagxref.tagtype>0)
    @  FROM event JOIN blob 
    @ WHERE blob.rid=event.objid
  ;