Check-in [1e9c0e287e]
Not logged in
Overview

SHA1 Hash:1e9c0e287e9609f3ee097136ff751d4701278cf5
Date: 2007-10-03 12:20:00
User: drh
Comment:Test commands for importing and exporting ticket configurations.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/db.c from [9a4a994425] to [0feeb7fd06].

@@ -832,12 +832,12 @@
 
 /*
 ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the
 ** repository and local databases.
 */
-const char *db_get(const char *zName, const char *zDefault){
-  const char *z = 0;
+char *db_get(const char *zName, char *zDefault){
+  char *z = 0;
   if( g.repositoryOpen ){
     z = db_text(0, "SELECT value FROM config WHERE name=%Q", zName);
   }
   if( z==0 ){
     z = db_text(0, "SELECT value FROM global_config WHERE name=%Q", zName);
@@ -885,11 +885,11 @@
   if( globalFlag && g.repositoryOpen ){
     db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
   }
   db_end_transaction(0);
 }
-char *db_lget(const char *zName, const char *zDefault){
+char *db_lget(const char *zName, char *zDefault){
   return db_text((char*)zDefault,
                  "SELECT value FROM vvar WHERE name=%Q", zName);
 }
 void db_lset(const char *zName, const char *zValue){
   db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%Q)", zName, zValue);

Modified src/main.c from [1a17fea25b] to [157f4f5378].

@@ -595,10 +595,19 @@
   }else{
     db_must_be_within_tree();
   }
   cgi_handle_http_request();
   process_one_web_page();
+}
+
+/*
+** COMMAND: test-http
+** Works like the http command but gives setup permission to all users.
+*/
+void cmd_test_http(void){
+  login_set_capabilities("s");
+  cmd_http();
 }
 
 /*
 ** COMMAND: server
 **

Modified src/setup.c from [8bc84ec78b] to [b3c7fee01f].

@@ -450,11 +450,11 @@
 static void entry_attribute(
   const char *zLabel,   /* The text label on the entry box */
   int width,            /* Width of the entry box */
   const char *zVar,     /* The corresponding row in the VAR table */
   const char *zQParm,   /* The query parameter */
-  const char *zDflt     /* Default value if VAR table entry does not exist */
+  char *zDflt     /* Default value if VAR table entry does not exist */
 ){
   const char *zVal = db_get(zVar, zDflt);
   const char *zQ = P(zQParm);
   if( zQ && strcmp(zQ,zVal)!=0 ){
     db_set(zVar, zQ, 0);
@@ -471,11 +471,11 @@
   const char *zLabel,   /* The text label on the textarea */
   int rows,             /* Rows in the textarea */
   int cols,             /* Columns in the textarea */
   const char *zVar,     /* The corresponding row in the VAR table */
   const char *zQParm,   /* The query parameter */
-  const char *zDflt     /* Default value if VAR table entry does not exist */
+  char *zDflt           /* Default value if VAR table entry does not exist */
 ){
   const char *zVal = db_get(zVar, zDflt);
   const char *zQ = P(zQParm);
   if( zQ && strcmp(zQ,zVal)!=0 ){
     db_set(zVar, zQ, 0);

Modified src/tktconf.c from [75634c8ba4] to [d2929cd226].

@@ -152,19 +152,19 @@
   ** the tktfield table and to insert template text into the
   ** config table
   */
   blob_appendf(&tbldef,
      "DROP TABLE IF EXISTS ticket;\n"
-     "CREATE TABLE ticket(\n"
+     "CREATE TABLE repository.ticket(\n"
      "  tktid INTEGER PRIMARY KEY,\n"
      "  tktuuid TEXT UNIQUE,\n"
      "  starttime DATETIME,\n"
      "  lastmod DATETIME"
   );
   blob_appendf(&sql,
      "DROP TABLE IF EXISTS tktfield;\n"
-     "CREATE TABLE tktfield(\n"
+     "CREATE TABLE repository.tktfield(\n"
      "  fidx INTEGER PRIMARY KEY,\n"
      "  name TEXT UNIQUE,\n"
      "  type TEXT,\n"
      "  width INTEGER,\n"
      "  arg\n"
@@ -308,11 +308,10 @@
     **  <text>
     */
     if( blob_eq(&token, "description")
      && blob_token(&line, &arg)
     ){
-      int idx;
       Blob content;
       int start;
       int end;
 
       start = end = blob_tell(pConfig);
@@ -367,18 +366,36 @@
 }
 
 /*
 ** COMMAND: test-tktconfig-parse
 */
-void test_tktconfig_cmd(void){
+void test_tktconfig_parse_cmd(void){
   Blob config, err;
   if( g.argc!=3 ){
     usage("FILENAME");
   }
   blob_read_from_file(&config, g.argv[2]);
   blob_zero(&err);
   ticket_config_parse(&config, 1, &err);
+  if( blob_size(&err) ){
+    blob_write_to_file(&err, "-");
+  }
+}
+/*
+** COMMAND: test-tktconfig-import
+*/
+void test_tktconfig_import_cmd(void){
+  Blob config, err;
+  db_must_be_within_tree();
+  if( g.argc!=3 ){
+    usage("FILENAME");
+  }
+  blob_read_from_file(&config, g.argv[2]);
+  blob_zero(&err);
+  db_begin_transaction();
+  ticket_config_parse(&config, 0, &err);
+  db_end_transaction(0);
   if( blob_size(&err) ){
     blob_write_to_file(&err, "-");
   }
 }
 
@@ -560,6 +577,92 @@
   ticket_config_parse(&config, 0, &errmsg);
   if( blob_size(&errmsg) ){
     fossil_fatal("%b", &errmsg);
   }
   db_end_transaction(0);
+}
+
+/*
+** Return the length of a string without its trailing whitespace.
+*/
+static int non_whitespace_length(const char *z){
+  int n = strlen(z);
+  while( n>0 && isspace(z[n-1]) ){ n--; }
+  return n;
+}
+
+/*
+** Fill the given Blob with text that describes the current
+** ticket configuration.  This is the inverse of ticket_config_parse()
+*/
+void ticket_config_render(Blob *pOut){
+  char *zDelim;
+  char *zContent;
+  Stmt q;
+  int n;
+
+  blob_appendf(pOut, "ticket-configuration\n");
+  zDelim = db_text(0, "SELECT '--end-of-text--' || hex(random(20))");
+  blob_appendf(pOut, "###################################################\n");
+  db_prepare(&q, "SELECT name, type, width, arg FROM tktfield");
+  while( db_step(&q)==SQLITE_ROW ){
+    const char *zName = db_column_text(&q, 0);
+    const char *zType = db_column_text(&q, 1);
+    int width = db_column_int(&q, 2);
+    const char *zArg = db_column_text(&q, 3);
+    blob_appendf(pOut, "field %s %s %d %s\n", zName, zType, width, zArg);
+  }
+  db_finalize(&q);
+  blob_appendf(pOut, "###################################################\n");
+  blob_appendf(pOut, "template new %s\n", zDelim);
+  zContent = db_get("tkt-new-template", 0);
+  if( zContent ){
+    n = non_whitespace_length(zContent);
+    blob_appendf(pOut, "%.*s\n", n, zContent);
+    free(zContent);
+  }
+  blob_appendf(pOut, "%s\n", zDelim);
+  blob_appendf(pOut, "###################################################\n");
+  blob_appendf(pOut, "template edit %s\n", zDelim);
+  zContent = db_get("tkt-edit-template", 0);
+  if( zContent ){
+    n = non_whitespace_length(zContent);
+    blob_appendf(pOut, "%.*s\n", n, zContent);
+    free(zContent);
+  }
+  blob_appendf(pOut, "%s\n", zDelim);
+  blob_appendf(pOut, "###################################################\n");
+  blob_appendf(pOut, "template view %s\n", zDelim);
+  zContent = db_get("tkt-view-template", 0);
+  if( zContent ){
+    n = non_whitespace_length(zContent);
+    blob_appendf(pOut, "%.*s\n", n, zContent);
+    free(zContent);
+  }
+  blob_appendf(pOut, "%s\n", zDelim);
+  blob_appendf(pOut, "###################################################\n");
+  blob_appendf(pOut, "description %s\n", zDelim);
+  zContent = db_get("tkt-desc", 0);
+  if( zContent ){
+    n = non_whitespace_length(zContent);
+    blob_appendf(pOut, "%.*s\n", n, zContent);
+    free(zContent);
+  }
+  blob_appendf(pOut, "%s\n", zDelim);
+}
+
+/*
+** COMMAND: test-tktconfig-export
+** Write the current ticket configuration out to a file.
+*/
+void tktconfig_render_cmd(void){
+  Blob config;
+
+  db_must_be_within_tree();
+  if( g.argc!=3 ){
+    usage("FILENAME");
+  }
+  blob_zero(&config);
+  ticket_config_render(&config);
+  blob_write_to_file(&config, g.argv[2]);
+  blob_reset(&config);
 }

Modified src/tktsetup.c from [58133ca678] to [1bb9488bc9].

@@ -44,34 +44,89 @@
     "Load a predefined ticket configuration");
   setup_menu_entry("Save", "tktsetup_save",
     "Save the current ticket configuration as an artifact");
   setup_menu_entry("Fields", "tktsetup_fields",
     "View or edit the fields allowed in tickets");
-  setup_menu_entry("New", "tktsetup_newtemplate",
+  setup_menu_entry("New", "tktsetup_template?type=new",
     "View or edit the template page used for creating a new ticket");
-  setup_menu_entry("View", "tktsetup_viewtemplate",
+  setup_menu_entry("View", "tktsetup_template?type=view",
     "View or edit the template page used for viewing a ticket");
-  setup_menu_entry("Edit", "tktsetup_edittemplate",
+  setup_menu_entry("Edit", "tktsetup_template?type=edit",
     "View or edit the template page used for editing a ticket");
   @ </dl>
 
   style_footer();
 }
 
 /*
+** Load the ticket configuration in the artifact with rid.
+** If an error occurs, return 1 and leave an error message.
+*/
+static int load_config(int rid, Blob *pErr){
+  Blob content;
+  int rc;
+  if( content_get(rid, &content)==0 ){
+    blob_appendf(pErr, "no such artifact: %d", rid);
+    return 1;
+  }
+  rc = ticket_config_parse(&content, 0, pErr);
+  blob_reset(&content);
+  return rc;
+}
+
+/*
 ** WEBPAGE: /tktsetup_load
 */
 void tktsetup_load_page(void){
   int loadrid;
-  int loaddflt;
+  Blob err;
+  Stmt s;
 
   login_check_credentials();
   if( !g.okSetup ){
     login_needed();
   }
-  loadrid = atoi(PD("id","0"));
-  loaddflt = P("dflt")!=0;
-  if( loaddflt ){
+  if( P("dflt")!=0 ){
     ticket_load_default_config();
     cgi_redirect("tktsetup");
   }
+  loadrid = atoi(PD("id","0"));
+  blob_zero(&err);
+  if( loadrid ){
+    if( load_config(loadrid, &err) ){
+      style_header("Configuration Error");
+      @ <p>The following error occurred while trying to load
+      @ the configuration in artifact #%d(loadrid):</p>
+      @ <blockquote><b>%h(blob_str(&err))</b></blockquote>
+      @ <p>Return to the <a href="tktsetup">ticket setup menu</a>.</p>
+      style_footer();
+    }else{
+      cgi_redirect("tktsetup");
+    }
+    return;
+  }
+  style_header("Load Configuration");
+  @ <p>Select one of the following ticket configurations to load:</p>
+  @ <ul>
+  @ <li><p>[<a href="tktsetup_load?dflt=1">default</a>]
+  @        The default built-in ticket configuration.</p></li>
+  db_prepare(&s,
+    "SELECT blob.uuid, tagxref.rid, datetime(tagxref.mtime, 'localtime')"
+    "  FROM tagxref, blob"
+    " WHERE tagxref.tagid=(SELECT tagid FROM tag "
+                           "WHERE tagname='ticket_configuration')"
+    "   AND blob.rid=tagxref.rid"
+    " ORDER BY tagxref.mtime DESC"
+  );
+  while( db_step(&s)==SQLITE_ROW ){
+    const char *zUuid = db_column_text(&s, 0);
+    int rid = db_column_int(&s, 1);
+    const char *zWhen = db_column_text(&s, 2);
+    @ <li><p>[<a href="tktsetup_load?id=%d(rid)">%s(zUuid)</a>].
+    @        Configuration created on %s(zWhen).</p></li>
+  }
+  db_finalize(&s);
+  @ <li><p>[<a href="tktsetup">Cancel</a>].  Return to the main
+  @        ticket configuration setup menu.</p></li>
+  @ </ul>
+  style_footer();
 }