Changes On Branch th1_fossiltag_cmd
Not logged in

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

Changes In Branch th1_fossiltag_cmd Excluding Merge-Ins

This is equivalent to a diff from 26c262cd03 to 413ebeb12e

2010-10-21
23:26
TH1 fossiltag command for accessing tag values.    Has two subcommands: get and list, which do what they sound like. Leaf check-in: 413ebeb12e user: bcsmith tags: th1_fossiltag_cmd
2010-10-11
13:43
Allow events to be referenced using a prefix of their full event-id. check-in: f2025072b4 user: drh tags: trunk
2010-10-09
17:18
Fix a potential segfault on "fossil pull". Ticket [71439c64b8d6af66f5e34]. check-in: 26c262cd03 user: drh tags: trunk
13:04
Add a compile-time option to ignore the control file checksum (for a modest performance increase while parsing control files.) Enhance the test-parse-manifest command to facilitate performance studies. check-in: 712988286e user: drh tags: trunk

Changes to src/th_main.c.

   231    231     }
   232    232     if( g.thTrace ){
   233    233       Th_Trace("[hascap %.*h] => %d<br />\n", argl[1], argv[1], rc);
   234    234     }
   235    235     Th_SetResultInt(interp, rc);
   236    236     return TH_OK;
   237    237   }
          238  +
          239  +/*
          240  +**
          241  +** TH1 command: fossiltag list ?ARTIFACT-ID?
          242  +**
          243  +**   Returns a list of tags on ARTIFACT-ID. Or, all tags,
          244  +**   if ARTIFACT-ID is not specified. Only uncancelled tags
          245  +**   are included in the result.
          246  +**
          247  +**   Example:
          248  +**     <b>List of tags on thing:</b>
          249  +**     <th1>
          250  +**     puts [fossiltag list 2b4630f34]
          251  +**     </th1>
          252  +*/
          253  +static int fossiltagListCmd(
          254  +  Th_Interp *interp,
          255  +  void *p,
          256  +  int argc,
          257  +  const char **argv,
          258  +  int *argl
          259  +){
          260  +  Stmt st;
          261  +  char *zTagList = 0;
          262  +  int  nTagList = 0;
          263  +  if( argc==3 ){
          264  +    db_prepare(&st,
          265  +               "SELECT tag.tagname FROM tag, tagxref "
          266  +               "  WHERE tagxref.rid=%d "
          267  +               "    AND tagxref.tagid=tag.tagid"
          268  +               "    AND tagxref.tagtype>0 ",
          269  +               name_to_rid((char*)argv[2])
          270  +               );
          271  +  }
          272  +  else {
          273  +    db_prepare(&st,
          274  +               "SELECT DISTINCT tag.tagname FROM tag, tagxref "
          275  +               "  WHERE "
          276  +               "    tagxref.tagid=tag.tagid"
          277  +               "    AND tagxref.tagtype>0 "
          278  +               );
          279  +  }
          280  +  while( db_step(&st) == SQLITE_ROW ){
          281  +    char *tagname = (char*)db_column_text(&st, 0);
          282  +    Th_ListAppend(interp, &zTagList, &nTagList, tagname, -1);
          283  +
          284  +  }
          285  +
          286  +  Th_SetResult(interp, zTagList, nTagList);
          287  +  Th_Free(interp, zTagList);
          288  +  db_finalize(&st);
          289  +  return TH_OK;
          290  +}
          291  +
          292  +/*
          293  +**
          294  +** TH1 command: fossiltag get TAG-NAME ?ARTIFACT-ID? ?FALLBACK-VALUE?
          295  +**
          296  +**   Returns the value of TAG-NAME on ARTIFACT-ID, or
          297  +**   one of the following:
          298  +**   if FALLBACK-VALUE provided and TAG-NAME not present,
          299  +**   then FALLBACK-VALUE is returned.
          300  +**   if FALLBACK-VALUE not provided, and TAG-NAME not present,
          301  +**   then 0 returned.
          302  +**   if TAG-NAME present, but has no value, then 1 is returned.
          303  +**
          304  +**   Example:
          305  +**     <b>Check-in acceptance status:</b>
          306  +**     <th1>
          307  +**     set accept_out ""
          308  +**     if {[set out [fossiltag get "QA_acceptance" $check_in_id "<b>DID NOT PASS</b>"]]} {
          309  +**       set accept_out "  *  QA: ${out}"
          310  +**     }
          311  +**     if {[set out [fossiltag get "Unit_passed" $check_in_id "<b>DID NOT PASS UNIT TESTS</b>"]]} {
          312  +**       set accept_out "${accept_out}\n  *  Unit tests: ${out}"
          313  +**     }
          314  +**     if {[set out [fossiltag get "Signed_off_by" $check_in_id "<b>NOT SIGNED OFF</b>"]]} {
          315  +**       set accept_out "${accept_out}\n  *  Signed off by: ${out}"
          316  +**     }
          317  +**     puts [wiki $accept_out]
          318  +**     </th1>
          319  +*/
          320  +static int fossiltagGetCmd(
          321  +  Th_Interp *interp,
          322  +  void *p,
          323  +  int argc,
          324  +  const char **argv,
          325  +  int *argl
          326  +){
          327  +  int rid = -1;
          328  +  char *zTagValue = 0;
          329  +  char *zDefault = 0;
          330  +  int nDefault = 0;
          331  +  db_open_local();
          332  +  db_open_repository(0);
          333  +  if( argc<3 ){
          334  +    return Th_WrongNumArgs(interp, "fossiltag get TAG-NAME ?ARTIFACT-ID? ?FALLBACK-TEXT?");
          335  +  }
          336  +  /* if a fallback value was provided, place it in zDefault */
          337  +  if( argc==5 ){
          338  +    zDefault = (char*)argv[4];
          339  +    nDefault = argl[4];
          340  +  }
          341  +  /* if an artifact-id (name) is given.. */
          342  +  if( argc>=4 && strlen((char*)argv[3])){
          343  +    rid =
          344  +    db_int(0,
          345  +           "SELECT blob.rid "
          346  +           "  FROM tag, tagxref, blob "
          347  +           "WHERE tag.tagname=%Q AND blob.rid=%d"
          348  +           "  AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
          349  +           "  AND blob.rid=tagxref.rid ",
          350  +           argv[2], name_to_rid((char*)argv[3])
          351  +           );
          352  +
          353  +    if( g.thTrace ){
          354  +      Th_Trace("[tagget] artifact-id: %s %d\n", argv[3], rid);
          355  +    }
          356  +  }
          357  +  else { /* if no artifact-id is given, we select the most recent commit
          358  +            containing TAG-NAME */
          359  +    rid =
          360  +    db_int(0,
          361  +       "SELECT blob.rid "
          362  +       "  FROM tag, tagxref, event, blob "
          363  +       "WHERE tag.tagname=%Q "
          364  +       "  AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
          365  +       "  AND event.objid=tagxref.rid "
          366  +       "  AND blob.rid=event.objid "
          367  +       "ORDER BY event.mtime DESC ",
          368  +       argv[2]
          369  +    );
          370  +    if( g.thTrace ){
          371  +      Th_Trace("[tagget] artifact-rid: %d\n", rid);
          372  +    }
          373  +  }
          374  +
          375  +  /* return 0 or the fallback value, since we couldn't
          376  +     find an artifact with TAG-NAME on it. */
          377  +  if( rid==0 && argc==5 ){
          378  +    if( g.thTrace ){
          379  +      Th_Trace("[tagget] tag not on any artifact; returning default: %s\n", zDefault);
          380  +    }
          381  +    Th_SetResult(interp, zDefault, nDefault);
          382  +    return TH_OK;
          383  +  }
          384  +  else if( rid==0 && argc<5 ){
          385  +    if( g.thTrace ){
          386  +      Th_Trace("[tagget] tag not on any artifact; ret: 0\n");
          387  +    }
          388  +    Th_SetResultInt(interp, 0);
          389  +    return TH_OK;
          390  +  }
          391  +
          392  +  zTagValue = db_text(zDefault,
          393  +                      "SELECT tagxref.value FROM tag, tagxref "
          394  +                      "  WHERE tag.tagname=%Q "
          395  +                      "    AND tagxref.tagid=tag.tagid "
          396  +                      "    AND tagxref.rid=%d ",
          397  +                      argv[2], rid
          398  +                      );
          399  +  if( zTagValue && strlen(zTagValue)==0 ){
          400  +    if( g.thTrace ){
          401  +      Th_Trace("[tagget] tag has no value; ret: 1\n");
          402  +    }
          403  +    Th_SetResultInt(interp, 1);
          404  +    free(zTagValue);
          405  +  }
          406  +  else {
          407  +    if( g.thTrace ){
          408  +      Th_Trace("[tagget] returning tag value: %s\n", zTagValue);
          409  +    }
          410  +    Th_SetResult(interp, zTagValue, -1);
          411  +    free(zTagValue);
          412  +  }
          413  +  return TH_OK;
          414  +}
          415  +
          416  +/*
          417  +** TH1 command: fossiltag list|get ...
          418  +**
          419  +** Provide TH1 commands for read-only interation with tags on
          420  +** any taggable artifact. The tags are always raw.
          421  +**
          422  +*/
          423  +static int fossiltagCmd(
          424  +  Th_Interp *interp,
          425  +  void *p,
          426  +  int argc,
          427  +  const char **argv,
          428  +  int *argl
          429  +){
          430  +  Th_SubCommand aSub[] = {
          431  +    { "list", fossiltagListCmd },
          432  +    { "get",   fossiltagGetCmd },
          433  +    { 0, 0 }
          434  +  };
          435  +  return Th_CallSubCommand(interp, p, argc, argv, argl, aSub);
          436  +}
   238    437   
   239    438   /*
   240    439   ** TH1 command:  combobox NAME TEXT-LIST NUMLINES
   241    440   **
   242    441   ** Generate an HTML combobox.  NAME is both the name of the
   243    442   ** CGI parameter and the name of a variable that contains the
   244    443   ** currently selected value.  TEXT-LIST is a list of possible
................................................................................
   348    547       {"linecount",     linecntCmd,           0},
   349    548       {"hascap",        hascapCmd,            0},
   350    549       {"htmlize",       htmlizeCmd,           0},
   351    550       {"date",          dateCmd,              0},
   352    551       {"html",          putsCmd,              0},
   353    552       {"puts",          putsCmd,       (void*)1},
   354    553       {"wiki",          wikiCmd,              0},
          554  +    {"fossiltag",     fossiltagCmd,         0},
   355    555     };
   356    556     if( g.interp==0 ){
   357    557       int i;
   358    558       g.interp = Th_CreateInterp(&vtab);
   359    559       th_register_language(g.interp);       /* Basic scripting commands. */
   360    560       for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){
   361    561         Th_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc,
................................................................................
   517    717   }
   518    718   
   519    719   /*
   520    720   ** COMMAND: test-th-render
   521    721   */
   522    722   void test_th_render(void){
   523    723     Blob in;
          724  +  g.thTrace = find_option("th-trace", 0, 0)!=0;
          725  +  if( g.thTrace ){
          726  +    blob_zero(&g.thLog);
          727  +  }
   524    728     if( g.argc<3 ){
   525    729       usage("FILE");
   526    730     }
   527    731     blob_zero(&in);
   528         -  blob_read_from_file(&in, g.argv[2]);
          732  +  if( g.thTrace ){
          733  +    blob_read_from_file(&in, g.argv[3]);
          734  +  }
          735  +  else{
          736  +    blob_read_from_file(&in, g.argv[2]);
          737  +  }
   529    738     Th_Render(blob_str(&in));
          739  +  if( g.thTrace ){
          740  +    fossil_print("%s", blob_materialize(&g.thLog));
          741  +  }
   530    742   }