Changes On Branch count-nochange
Not logged in

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

Changes In Branch count-nochange Excluding Merge-Ins

This is equivalent to a diff from 91aa222d7f to e72af5058e

2013-04-21
21:59
Add -n|--dry-run options to commands which already have --test or --nochange. check-in: 0b866397a8 user: jan.nijtmans tags: trunk
08:08
Merge with trunk - Remove reverse-proxying support which is already provided by --baseurl option. check-in: 940b0b33c9 user: ashish tags: ashish-ipv6
2013-04-19
07:55
Rename "--limit" to "--count" and "--test" to "--nochange" in some fossil commands Closed-Leaf check-in: e72af5058e user: jan.nijtmans tags: count-nochange
2013-04-18
18:53
Record cherrypicks and backouts in the Q card of the check-in manifest. This is the first step in adding display of cherry-picks, ticket [eaf1c4fdbeeca8eb]. check-in: 91aa222d7f user: drh tags: trunk
08:46
Use the function filename_collation() everywhere in stead of passing caseSensitive as parameter. check-in: 3c781f4f0b user: jan.nijtmans tags: trunk

Changes to src/add.c.

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
** This command can be used to track third party software.
** 
** Options: 
**   --case-sensitive <BOOL> override case-sensitive setting
**   --dotfiles              include files beginning with a dot (".")   
**   --ignore <CSG>          ignore files matching patterns from the 
**                           comma separated list of glob patterns.
**   --test                  If given, display instead of run actions
**
** See also: add, rm
*/
void addremove_cmd(void){
  Blob path;
  const char *zIgnoreFlag = find_option("ignore",0,1);
  unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
  int isTest = find_option("test",0,0)!=0;
  int n;
  Stmt q;
  int vid;
  int nAdd = 0;
  int nDelete = 0;
  Glob *pIgnore;





  capture_case_sensitive_option();
  db_must_be_within_tree();
  if( zIgnoreFlag==0 ){
    zIgnoreFlag = db_get("ignore-glob", 0);
  }
  vid = db_lget_int("checkout",0);
  if( vid==0 ){







|







|







>
>
>
>







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
** This command can be used to track third party software.
** 
** Options: 
**   --case-sensitive <BOOL> override case-sensitive setting
**   --dotfiles              include files beginning with a dot (".")   
**   --ignore <CSG>          ignore files matching patterns from the 
**                           comma separated list of glob patterns.
**   --nochange|-n           If given, display instead of run actions
**
** See also: add, rm
*/
void addremove_cmd(void){
  Blob path;
  const char *zIgnoreFlag = find_option("ignore",0,1);
  unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
  int nochangeFlag = find_option("nochange","n",0)!=0;
  int n;
  Stmt q;
  int vid;
  int nAdd = 0;
  int nDelete = 0;
  Glob *pIgnore;

  if( !nochangeFlag ){
    /* --test is deprecated */
    nochangeFlag = find_option("test",0,0)!=0;
  }
  capture_case_sensitive_option();
  db_must_be_within_tree();
  if( zIgnoreFlag==0 ){
    zIgnoreFlag = db_get("ignore-glob", 0);
  }
  vid = db_lget_int("checkout",0);
  if( vid==0 ){
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
  while( db_step(&q)==SQLITE_ROW ){
    const char * zFile;
    const char * zPath;

    zFile = db_column_text(&q, 0);
    zPath = db_column_text(&q, 1);
    if( !file_wd_isfile_or_link(zPath) ){
      if( !isTest ){
        db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zFile);
      }
      fossil_print("DELETED  %s\n", zFile);
      nDelete++;
    }
  }
  db_finalize(&q);
  /* show command summary */
  fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);

  db_end_transaction(isTest);
}


/*
** Rename a single file.
**
** The original name of the file is zOrig.  The new filename is zNew.







|










|







514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
  while( db_step(&q)==SQLITE_ROW ){
    const char * zFile;
    const char * zPath;

    zFile = db_column_text(&q, 0);
    zPath = db_column_text(&q, 1);
    if( !file_wd_isfile_or_link(zPath) ){
      if( !nochangeFlag ){
        db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zFile);
      }
      fossil_print("DELETED  %s\n", zFile);
      nDelete++;
    }
  }
  db_finalize(&q);
  /* show command summary */
  fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);

  db_end_transaction(nochangeFlag);
}


/*
** Rename a single file.
**
** The original name of the file is zOrig.  The new filename is zNew.

Changes to src/allrepo.c.

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  const char *zCmd;
  char *zSyscmd;
  char *zFossil;
  char *zQFilename;
  Blob extra;
  int useCheckouts = 0;
  int quiet = 0;
  int testRun = 0;
  int stopOnError = find_option("dontstop",0,0)==0;
  int rc;
  Bag outOfDate;
  
  /* The undocumented --test option causes no changes to occur to any
  ** repository, but instead show what would have happened.  Intended for
  ** test and debugging use.
  */
  testRun = find_option("test",0,0)!=0;

  if( g.argc<3 ){
    usage("changes|list|ls|pull|push|rebuild|sync");
  }
  n = strlen(g.argv[2]);
  db_open_config(1);
  blob_zero(&extra);







|




|



|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  const char *zCmd;
  char *zSyscmd;
  char *zFossil;
  char *zQFilename;
  Blob extra;
  int useCheckouts = 0;
  int quiet = 0;
  int nochangeFlag = 0;
  int stopOnError = find_option("dontstop",0,0)==0;
  int rc;
  Bag outOfDate;
  
  /* The undocumented --nochange option causes no changes to occur to any
  ** repository, but instead show what would have happened.  Intended for
  ** test and debugging use.
  */
  nochangeFlag = find_option("nochange","n",0)!=0;

  if( g.argc<3 ){
    usage("changes|list|ls|pull|push|rebuild|sync");
  }
  n = strlen(g.argv[2]);
  db_open_config(1);
  blob_zero(&extra);
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
  }else if( strncmp(zCmd, "ignore", n)==0 ){
    int j;
    verify_all_options();
    db_begin_transaction();
    for(j=3; j<g.argc; j++){
      char *zSql = mprintf("DELETE FROM global_config"
                           " WHERE name GLOB 'repo:%q'", g.argv[j]);
      if( testRun ){
        fossil_print("%s\n", zSql);
      }else{
        db_multi_exec("%s", zSql);
      }
      fossil_free(zSql);
    }
    db_end_transaction(0);







|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
  }else if( strncmp(zCmd, "ignore", n)==0 ){
    int j;
    verify_all_options();
    db_begin_transaction();
    for(j=3; j<g.argc; j++){
      char *zSql = mprintf("DELETE FROM global_config"
                           " WHERE name GLOB 'repo:%q'", g.argv[j]);
      if( nochangeFlag ){
        fossil_print("%s\n", zSql);
      }else{
        db_multi_exec("%s", zSql);
      }
      fossil_free(zSql);
    }
    db_end_transaction(0);
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
    if( zCmd[0]=='l' ){
      fossil_print("%s\n", zFilename);
      continue;
    }
    zQFilename = quoteFilename(zFilename);
    zSyscmd = mprintf("%s %s %s%s",
                      zFossil, zCmd, zQFilename, blob_str(&extra));
    if( !quiet || testRun ){
      fossil_print("%s\n", zSyscmd);
      fflush(stdout);
    }
    rc = testRun ? 0 : fossil_system(zSyscmd);
    free(zSyscmd);
    free(zQFilename);
    if( stopOnError && rc ){
      break;
    }
  }
  db_finalize(&q);







|



|







216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
    if( zCmd[0]=='l' ){
      fossil_print("%s\n", zFilename);
      continue;
    }
    zQFilename = quoteFilename(zFilename);
    zSyscmd = mprintf("%s %s %s%s",
                      zFossil, zCmd, zQFilename, blob_str(&extra));
    if( !quiet || nochangeFlag ){
      fossil_print("%s\n", zSyscmd);
      fflush(stdout);
    }
    rc = nochangeFlag ? 0 : fossil_system(zSyscmd);
    free(zSyscmd);
    free(zQFilename);
    if( stopOnError && rc ){
      break;
    }
  }
  db_finalize(&q);
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
    blob_zero(&sql);
    blob_appendf(&sql, "DELETE FROM global_config WHERE rowid IN ");
    for(rowid=bag_first(&outOfDate); rowid>0; rowid=bag_next(&outOfDate,rowid)){
      blob_appendf(&sql, "%s%d", zSep, rowid);
      zSep = ",";
    }
    blob_appendf(&sql, ")");
    if( testRun ){
      fossil_print("%s\n", blob_str(&sql));
    }else{
      db_multi_exec(blob_str(&sql));
    }
    blob_reset(&sql);
  }
}







|







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
    blob_zero(&sql);
    blob_appendf(&sql, "DELETE FROM global_config WHERE rowid IN ");
    for(rowid=bag_first(&outOfDate); rowid>0; rowid=bag_next(&outOfDate,rowid)){
      blob_appendf(&sql, "%s%d", zSep, rowid);
      zSep = ",";
    }
    blob_appendf(&sql, ")");
    if( nochangeFlag ){
      fossil_print("%s\n", blob_str(&sql));
    }else{
      db_multi_exec(blob_str(&sql));
    }
    blob_reset(&sql);
  }
}

Changes to src/checkin.c.

408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
  int allFlag;
  unsigned scanFlags = 0;
  const char *zIgnoreFlag;
  Blob path, repo;
  Stmt q;
  int n;
  Glob *pIgnore;
  int testFlag = 0;

  allFlag = find_option("force","f",0)!=0;
  if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL;
  if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
  zIgnoreFlag = find_option("ignore",0,1);
  testFlag = find_option("test",0,0)!=0;
  capture_case_sensitive_option();
  db_must_be_within_tree();
  if( zIgnoreFlag==0 ){
    zIgnoreFlag = db_get("ignore-glob", 0);
  }
  db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
                filename_collation());







|





|







408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
  int allFlag;
  unsigned scanFlags = 0;
  const char *zIgnoreFlag;
  Blob path, repo;
  Stmt q;
  int n;
  Glob *pIgnore;
  int nochangeFlag = 0;

  allFlag = find_option("force","f",0)!=0;
  if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL;
  if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
  zIgnoreFlag = find_option("ignore",0,1);
  nochangeFlag = find_option("nochange","n",0)!=0;
  capture_case_sensitive_option();
  db_must_be_within_tree();
  if( zIgnoreFlag==0 ){
    zIgnoreFlag = db_get("ignore-glob", 0);
  }
  db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
                filename_collation());
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
      g.zLocalRoot, fossil_all_reserved_names(0)
  );
  if( file_tree_name(g.zRepositoryName, &repo, 0) ){
    db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
  }
  db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
  while( db_step(&q)==SQLITE_ROW ){
    if( testFlag ){
      fossil_print("%s\n", db_column_text(&q,0));
      continue;
    }else if( !allFlag ){
      Blob ans;
      char cReply;
      char *prompt = mprintf("remove unmanaged file \"%s\" (a=all/y/N)? ",
                              db_column_text(&q, 0));







|







438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
      g.zLocalRoot, fossil_all_reserved_names(0)
  );
  if( file_tree_name(g.zRepositoryName, &repo, 0) ){
    db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
  }
  db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
  while( db_step(&q)==SQLITE_ROW ){
    if( nochangeFlag ){
      fossil_print("%s\n", db_column_text(&q,0));
      continue;
    }else if( !allFlag ){
      Blob ans;
      char cReply;
      char *prompt = mprintf("remove unmanaged file \"%s\" (a=all/y/N)? ",
                              db_column_text(&q, 0));
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
  int allowConflict = 0; /* Allow unresolve merge conflicts */
  int allowEmpty = 0;    /* Allow a commit with no changes */
  int allowFork = 0;     /* Allow the commit to fork */
  int allowOlder = 0;    /* Allow a commit older than its ancestor */
  char *zManifestFile;   /* Name of the manifest file */
  int useCksum;          /* True if checksums should be computed and verified */
  int outputManifest;    /* True to output "manifest" and "manifest.uuid" */
  int testRun;           /* True for a test run.  Debugging only */
  CheckinInfo sCiInfo;   /* Information about this check-in */
  const char *zComFile;  /* Read commit message from this file */
  int nTag = 0;          /* Number of --tag arguments */
  const char *zTag;      /* A single --tag argument */
  Blob manifest;         /* Manifest in baseline form */
  Blob muuid;            /* Manifest uuid */
  Blob cksum1, cksum2;   /* Before and after commit checksums */







|







1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
  int allowConflict = 0; /* Allow unresolve merge conflicts */
  int allowEmpty = 0;    /* Allow a commit with no changes */
  int allowFork = 0;     /* Allow the commit to fork */
  int allowOlder = 0;    /* Allow a commit older than its ancestor */
  char *zManifestFile;   /* Name of the manifest file */
  int useCksum;          /* True if checksums should be computed and verified */
  int outputManifest;    /* True to output "manifest" and "manifest.uuid" */
  int nochangeFlag;      /* True for a test run.  Debugging only */
  CheckinInfo sCiInfo;   /* Information about this check-in */
  const char *zComFile;  /* Read commit message from this file */
  int nTag = 0;          /* Number of --tag arguments */
  const char *zTag;      /* A single --tag argument */
  Blob manifest;         /* Manifest in baseline form */
  Blob muuid;            /* Manifest uuid */
  Blob cksum1, cksum2;   /* Before and after commit checksums */
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
  url_proxy_options();
  noSign = find_option("nosign",0,0)!=0;
  forceDelta = find_option("delta",0,0)!=0;
  forceBaseline = find_option("baseline",0,0)!=0;
  if( forceDelta && forceBaseline ){
    fossil_fatal("cannot use --delta and --baseline together");
  }
  testRun = find_option("test",0,0)!=0;
  zComment = find_option("comment","m",1);
  forceFlag = find_option("force", "f", 0)!=0;
  allowConflict = find_option("allow-conflict",0,0)!=0;
  allowEmpty = find_option("allow-empty",0,0)!=0;
  allowFork = find_option("allow-fork",0,0)!=0;
  allowOlder = find_option("allow-older",0,0)!=0;
  noWarningFlag = find_option("no-warnings", 0, 0)!=0;







|







1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
  url_proxy_options();
  noSign = find_option("nosign",0,0)!=0;
  forceDelta = find_option("delta",0,0)!=0;
  forceBaseline = find_option("baseline",0,0)!=0;
  if( forceDelta && forceBaseline ){
    fossil_fatal("cannot use --delta and --baseline together");
  }
  nochangeFlag = find_option("nochange","n",0)!=0;
  zComment = find_option("comment","m",1);
  forceFlag = find_option("force", "f", 0)!=0;
  allowConflict = find_option("allow-conflict",0,0)!=0;
  allowEmpty = find_option("allow-empty",0,0)!=0;
  allowFork = find_option("allow-fork",0,0)!=0;
  allowOlder = find_option("allow-older",0,0)!=0;
  noWarningFlag = find_option("no-warnings", 0, 0)!=0;
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
      fossil_exit(1);
    }
  }

  /* If the --test option is specified, output the manifest file
  ** and rollback the transaction.
  */
  if( testRun ){
    blob_write_to_file(&manifest, "");
  }

  if( outputManifest ){
    zManifestFile = mprintf("%smanifest", g.zLocalRoot);
    blob_write_to_file(&manifest, zManifestFile);
    blob_reset(&manifest);







|







1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
      fossil_exit(1);
    }
  }

  /* If the --test option is specified, output the manifest file
  ** and rollback the transaction.
  */
  if( nochangeFlag ){
    blob_write_to_file(&manifest, "");
  }

  if( outputManifest ){
    zManifestFile = mprintf("%smanifest", g.zLocalRoot);
    blob_write_to_file(&manifest, zManifestFile);
    blob_reset(&manifest);
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
  }

  /* Clear the undo/redo stack */
  undo_reset();

  /* Commit */
  db_multi_exec("DELETE FROM vvar WHERE name='ci-comment'");
  if( testRun ){
    db_end_transaction(1);
    exit(1);
  }
  db_end_transaction(0);

  if( !g.markPrivate ){
    autosync(SYNC_PUSH|SYNC_PULL);
  }
  if( count_nonbranch_children(vid)>1 ){
    fossil_print("**** warning: a fork has occurred *****\n");
  }
}







|












1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
  }

  /* Clear the undo/redo stack */
  undo_reset();

  /* Commit */
  db_multi_exec("DELETE FROM vvar WHERE name='ci-comment'");
  if( nochangeFlag ){
    db_end_transaction(1);
    exit(1);
  }
  db_end_transaction(0);

  if( !g.markPrivate ){
    autosync(SYNC_PUSH|SYNC_PULL);
  }
  if( count_nonbranch_children(vid)>1 ){
    fossil_print("**** warning: a fork has occurred *****\n");
  }
}

Changes to src/diff.c.

2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427

  showLn = P("ln")!=0;
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  mid = name_to_typed_rid(PD("checkin","0"),"ci");
  fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename"));
  if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
  iLimit = atoi(PD("limit","-1"));
  if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
    fossil_redirect_home();
  }
  compute_direct_ancestors(mid, 10000000);
  style_header("File Annotation");
  if( P("filevers") ) annFlags |= ANN_FILE_VERS;
  annotate_file(&ann, fnid, mid, g.perm.Hyperlink, iLimit, annFlags);







|







2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427

  showLn = P("ln")!=0;
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  mid = name_to_typed_rid(PD("checkin","0"),"ci");
  fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename"));
  if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
  iLimit = atoi(PD("count","-1"));
  if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
    fossil_redirect_home();
  }
  compute_direct_ancestors(mid, 10000000);
  style_header("File Annotation");
  if( P("filevers") ) annFlags |= ANN_FILE_VERS;
  annotate_file(&ann, fnid, mid, g.perm.Hyperlink, iLimit, annFlags);
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484



2485

2486
2487
2488
2489
2490
2491
2492
**
** %fossil annotate ?OPTIONS? FILENAME
**
** Output the text of a file with markings to show when each line of
** the file was last modified.
**
** Options:
**   --limit N       Only look backwards in time by N versions
**   --log           List all versions analyzed
**   --filevers      Show file version numbers rather than check-in versions
**
** See also: info, finfo, timeline
*/
void annotate_cmd(void){
  int fnid;         /* Filename ID */
  int fid;          /* File instance ID */
  int mid;          /* Manifest where file was checked in */
  int cid;          /* Checkout ID */
  Blob treename;    /* FILENAME translated to canonical form */
  char *zFilename;  /* Canonical filename */
  Annotator ann;    /* The annotation of the file */
  int i;            /* Loop counter */
  const char *zLimit; /* The value to the --limit option */
  int iLimit;       /* How far back in time to look */
  int showLog;      /* True to show the log */
  int fileVers;     /* Show file version instead of check-in versions */
  int annFlags = 0; /* Flags to control annotation properties */




  zLimit = find_option("limit",0,1);

  if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
  iLimit = atoi(zLimit);
  showLog = find_option("log",0,0)!=0;
  fileVers = find_option("filevers",0,0)!=0;
  db_must_be_within_tree();
  if( g.argc<3 ) {
    usage("FILENAME");







|














|





>
>
>
|
>







2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
**
** %fossil annotate ?OPTIONS? FILENAME
**
** Output the text of a file with markings to show when each line of
** the file was last modified.
**
** Options:
**   --count|-n N    Only look backwards in time by N versions
**   --log           List all versions analyzed
**   --filevers      Show file version numbers rather than check-in versions
**
** See also: info, finfo, timeline
*/
void annotate_cmd(void){
  int fnid;         /* Filename ID */
  int fid;          /* File instance ID */
  int mid;          /* Manifest where file was checked in */
  int cid;          /* Checkout ID */
  Blob treename;    /* FILENAME translated to canonical form */
  char *zFilename;  /* Canonical filename */
  Annotator ann;    /* The annotation of the file */
  int i;            /* Loop counter */
  const char *zLimit; /* The value to the --count option */
  int iLimit;       /* How far back in time to look */
  int showLog;      /* True to show the log */
  int fileVers;     /* Show file version instead of check-in versions */
  int annFlags = 0; /* Flags to control annotation properties */

  zLimit = find_option("count","n",1);
  if(!zLimit){
    /* deprecated */
    zLimit = find_option("limit",0,1);
  }
  if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
  iLimit = atoi(zLimit);
  showLog = find_option("log",0,0)!=0;
  fileVers = find_option("filevers",0,0)!=0;
  db_must_be_within_tree();
  if( g.argc<3 ) {
    usage("FILENAME");

Changes to src/finfo.c.

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
**
** Usage: %fossil finfo ?OPTIONS? FILENAME
**
** Print the complete change history for a single file going backwards
** in time.  The default mode is -l.
**
** For the -l|--log mode: If "-b|--brief" is specified one line per revision
** is printed, otherwise the full comment is printed.  The "--limit N"
** and "--offset P" options limits the output to the first N changes
** after skipping P changes.
**
** In the -s mode prints the status as <status> <revision>.  This is
** a quick status and does not check for up-to-date-ness of the file.
**
** In the -p mode, there's an optional flag "-r|--revision REVISION".
** The specified version (or the latest checked out version) is printed
** to stdout.  The -p mode is another form of the "cat" command.
**
** Options:
**   --brief|-b           display a brief (one line / revision) summary
**   --case-sensitive B   Enable or disable case-sensitive filenames.  B is a
**                        boolean: "yes", "no", "true", "false", etc.
**   --limit N            display the first N changes
**   --log|-l             select log mode (the default)
**   --offset P           skip P changes
**   --print|-p           select print mode
**   --revision|-r R      print the given revision (or ckout, if none is given)
**                        to stdout (only in print mode)
**   --status|-s          select status mode (print a status indicator for FILE)
**







|














|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
**
** Usage: %fossil finfo ?OPTIONS? FILENAME
**
** Print the complete change history for a single file going backwards
** in time.  The default mode is -l.
**
** For the -l|--log mode: If "-b|--brief" is specified one line per revision
** is printed, otherwise the full comment is printed.  The "--count N"
** and "--offset P" options limits the output to the first N changes
** after skipping P changes.
**
** In the -s mode prints the status as <status> <revision>.  This is
** a quick status and does not check for up-to-date-ness of the file.
**
** In the -p mode, there's an optional flag "-r|--revision REVISION".
** The specified version (or the latest checked out version) is printed
** to stdout.  The -p mode is another form of the "cat" command.
**
** Options:
**   --brief|-b           display a brief (one line / revision) summary
**   --case-sensitive B   Enable or disable case-sensitive filenames.  B is a
**                        boolean: "yes", "no", "true", "false", etc.
**   --count|n N          display the first N changes
**   --log|-l             select log mode (the default)
**   --offset P           skip P changes
**   --print|-p           select print mode
**   --revision|-r R      print the given revision (or ckout, if none is given)
**                        to stdout (only in print mode)
**   --status|-s          select status mode (print a status indicator for FILE)
**
138
139
140
141
142
143
144



145

146
147
148
149
150
151
152
    const char *zLimit;
    const char *zOffset;
    int iLimit, iOffset, iBrief;

    if( find_option("log","l",0) ){
      /* this is the default, no-op */
    }



    zLimit = find_option("limit",0,1);

    iLimit = zLimit ? atoi(zLimit) : -1;
    zOffset = find_option("offset",0,1);
    iOffset = zOffset ? atoi(zOffset) : 0;
    iBrief = (find_option("brief","b",0) == 0);
    if( g.argc!=3 ){
      usage("?-l|--log? ?-b|--brief? FILENAME");
    }







>
>
>
|
>







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    const char *zLimit;
    const char *zOffset;
    int iLimit, iOffset, iBrief;

    if( find_option("log","l",0) ){
      /* this is the default, no-op */
    }
    zLimit = find_option("count","n",1);
    if( !zLimit ){
      /* deprecated */
      zLimit = find_option("limit",0,1);
    }
    iLimit = zLimit ? atoi(zLimit) : -1;
    zOffset = find_option("offset",0,1);
    iOffset = zOffset ? atoi(zOffset) : 0;
    iBrief = (find_option("brief","b",0) == 0);
    if( g.argc!=3 ){
      usage("?-l|--log? ?-b|--brief? FILENAME");
    }

Changes to src/json_finfo.c.

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  cson_object * pay = NULL;
  cson_array * checkins = NULL;
  char const * zFilename = NULL;
  Blob sql = empty_blob;
  Stmt q = empty_Stmt;
  char const * zAfter = NULL;
  char const * zBefore = NULL;
  int limit = -1;
  int currentRow = 0;
  char const * zCheckin = NULL;
  char sort = -1;
  if(!g.perm.Read){
    json_set_err(FSL_JSON_E_DENIED,"Requires 'o' privileges.");
    return NULL;
  }







|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  cson_object * pay = NULL;
  cson_array * checkins = NULL;
  char const * zFilename = NULL;
  Blob sql = empty_blob;
  Stmt q = empty_Stmt;
  char const * zAfter = NULL;
  char const * zBefore = NULL;
  int count = -1;
  int currentRow = 0;
  char const * zCheckin = NULL;
  char sort = -1;
  if(!g.perm.Read){
    json_set_err(FSL_JSON_E_DENIED,"Requires 'o' privileges.");
    return NULL;
  }
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  if(0==db_int(0,"SELECT 1 FROM filename WHERE name=%Q",zFilename)){
    json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND, "File entry not found.");
    return NULL;
  }
  
  zBefore = json_find_option_cstr("before",NULL,"b");
  zAfter = json_find_option_cstr("after",NULL,"a");
  limit = json_find_option_int("limit",NULL,"n", -1);
  zCheckin = json_find_option_cstr("checkin",NULL,"ci");

  blob_appendf(&sql, 
/*0*/   "SELECT b.uuid,"
/*1*/   "   ci.uuid,"
/*2*/   "   (SELECT uuid FROM blob WHERE rid=mlink.fid),"  /* Current file uuid */
/*3*/   "   cast(strftime('%%s',event.mtime) AS INTEGER),"







|







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  if(0==db_int(0,"SELECT 1 FROM filename WHERE name=%Q",zFilename)){
    json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND, "File entry not found.");
    return NULL;
  }
  
  zBefore = json_find_option_cstr("before",NULL,"b");
  zAfter = json_find_option_cstr("after",NULL,"a");
  count = json_find_option_int("count",NULL,"n", -1);
  zCheckin = json_find_option_cstr("checkin",NULL,"ci");

  blob_appendf(&sql, 
/*0*/   "SELECT b.uuid,"
/*1*/   "   ci.uuid,"
/*2*/   "   (SELECT uuid FROM blob WHERE rid=mlink.fid),"  /* Current file uuid */
/*3*/   "   cast(strftime('%%s',event.mtime) AS INTEGER),"
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  /*printf("SQL=\n%s\n",blob_str(&sql));*/
  db_prepare(&q, "%s", blob_str(&sql)/*extra %s to avoid double-expanding
                                       SQL escapes*/);
  blob_reset(&sql);

  pay = cson_new_object();
  cson_object_set(pay, "name", json_new_string(zFilename));
  if( limit > 0 ){
    cson_object_set(pay, "limit", json_new_int(limit));
  }
  checkins = cson_new_array();
  cson_object_set(pay, "checkins", cson_array_value(checkins));
  while( db_step(&q)==SQLITE_ROW ){
    cson_object * row = cson_new_object();
    int const isNew = db_column_int(&q,9);
    int const isDel = db_column_int(&q,10);
    cson_array_append( checkins, cson_object_value(row) );
    cson_object_set(row, "checkin", json_new_string( db_column_text(&q,1) ));
    cson_object_set(row, "uuid", json_new_string( db_column_text(&q,2) ));
    /*cson_object_set(row, "parentArtifact", json_new_string( db_column_text(&q,6) ));*/
    cson_object_set(row, "timestamp", json_new_int( db_column_int(&q,3) ));
    cson_object_set(row, "user", json_new_string( db_column_text(&q,4) ));
    cson_object_set(row, "comment", json_new_string( db_column_text(&q,5) ));
    /*cson_object_set(row, "bgColor", json_new_string( db_column_text(&q,7) ));*/
    cson_object_set(row, "size", cson_value_new_integer( (cson_int_t)db_column_int64(&q,8) ));
    cson_object_set(row, "state",
                    json_new_string(json_artifact_status_to_string(isNew,isDel)));
    if( (0 < limit) && (++currentRow >= limit) ){
      break;
    }
  }
  db_finalize(&q);

  return pay ? cson_object_value(pay) : NULL;
}



#endif /* FOSSIL_ENABLE_JSON */







|
|


















|











110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  /*printf("SQL=\n%s\n",blob_str(&sql));*/
  db_prepare(&q, "%s", blob_str(&sql)/*extra %s to avoid double-expanding
                                       SQL escapes*/);
  blob_reset(&sql);

  pay = cson_new_object();
  cson_object_set(pay, "name", json_new_string(zFilename));
  if( count > 0 ){
    cson_object_set(pay, "count", json_new_int(count));
  }
  checkins = cson_new_array();
  cson_object_set(pay, "checkins", cson_array_value(checkins));
  while( db_step(&q)==SQLITE_ROW ){
    cson_object * row = cson_new_object();
    int const isNew = db_column_int(&q,9);
    int const isDel = db_column_int(&q,10);
    cson_array_append( checkins, cson_object_value(row) );
    cson_object_set(row, "checkin", json_new_string( db_column_text(&q,1) ));
    cson_object_set(row, "uuid", json_new_string( db_column_text(&q,2) ));
    /*cson_object_set(row, "parentArtifact", json_new_string( db_column_text(&q,6) ));*/
    cson_object_set(row, "timestamp", json_new_int( db_column_int(&q,3) ));
    cson_object_set(row, "user", json_new_string( db_column_text(&q,4) ));
    cson_object_set(row, "comment", json_new_string( db_column_text(&q,5) ));
    /*cson_object_set(row, "bgColor", json_new_string( db_column_text(&q,7) ));*/
    cson_object_set(row, "size", cson_value_new_integer( (cson_int_t)db_column_int64(&q,8) ));
    cson_object_set(row, "state",
                    json_new_string(json_artifact_status_to_string(isNew,isDel)));
    if( (0 < count) && (++currentRow >= count) ){
      break;
    }
  }
  db_finalize(&q);

  return pay ? cson_object_value(pay) : NULL;
}



#endif /* FOSSIL_ENABLE_JSON */

Changes to src/json_report.c.

151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
** Impl for /json/report/run
**
** Options/arguments:
**
** report=int (CLI: -report # or -r #) is the report number to run.
**
** limit=int (CLI: -limit # or -n #) -n is for compat. with other commands.
**
** format=a|o Specifies result format: a=each row is an arry, o=each
** row is an object.  Default=o.
*/
static cson_value * json_report_run(){
  int nReport;
  Stmt q = empty_Stmt;
  cson_object * pay = NULL;
  cson_array * tktList = NULL;
  char const * zFmt;
  char * zTitle = NULL;
  Blob sql = empty_blob;
  int limit = 0;
  cson_value * colNames = NULL;
  int i;

  if(!g.perm.RdTkt){
    json_set_err(FSL_JSON_E_DENIED,
                 "Requires 'r' privileges.");
    return NULL;







|












|







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
** Impl for /json/report/run
**
** Options/arguments:
**
** report=int (CLI: -report # or -r #) is the report number to run.
**
** count=int (CLI: -count # or -n #) -n is for compat. with other commands.
**
** format=a|o Specifies result format: a=each row is an arry, o=each
** row is an object.  Default=o.
*/
static cson_value * json_report_run(){
  int nReport;
  Stmt q = empty_Stmt;
  cson_object * pay = NULL;
  cson_array * tktList = NULL;
  char const * zFmt;
  char * zTitle = NULL;
  Blob sql = empty_blob;
  int count = 0;
  cson_value * colNames = NULL;
  int i;

  if(!g.perm.RdTkt){
    json_set_err(FSL_JSON_E_DENIED,
                 "Requires 'r' privileges.");
    return NULL;
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
    json_set_err(FSL_JSON_E_INVALID_ARGS,
                 "Report number %d not found.",
                 nReport);
    db_finalize(&q);
    goto error;
  }

  limit = json_find_option_int("limit",NULL,"n",-1);

  
  /* Copy over report's SQL...*/
  blob_append(&sql, db_column_text(&q,0), -1);
  zTitle = mprintf("%s", db_column_text(&q,1));
  db_finalize(&q);
  db_prepare(&q, "%s", blob_str(&sql));

  /** Build the response... */
  pay = cson_new_object();

  cson_object_set(pay, "report", json_new_int(nReport));
  cson_object_set(pay, "title", json_new_string(zTitle));
  if(limit>0){
    cson_object_set(pay, "limit", json_new_int((limit<0) ? 0 : limit));
  }
  free(zTitle);
  zTitle = NULL;

  if(g.perm.TktFmt){
    cson_object_set(pay, "sqlcode",
                    cson_value_new_string(blob_str(&sql),
                                          (unsigned int)blob_size(&sql)));
  }
  blob_reset(&sql);

  colNames = cson_sqlite3_column_names(q.pStmt);
  cson_object_set( pay, "columnNames", colNames);
  for( i = 0 ; ((limit>0) ?(i < limit) : 1)
         && (SQLITE_ROW == db_step(&q));
       ++i){
    cson_value * row = ('a'==*zFmt)
      ? cson_sqlite3_row_to_array(q.pStmt)
      : cson_sqlite3_row_to_object2(q.pStmt,
                                    cson_value_get_array(colNames));
    ;







|













|
|













|







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
    json_set_err(FSL_JSON_E_INVALID_ARGS,
                 "Report number %d not found.",
                 nReport);
    db_finalize(&q);
    goto error;
  }

  count = json_find_option_int("count",NULL,"n",-1);

  
  /* Copy over report's SQL...*/
  blob_append(&sql, db_column_text(&q,0), -1);
  zTitle = mprintf("%s", db_column_text(&q,1));
  db_finalize(&q);
  db_prepare(&q, "%s", blob_str(&sql));

  /** Build the response... */
  pay = cson_new_object();

  cson_object_set(pay, "report", json_new_int(nReport));
  cson_object_set(pay, "title", json_new_string(zTitle));
  if(count>0){
    cson_object_set(pay, "count", json_new_int((count<0) ? 0 : count));
  }
  free(zTitle);
  zTitle = NULL;

  if(g.perm.TktFmt){
    cson_object_set(pay, "sqlcode",
                    cson_value_new_string(blob_str(&sql),
                                          (unsigned int)blob_size(&sql)));
  }
  blob_reset(&sql);

  colNames = cson_sqlite3_column_names(q.pStmt);
  cson_object_set( pay, "columnNames", colNames);
  for( i = 0 ; ((count>0) ?(i < count) : 1)
         && (SQLITE_ROW == db_step(&q));
       ++i){
    cson_value * row = ('a'==*zFmt)
      ? cson_sqlite3_row_to_array(q.pStmt)
      : cson_sqlite3_row_to_object2(q.pStmt,
                                    cson_value_get_array(colNames));
    ;

Changes to src/json_tag.c.

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
  cson_value * listV = NULL;
  cson_array * list = NULL;
  char const * zName = NULL;
  char const * zType = NULL;
  char const * zType2 = NULL;
  char fRaw = 0;
  Stmt q = empty_Stmt;
  int limit = 0;
  int tagid = 0;

  if( !g.perm.Read ){
    json_set_err(FSL_JSON_E_DENIED,
                 "Requires 'o' permissions.");
    return NULL;
  }







|







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
  cson_value * listV = NULL;
  cson_array * list = NULL;
  char const * zName = NULL;
  char const * zType = NULL;
  char const * zType2 = NULL;
  char fRaw = 0;
  Stmt q = empty_Stmt;
  int count = 0;
  int tagid = 0;

  if( !g.perm.Read ){
    json_set_err(FSL_JSON_E_DENIED,
                 "Requires 'o' permissions.");
    return NULL;
  }
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
      case 'c': zType = "ci"; zType2 = "checkin"; break;
      case 'e': zType = "e"; zType2 = "event"; break;
      case 'w': zType = "w"; zType2 = "wiki"; break;
      case 't': zType = "t"; zType2 = "ticket"; break;
    }
  }

  limit = json_find_option_int("limit",NULL,"n",0);
  fRaw = json_find_option_bool("raw",NULL,NULL,0);
  
  tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='%s' || %Q",
                 fRaw ? "" : "sym-",
                 zName);
  
  payV = cson_value_new_object();
  pay = cson_value_get_object(payV);
  cson_object_set(pay, "name", json_new_string(zName));
  cson_object_set(pay, "raw", cson_value_new_bool(fRaw));
  cson_object_set(pay, "type", json_new_string(zType2));
  cson_object_set(pay, "limit", json_new_int(limit));

#if 1
  if( tagid<=0 ){
    cson_object_set(pay,"artifacts", cson_value_null());
    json_warn(FSL_JSON_W_TAG_NOT_FOUND, "Tag not found.");
    return payV;
  }
#endif

  if( fRaw ){
    db_prepare(&q,
               "SELECT blob.uuid FROM tagxref, blob"
               " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
               "   AND tagxref.tagtype>0"
               "   AND blob.rid=tagxref.rid"
               "%s LIMIT %d",
               zName,
               (limit>0)?"":"--", limit
               );
    while( db_step(&q)==SQLITE_ROW ){
      if(!listV){
        listV = cson_value_new_array();
        list = cson_value_get_array(listV);
      }
      cson_array_append(list, cson_sqlite3_column_to_value(q.pStmt,0));







|











|

















|







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
      case 'c': zType = "ci"; zType2 = "checkin"; break;
      case 'e': zType = "e"; zType2 = "event"; break;
      case 'w': zType = "w"; zType2 = "wiki"; break;
      case 't': zType = "t"; zType2 = "ticket"; break;
    }
  }

  count = json_find_option_int("count",NULL,"n",0);
  fRaw = json_find_option_bool("raw",NULL,NULL,0);
  
  tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='%s' || %Q",
                 fRaw ? "" : "sym-",
                 zName);
  
  payV = cson_value_new_object();
  pay = cson_value_get_object(payV);
  cson_object_set(pay, "name", json_new_string(zName));
  cson_object_set(pay, "raw", cson_value_new_bool(fRaw));
  cson_object_set(pay, "type", json_new_string(zType2));
  cson_object_set(pay, "count", json_new_int(count));

#if 1
  if( tagid<=0 ){
    cson_object_set(pay,"artifacts", cson_value_null());
    json_warn(FSL_JSON_W_TAG_NOT_FOUND, "Tag not found.");
    return payV;
  }
#endif

  if( fRaw ){
    db_prepare(&q,
               "SELECT blob.uuid FROM tagxref, blob"
               " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
               "   AND tagxref.tagtype>0"
               "   AND blob.rid=tagxref.rid"
               "%s LIMIT %d",
               zName,
               (count>0)?"":"--", count
               );
    while( db_step(&q)==SQLITE_ROW ){
      if(!listV){
        listV = cson_value_new_array();
        list = cson_value_get_array(listV);
      }
      cson_array_append(list, cson_sqlite3_column_to_value(q.pStmt,0));
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
               "  AND blob.rid IN ("
               "    SELECT rid FROM tagxref"
               "      WHERE tagtype>0 AND tagid=%d"
               "  )"
               " ORDER BY event.mtime DESC"
               "%s LIMIT %d",
               zSqlBase, zType, tagid,
               (limit>0)?"":"--", limit
               );
    listV = json_stmt_to_array_of_obj(&q, NULL);
    db_finalize(&q);
  }

  if(!listV) {
    listV = cson_value_null();







|







300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
               "  AND blob.rid IN ("
               "    SELECT rid FROM tagxref"
               "      WHERE tagtype>0 AND tagid=%d"
               "  )"
               " ORDER BY event.mtime DESC"
               "%s LIMIT %d",
               zSqlBase, zType, tagid,
               (count>0)?"":"--", count
               );
    listV = json_stmt_to_array_of_obj(&q, NULL);
    db_finalize(&q);
  }

  if(!listV) {
    listV = cson_value_null();

Changes to src/json_timeline.c.

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
    blob_append(pSql, " ORDER BY event.mtime DESC ", -1);
    rc = 0;
  }
  return rc;
}

/*
** Tries to figure out a timeline query length limit base on
** environment parameters. If it can it returns that value,
** else it returns some statically defined default value.
**
** Never returns a negative value. 0 means no limit.
*/
static int json_timeline_limit(int defaultLimit){
  int limit = -1;
  if(!g.isHTTP){/* CLI mode */
    char const * arg = find_option("limit","n",1);
    if(arg && *arg){
      limit = atoi(arg);
    }
  }
  if( (limit<0) && fossil_has_json() ){
    limit = json_getenv_int("limit",-1);
  }
  return (limit<0) ? defaultLimit : limit;
}

/*
** Internal helper for the json_timeline_EVENTTYPE() family of
** functions. zEventType must be one of (ci, w, t). pSql must be a
** cleanly-initialized, empty Blob to store the sql in. If pPayload is
** not NULL it is assumed to be the pending response payload. If
** json_timeline_limit() returns non-0, this function adds a LIMIT
** clause to the generated SQL.
**
** If pPayload is not NULL then this might add properties to pPayload,
** reflecting options set in the request environment.
**
** Returns 0 on success. On error processing should not continue and
** the returned value should be used as g.json.resultCode.
*/
static int json_timeline_setup_sql( char const * zEventType,
                                    Blob * pSql,
                                    cson_object * pPayload ){
  int limit;
  assert( zEventType && *zEventType && pSql );
  json_timeline_temp_table();
  blob_append(pSql, "INSERT OR IGNORE INTO json_timeline ", -1);
  blob_append(pSql, json_timeline_query(), -1 );
  blob_appendf(pSql, " AND event.type IN(%Q) ", zEventType);
  if( json_timeline_add_tag_branch_clause(pSql, pPayload) < 0 ){
    return FSL_JSON_E_INVALID_ARGS;
  }
  json_timeline_add_time_clause(pSql);
  limit = json_timeline_limit(20);
  if(limit>0){
    blob_appendf(pSql,"LIMIT %d ",limit);
  }
  if(pPayload){
    cson_object_set(pPayload, "limit", json_new_int(limit));
  }
  return 0;
}


/*
** If any files are associated with the given rid, a JSON array







|



|

|
|

|

|


|
|

|



















|









|
|
|


|







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
    blob_append(pSql, " ORDER BY event.mtime DESC ", -1);
    rc = 0;
  }
  return rc;
}

/*
** Tries to figure out a timeline query length count base on
** environment parameters. If it can it returns that value,
** else it returns some statically defined default value.
**
** Never returns a negative value. 0 means no count.
*/
static int json_timeline_count(int defaultCount){
  int count = -1;
  if(!g.isHTTP){/* CLI mode */
    char const * arg = find_option("count","n",1);
    if(arg && *arg){
    	count = atoi(arg);
    }
  }
  if( (count<0) && fossil_has_json() ){
    count = json_getenv_int("count",-1);
  }
  return (count<0) ? defaultCount : count;
}

/*
** Internal helper for the json_timeline_EVENTTYPE() family of
** functions. zEventType must be one of (ci, w, t). pSql must be a
** cleanly-initialized, empty Blob to store the sql in. If pPayload is
** not NULL it is assumed to be the pending response payload. If
** json_timeline_limit() returns non-0, this function adds a LIMIT
** clause to the generated SQL.
**
** If pPayload is not NULL then this might add properties to pPayload,
** reflecting options set in the request environment.
**
** Returns 0 on success. On error processing should not continue and
** the returned value should be used as g.json.resultCode.
*/
static int json_timeline_setup_sql( char const * zEventType,
                                    Blob * pSql,
                                    cson_object * pPayload ){
  int count;
  assert( zEventType && *zEventType && pSql );
  json_timeline_temp_table();
  blob_append(pSql, "INSERT OR IGNORE INTO json_timeline ", -1);
  blob_append(pSql, json_timeline_query(), -1 );
  blob_appendf(pSql, " AND event.type IN(%Q) ", zEventType);
  if( json_timeline_add_tag_branch_clause(pSql, pPayload) < 0 ){
    return FSL_JSON_E_INVALID_ARGS;
  }
  json_timeline_add_time_clause(pSql);
  count = json_timeline_count(20);
  if(count>0){
    blob_appendf(pSql,"LIMIT %d ",count);
  }
  if(pPayload){
    cson_object_set(pPayload, "count", json_new_int(count));
  }
  return 0;
}


/*
** If any files are associated with the given rid, a JSON array
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
  return rowsV;
}

static cson_value * json_timeline_branch(){
  cson_value * pay = NULL;
  Blob sql = empty_blob;
  Stmt q = empty_Stmt;
  int limit = 0;
  if(!g.perm.Read){
    json_set_err(FSL_JSON_E_DENIED,
                 "Requires 'o' permissions.");
    return NULL;
  }
  json_timeline_temp_table();
  blob_append(&sql,







|







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
  return rowsV;
}

static cson_value * json_timeline_branch(){
  cson_value * pay = NULL;
  Blob sql = empty_blob;
  Stmt q = empty_Stmt;
  int count = 0;
  if(!g.perm.Read){
    json_set_err(FSL_JSON_E_DENIED,
                 "Requires 'o' permissions.");
    return NULL;
  }
  json_timeline_temp_table();
  blob_append(&sql,
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382

  blob_appendf(&sql,
               " AND event.type='ci'"
               " AND blob.rid IN (SELECT rid FROM tagxref"
               "  WHERE tagtype>0 AND tagid=%d AND srcid!=0)"
               " ORDER BY event.mtime DESC",
               TAG_BRANCH);
  limit = json_timeline_limit(20);
  if(limit>0){
    blob_appendf(&sql," LIMIT %d ",limit);
  }
  db_prepare(&q,"%s", blob_str(&sql));
  blob_reset(&sql);
  pay = json_stmt_to_array_of_obj(&q, NULL);
  db_finalize(&q);
  assert(NULL != pay);
  if(pay){







|
|
|







366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382

  blob_appendf(&sql,
               " AND event.type='ci'"
               " AND blob.rid IN (SELECT rid FROM tagxref"
               "  WHERE tagtype>0 AND tagid=%d AND srcid!=0)"
               " ORDER BY event.mtime DESC",
               TAG_BRANCH);
  count = json_timeline_count(20);
  if(count>0){
    blob_appendf(&sql," LIMIT %d ",count);
  }
  db_prepare(&q,"%s", blob_str(&sql));
  blob_reset(&sql);
  pay = json_stmt_to_array_of_obj(&q, NULL);
  db_finalize(&q);
  assert(NULL != pay);
  if(pay){
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
    cson_value_free( cson_string_value(tags) );
    cson_value_free( cson_string_value(isLeaf) );

    /* now we wrap the payload in an outer shell, for consistency with
       other /json/timeline/xyz APIs...
    */
    outer = cson_new_object();
    if(limit>0){
      cson_object_set( outer, "limit", json_new_int(limit) );
    }
    cson_object_set( outer, "timeline", pay );
    pay = cson_object_value(outer);
  }
  return pay;
}








|
|







402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
    cson_value_free( cson_string_value(tags) );
    cson_value_free( cson_string_value(isLeaf) );

    /* now we wrap the payload in an outer shell, for consistency with
       other /json/timeline/xyz APIs...
    */
    outer = cson_new_object();
    if(count>0){
      cson_object_set( outer, "count", json_new_int(count) );
    }
    cson_object_set( outer, "timeline", pay );
    pay = cson_object_value(outer);
  }
  return pay;
}