Fossil

Check-in [f486d0f0]
Login

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

Overview
Comment:add TECHNOTEID to fossil wiki export. Rename --show-artifact-ids to --show-technote-ids on fossil wiki list (and ignore option for wiki pages as the page name uniquely identifies wiki page name). Rename done as tech note ids are not artifact ids (e.g. they cannot be used on fossil artifact)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | technoteattachcli
Files: files | file ages | folders
SHA1:f486d0f0694b0549788e0bf58d7c33dd7ef271d5
User & Date: dave.vines 2016-04-12 19:14:14
Context
2016-04-18
08:17
add TECHNOTEID to fossil wiki commit and allow creation of multiple tech notes with the same timestamp (as already permitted by the GUI). check-in: aeaef8fb user: dave.vines tags: technoteattachcli
2016-04-12
19:14
add TECHNOTEID to fossil wiki export. Rename --show-artifact-ids to --show-technote-ids on fossil wiki list (and ignore option for wiki pages as the page name uniquely identifies wiki page name). Rename done as tech note ids are not artifact ids (e.g. they cannot be used on fossil artifact) check-in: f486d0f0 user: dave.vines tags: technoteattachcli
2016-04-04
17:30
Add a --show-artifact-ids to the 'fossil wiki list' command. Note this commit does not add the ability to select what to update on the 'fossil wiki commit' command, that is to come in a later commit. check-in: cbda43e7 user: dave.vines tags: technoteattachcli
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/wiki.c.

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
....
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185

1186
1187
1188
1189
1190
1191
1192
....
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235

1236
1237
1238
1239
1240
1241
1242
....
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344

1345
1346
1347
1348
1349
1350
1351
1352
1353
  blob_appendf(&wiki, "Z %b\n", &cksum);
  blob_reset(&cksum);
  db_begin_transaction();
  wiki_put(&wiki, 0, wiki_need_moderation(localUser));
  db_end_transaction(0);
  return 1;
}








































/*
** COMMAND: wiki*
**
** Usage: %fossil wiki (export|create|commit|list) WikiName
**
** Run various subcommands to work with wiki entries or tech notes.
**
**    %fossil wiki export ?PAGENAME? ?FILE? [-t|--technote DATETIME ]

**
**       Sends the latest version of either the PAGENAME wiki entry
**       or the DATETIME tech note to the given file or standard 
**       output. One of PAGENAME or DATETIME must be specified.




**
**    %fossil wiki (create|commit) PAGENAME ?FILE? ?OPTIONS?
**              
**       Create a new or commit changes to an existing wiki page or 
**       technote from FILE or from standard input. PAGENAME is the
**       name of the wiki entry or the timeline comment of the
**       technote.
................................................................................
**       case-insensitively by name. 
**
**       Options:
**         --technote                  Technotes will be listed instead of
**                                     pages. The technotes will be in order
**                                     of timestamp with the most recent
**                                     first.
**         --show-artifact-ids         The artifact id of the wiki page or 
**                                     tech note will be listed along side the
**                                     page name or timestamp. The artifact id
**                                     will be the first word on each line.

**
*/
void wiki_cmd(void){
  int n;
  db_find_and_open_repository(0, 0);
  if( g.argc<3 ){
    goto wiki_cmd_usage;
................................................................................
      }
      if( zBody==0 ){
        fossil_fatal("wiki page [%s] not found",zPageName);
      }
      zFile = (g.argc==4) ? "-" : g.argv[4];
    }else{
      if( (g.argc!=3) && (g.argc!=4) ){
        usage("export ?FILE? --technote DATETIME");
      }
      rid = db_int(0, "SELECT objid FROM event"
        " WHERE datetime(mtime)=datetime('%q') AND type='e'"
        " ORDER BY mtime DESC LIMIT 1",
        zETime
      );

      if( (pWiki = manifest_get(rid, CFTYPE_EVENT, 0))!=0 ){
        zBody = pWiki->zWiki;
      }
      if( zBody==0 ){
        fossil_fatal("technote [%s] not found",zETime);
      }
      zFile = (g.argc==3) ? "-" : g.argv[3];
................................................................................
    if( g.argc!=5 ){
      usage("delete PAGENAME");
    }
    fossil_fatal("delete not yet implemented.");
  }else if(( strncmp(g.argv[2],"list",n)==0 )
          || ( strncmp(g.argv[2],"ls",n)==0 )){
    Stmt q;
    int showIds = find_option("show-artifact-ids","s",0)!=0;

    if ( !find_option("technote","t",0) ){
      db_prepare(&q,
        "SELECT substr(t.tagname, 6), b.uuid" 
         " FROM tag t, tagxref x, blob b"
        " WHERE tagname GLOB 'wiki-*'"
          " AND t.tagid=x.tagid AND b.rid=x.rid"
          " AND x.mtime=(SELECT MAX(xx.mtime)"
                         " FROM tagxref xx"
                        " WHERE xx.tagid=x.tagid)"
        " ORDER BY lower(tagname) /*sort*/"
      );
    }else{

      db_prepare(&q,
        "SELECT datetime(e.mtime), substr(t.tagname,7) "
         " FROM event e, tag t"
        " WHERE e.type='e'"
          " AND e.tagid IS NOT NULL"
          " AND t.tagid=e.tagid"
        " ORDER BY e.mtime DESC /*sort*/"
      );
    }







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








|
>

|
|
<
>
>
>
>







 







|
|
|
|
>







 







|

|
|
|
<
<
>







 







|



<
<
|
<
<
<
<



>

|







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
....
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
....
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277


1278
1279
1280
1281
1282
1283
1284
1285
....
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377


1378




1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
  blob_appendf(&wiki, "Z %b\n", &cksum);
  blob_reset(&cksum);
  db_begin_transaction();
  wiki_put(&wiki, 0, wiki_need_moderation(localUser));
  db_end_transaction(0);
  return 1;
}

/*
** Determine the rid for a tech note given either its id or its
** timestamp. Returns 0 if there is no such item and-1 if the details 
** are ambiguous and could refer to multiple items
*/
int wiki_technote_to_rid(const char *zETime) {
  int rid=0;                    /* Artifact ID of the tech note */
  int nETime = strlen(zETime);
  Stmt q;
  if( nETime>=4 && nETime<=UUID_SIZE && validate16(zETime, nETime) ){
    char zUuid[UUID_SIZE+1];
    memcpy(zUuid, zETime, nETime+1);
    canonical16(zUuid, nETime);
    db_prepare(&q,
      "SELECT e.objid"
      "  FROM event e, tag t"
      " WHERE e.type='e' AND e.tagid IS NOT NULL AND t.tagid=e.tagid"
      "   AND t.tagname GLOB 'event-%q*'",
      zUuid
    );
    if( db_step(&q)==SQLITE_ROW ){
      rid = db_column_int(&q, 0);
      if( db_step(&q)==SQLITE_ROW ) rid = -1;
    }
    db_finalize(&q);
  }
  if (!rid) {
    if (strlen(zETime)>4) {
      rid = db_int(0, "SELECT objid"
                      " FROM event"
                      " WHERE datetime(mtime)=datetime('%q')"
                      " AND type='e'"
                      " ORDER BY mtime DESC LIMIT 1",
                   zETime);
    }
  }
  return rid;
}

/*
** COMMAND: wiki*
**
** Usage: %fossil wiki (export|create|commit|list) WikiName
**
** Run various subcommands to work with wiki entries or tech notes.
**
**    %fossil wiki export PAGENAME ?FILE?
**    %fossil wiki export ?FILE? -t|--technote DATETIME|TECHNOTE-ID 
**
**       Sends the latest version of either a wiki page or of a tech note
**       to the given file or standard output. 

**       If PAGENAME is provided, the wiki page will be output. For
**       a tech note either DATETIME or TECHNOTE-ID must be specified. If 
**       DATETIME is used, the most recently modified tech note with that
**       DATETIME will be sent.
**
**    %fossil wiki (create|commit) PAGENAME ?FILE? ?OPTIONS?
**              
**       Create a new or commit changes to an existing wiki page or 
**       technote from FILE or from standard input. PAGENAME is the
**       name of the wiki entry or the timeline comment of the
**       technote.
................................................................................
**       case-insensitively by name. 
**
**       Options:
**         --technote                  Technotes will be listed instead of
**                                     pages. The technotes will be in order
**                                     of timestamp with the most recent
**                                     first.
**         --show-technote-ids         The id of the tech note will be listed
**                                     along side the timestamp. The tech note
**                                     id will be the first word on each line.
**                                     This option only applies if the
**                                     --technote option is also specified.
**
*/
void wiki_cmd(void){
  int n;
  db_find_and_open_repository(0, 0);
  if( g.argc<3 ){
    goto wiki_cmd_usage;
................................................................................
      }
      if( zBody==0 ){
        fossil_fatal("wiki page [%s] not found",zPageName);
      }
      zFile = (g.argc==4) ? "-" : g.argv[4];
    }else{
      if( (g.argc!=3) && (g.argc!=4) ){
        usage("export ?FILE? --technote DATETIME|TECHNOTE-ID");
      }
      rid = wiki_technote_to_rid(zETime);
      if (rid == -1) {
        fossil_fatal("ambiguous tech note id: %s", zETime);


      }
      if( (pWiki = manifest_get(rid, CFTYPE_EVENT, 0))!=0 ){
        zBody = pWiki->zWiki;
      }
      if( zBody==0 ){
        fossil_fatal("technote [%s] not found",zETime);
      }
      zFile = (g.argc==3) ? "-" : g.argv[3];
................................................................................
    if( g.argc!=5 ){
      usage("delete PAGENAME");
    }
    fossil_fatal("delete not yet implemented.");
  }else if(( strncmp(g.argv[2],"list",n)==0 )
          || ( strncmp(g.argv[2],"ls",n)==0 )){
    Stmt q;
    int showIds = 0;

    if ( !find_option("technote","t",0) ){
      db_prepare(&q,


        "SELECT substr(tagname, 6) FROM tag WHERE tagname GLOB 'wiki-*'"




        " ORDER BY lower(tagname) /*sort*/"
      );
    }else{
      showIds = find_option("show-technote-ids","s",0)!=0;
      db_prepare(&q,
        "SELECT datetime(e.mtime), substr(t.tagname,7)"
         " FROM event e, tag t"
        " WHERE e.type='e'"
          " AND e.tagid IS NOT NULL"
          " AND t.tagid=e.tagid"
        " ORDER BY e.mtime DESC /*sort*/"
      );
    }

Changes to test/wiki.test.

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241
242


243















244
245
246
247




248
249
250

251
252
253
















254





255
256
# extra ones from other events (such as the attachments) - 7 tech notes 
# expected created by tests 9, 17, 19, 29, 31, 32 and 34 
fossil wiki list --technote
set technotelist [split $RESULT "\n"] 
test wiki-37 {[llength $technotelist] == 7}

###############################################################################
# Check that using the show-artifact-ids shows the same tech notes in the same
# order (with the artifact id as the first word of the line
fossil wiki list --technote --show-artifact-ids
set technoteartifactlist [split $RESULT "\n"]
test wiki-38 {[llength $technoteartifactlist] == 7}
for {set i 0} {$i < [llength $technotelist]} {incr i} {
  set match "*"
  append match [lindex $technotelist $i]
  test "wiki-39-$i" {[string match $match [lindex $technoteartifactlist $i]]} 
}

###############################################################################
# Similarly check that wiki pages can have their artifact ids displayed
# Note: the tests above have only created a single wiki page, hence the list
# should be of length 1 at this point (created by test 1)

fossil wiki list
set wikilist [split $RESULT "\n"]


test wiki-40 {[llength $wikilist] == 1}















fossil wiki list --show-artifact-ids
set wikiartifactlist [split $RESULT "\n"]
test wiki-41 {[llength $wikilist] == [llength $wikiartifactlist]}
for {set i 0} {$i < [llength $wikilist]} {incr i} {




  set match "*"
  append match [lindex $wikilist $i]
  test "wiki-42-$i" {[string match $match [lindex $wikiartifactlist $i]]}

}

###############################################################################






















test_cleanup








|
|
|
|
|

|

|



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


219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269


270
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
# extra ones from other events (such as the attachments) - 7 tech notes 
# expected created by tests 9, 17, 19, 29, 31, 32 and 34 
fossil wiki list --technote
set technotelist [split $RESULT "\n"] 
test wiki-37 {[llength $technotelist] == 7}

###############################################################################
# Check that using the show-technote-ids shows the same tech notes in the same
# order (with the technote id as the first word of the line
fossil wiki list --technote --show-technote-ids
set technoteidlist [split $RESULT "\n"]
test wiki-38 {[llength $technotelist] == 7}
for {set i 0} {$i < [llength $technotelist]} {incr i} {
  set match "???????????????????????????????????????? "
  append match [lindex $technotelist $i]
  test "wiki-39-$i" {[string match $match [lindex $technoteidlist $i]]}
}

###############################################################################
# Create new tech note with a old timestamp so that it is oldest and then check that
# the contents of the oldest tech note (by tech note id, both full and short) match up
write_file f12 "A really old tech note"
fossil wiki create {Old tech note} f12 --technote {2001-07-07 09:08:07}
fossil wiki list --technote --show-technote-ids
set technotelist [split $RESULT "\n"]
set oldesttechnoteid [lindex [split [lindex $technotelist [llength $technotelist]-1]] 0]
fossil wiki export a12 --technote $oldesttechnoteid
test wiki-40 {[similar_file f12 a12]}

###############################################################################
# Also check that we can specify a prefix of the tech note id (note: with
# 8 items in the tech note at this point there is a chance of a collision.
# However with the chance of the collision being 1 in approx 10^22 if I use a 20
# character prefix I'll ignore that possibility for this test.
fossil wiki export a12.1 --technote [string range $oldesttechnoteid 0 20]
test wiki-41 {[similar_file f12 a12.1]}

###############################################################################
# Now we need to force a collision in the first four characters of the tech
# note id if we don't already have one so we can check we get an error if the
# tech note id is ambiguous
set idcounts [dict create]
set maxcount 0
fossil wiki list --technote --show-technote-ids
set technotelist [split $RESULT "\n"]

for {set i 0} {$i < [llength $technotelist]} {incr i} {
  set fullid [lindex $technotelist $i]
  set id [string range $fullid 0 3]
  dict incr idcounts $id
  if {[dict get $idcounts $id] > $maxcount} {
    set maxid $id


    incr maxcount 
  }
}

# get i so that, as a julian date, it is in the 1800s, i.e., older than
# any other tech note, but after 1 AD
set i 2400000
while {$maxcount < 2} {
  # keep getting older
  incr i -1
  write_file collision "A tech note with timestamp of jday=$i"
  fossil wiki create "timestamp of $i" collision --technote "$i"
  fossil wiki list --technote --show-technote-ids
  set technotelist [split $RESULT "\n"]
  set oldesttechnoteid [lindex [split [lindex $technotelist [llength $technotelist]-1]] 0]
  set id [string range $oldesttechnoteid 0 3]
  dict incr idcounts $id
  if {[dict get $idcounts $id] > $maxcount} {
    set maxid $id
    incr maxcount 
  }
}
fossil wiki export a13 --technote $maxid -expectError
test wiki-42 {$CODE != 0}

###############################################################################
test_cleanup