Index: trunk/ippTools/src/pztool.c
===================================================================
--- trunk/ippTools/src/pztool.c	(revision 21479)
+++ trunk/ippTools/src/pztool.c	(revision 23497)
@@ -44,7 +44,8 @@
 
 static bool clearcommonfaultsMode(pxConfig *config);
+static bool toadvanceMode(pxConfig *config);
 static bool advanceMode(pxConfig *config);
 
-static bool copydoneCompleteExp(pxConfig *config);
+// static bool copydoneCompleteExp(pxConfig *config);
 static psArray *pzGetPendingCameras(pxConfig *config);
 static psArray *pzArrayZip(psArray *arraySet, psS64 limit);
@@ -80,4 +81,5 @@
         MODECASE(PZTOOL_MODE_REVERTCOPIED, revertcopiedMode);
         MODECASE(PZTOOL_MODE_CLEARCOMMONFAULTS, clearcommonfaultsMode);
+        MODECASE(PZTOOL_MODE_TOADVANCE, toadvanceMode);
         MODECASE(PZTOOL_MODE_ADVANCE, advanceMode);
         default:
@@ -403,6 +405,4 @@
     PXOPT_LOOKUP_S16(code, config->args, "-code", false, false);
 
-    // NOTE : the rest of the command-line args are parsed in copydoneCompleteExp
-
     // start a transaction early so it will contain any row level locks
     if (!psDBTransaction(config->dbh)) {
@@ -463,15 +463,4 @@
     }
 
-#ifdef notdef
-    // we've changed to use -advance instead
-    if (!copydoneCompleteExp(config)) {
-        // rollback
-        if (!psDBRollback(config->dbh)) {
-            psError(PS_ERR_UNKNOWN, false, "database error");
-        }
-        psError(PS_ERR_UNKNOWN, false, "copydoneCompleteExp() failed");
-        return false;
-    }
-#endif
     // point of no return
     if (!psDBCommit(config->dbh)) {
@@ -487,21 +476,10 @@
 }
 
-static bool copydoneCompleteExp(pxConfig *config)
-{
-    // THIS FUNCTION MUST BE INVOKED FROM INSIDE A TRANSACTION!!!
-    
-    PS_ASSERT_PTR_NON_NULL(config, false);
-
-    // XXX this is an ugly hack!
-    // we are passing exp level info to a imfile level mode (-copydone)
-    // these options are thrown away unless we just -copydone'd the last imfile
-    // in an exp.  
- 
-    // optional
-    PXOPT_LOOKUP_STR(workdir, config->args, "-workdir", false, false);
-    PXOPT_LOOKUP_STR(dvodb, config->args, "-dvodb", false, false);
-    PXOPT_LOOKUP_STR(tess_id, config->args, "-tess_id", false, false);
-    PXOPT_LOOKUP_STR(end_stage, config->args, "-end_stage", false, false);
-    PXOPT_LOOKUP_STR(label, config->args, "-label", false, false);
+static bool toadvanceMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    // optional args
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
 
@@ -517,5 +495,6 @@
     PXOPT_COPY_STR(config->args, where,  "-exp_name", "exp_name", "==");
     PXOPT_COPY_STR(config->args, where,  "-inst", "camera", "==");
-    PXOPT_COPY_STR(config->args, where,  "-telescope", "telescope", "==");
+    PXOPT_COPY_STR(config->args, where,  "-inst", "camera", "==");
+    PXOPT_COPY_STR(config->args, where,  "-label", "label", "==");
 
     if (psListLength(where->list)) {
@@ -525,4 +504,5 @@
     }
     psFree(where);
+
 
     // treat limit == 0 as "no limit"
@@ -552,34 +532,54 @@
     }
 
-   for (long i = 0; i < psArrayLength(output); i++) {
-        psMetadata *row = output->data[i];
-
-        pzDownloadExpRow *doneExp = pzDownloadExpObjectFromMetadata(row);
-        if (!doneExp) {
-            psError(PS_ERR_UNKNOWN, false, "pzDownloadExpObjectFromMetadata() failed");
-            psFree(doneExp);
-            psFree(output);
-            return false;
-        }
-
-        if (!newExpInsert(config->dbh,
-                    0x0,                // exp_id
-                    doneExp->exp_name,  // tmp_exp_name
-                    doneExp->camera,    // tmp_camera
-                    doneExp->telescope, // tmp_telescope
-                    "run",              // state
-                    workdir,            // workdir
-                    "dirty",            // workdir state
-                    NULL,               // reduction class
-                    dvodb,              // dvodb
-                    tess_id,            // tess_id
-                    end_stage,          // end_stage
-                    label,
-                    NULL                // epoch
-                )
+    if (!ippdbPrintMetadatas(stdout, output, "toadvance", !simple)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print array");
+        psFree(output);
+        return false;
+    }
+
+    psFree(output);
+
+    return true;
+}
+
+static bool advanceMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    // required
+    PXOPT_LOOKUP_STR(exp_name, config->args, "-exp_name", true, false);
+    PXOPT_LOOKUP_STR(inst, config->args, "-inst", true, false);
+    PXOPT_LOOKUP_STR(telescope, config->args, "-telescope", true, false);
+    PXOPT_LOOKUP_STR(workdir, config->args, "-workdir", true, false);
+
+    // optional
+    PXOPT_LOOKUP_STR(dvodb, config->args, "-dvodb", false, false);
+    PXOPT_LOOKUP_STR(tess_id, config->args, "-tess_id", false, false);
+    PXOPT_LOOKUP_STR(end_stage, config->args, "-end_stage", false, false);
+    PXOPT_LOOKUP_STR(label, config->args, "-label", false, false);
+
+    // start a transaction so it's all rows or nothing
+    if (!psDBTransaction(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    if (!newExpInsert(config->dbh,
+            0x0,        // exp_id
+            exp_name,   // tmp_exp_name
+            inst,       // tmp_camera
+            telescope,  // tmp_telescope
+            "run",      // state
+            workdir,    // workdir
+            "dirty",    // workdir state
+            NULL,       // reduction class
+            dvodb,      // dvodb
+            tess_id,    // tess_id
+            end_stage,  // end_stage
+            label,      // label
+            NULL        // epoch
+            )
         ) {
             psError(PS_ERR_UNKNOWN, false, "database error");
-            psFree(doneExp);
-            psFree(output);
             return false;
         }
@@ -592,8 +592,8 @@
                 "INSERT INTO newImfile"
                 "   SElECT"
-                "       %" PRId64 "," // exp_id
+                "       %" PRId64 ","               // exp_id
                 "       pzDownloadImfile.class_id," // tmp_class_id
-                "       pzDownloadImfile.uri," // uri
-                "       NULL" // epoch
+                "       pzDownloadImfile.uri,"      // uri
+                "       NULL"                       // epoch
                 "   FROM pzDownloadImfile"
                 "   WHERE"
@@ -602,33 +602,33 @@
                 "       AND pzDownloadImfile.telescope = '%s'";
 
-            if (!p_psDBRunQueryF(config->dbh, query, exp_id, doneExp->exp_name, doneExp->camera, doneExp->telescope)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-                psFree(doneExp);
-                psFree(output);
-                return false;
-            } 
-
-            // sanity check: we should have inserted at least one row
-            psU64 affected = psDBAffectedRows(config->dbh);
-            if (psDBAffectedRows(config->dbh) < 1) {
-                psError(PS_ERR_UNKNOWN, false, "should have affected at least 1 row but %" PRIu64 " rows were modified", affected);
-                psFree(doneExp);
-                psFree(output);
-                return false;
-            }
-        }
-
-        // set pzDownloadExp.state to 'stop'
-        if (!pzDownloadExpSetState(config, doneExp->exp_name, doneExp->camera, doneExp->telescope, "stop")) {
-            psError(PS_ERR_UNKNOWN, false, "failed to change pzDownloadExp.state for %s:%s:%s", doneExp->exp_name, doneExp->camera, doneExp->telescope);
-            psFree(doneExp);
-            psFree(output);
+        if (!p_psDBRunQueryF(config->dbh, query, exp_id, exp_name, inst, telescope)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
             return false;
-        }
-
-        psFree(doneExp);
-    }
-
-    psFree(output);
+        } 
+
+        // sanity check: we should have inserted at least one row
+        psU64 affected = psDBAffectedRows(config->dbh);
+        if (psDBAffectedRows(config->dbh) < 1) {
+            psError(PS_ERR_UNKNOWN, false, "should have affected at least 1 row but %" PRIu64 " rows were modified", affected);
+            return false;
+        }
+    }
+
+    // set pzDownloadExp.state to 'stop'
+    if (!pzDownloadExpSetState(config, exp_name, inst, telescope, "stop")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to change pzDownloadExp.state for %s:%s:%s", exp_name, inst, telescope);
+        return false;
+    }
+
+    // point of no return
+    if (!psDBCommit(config->dbh)) {
+        // rollback
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+        }
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
 
     return true;
@@ -872,39 +872,4 @@
 }
 
-static bool advanceMode(pxConfig *config)
-{
-    PS_ASSERT_PTR_NON_NULL(config, false);
-
-    // NOTE : the command-line args are parsed in copydoneCompleteExp
-
-    // start a transaction so it's all rows or nothing
-    if (!psDBTransaction(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        return false;
-    }
-
-    if (!copydoneCompleteExp(config)) {
-        // rollback
-        if (!psDBRollback(config->dbh)) {
-            psError(PS_ERR_UNKNOWN, false, "database error");
-        }
-        psError(PS_ERR_UNKNOWN, false, "copydoneCompleteExp() failed");
-        return false;
-    }
-
-    // point of no return
-    if (!psDBCommit(config->dbh)) {
-        // rollback
-        if (!psDBRollback(config->dbh)) {
-            psError(PS_ERR_UNKNOWN, false, "database error");
-        }
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        return false;
-    }
-
-
-    return true;
-}
-
 
 static bool pzDownloadExpSetState(pxConfig *config, const char *exp_name, const char *camera, const char *telescope, const char *state)
