Index: branches/tap_branches/ippTools/src/addtool.c
===================================================================
--- branches/tap_branches/ippTools/src/addtool.c	(revision 25900)
+++ branches/tap_branches/ippTools/src/addtool.c	(revision 27838)
@@ -98,11 +98,11 @@
     pxcamGetSearchArgs (config, where);
     PXOPT_COPY_S64(config->args, where,  "-cam_id",    "camRun.cam_id", "==");
-    pxAddLabelSearchArgs (config, where, "-label",     "camRun.label", "==");
+    pxAddLabelSearchArgs (config, where, "-label",     "camRun.label", "=="); // define using camRun label
+    pxAddLabelSearchArgs (config, where, "-data_group","camRun.data_group", "=="); // define using camRun label
     PXOPT_COPY_STR(config->args, where,  "-reduction", "camRun.reduction", "==");
 
-    if (!psListLength(where->list) &&
-        !psMetadataLookupBool(NULL, config->args, "-all")) {
+    if (!psListLength(where->list)) {
         psFree(where);
-        psError(PXTOOLS_ERR_DATA, false, "search parameters are required");
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
         return false;
     }
@@ -115,14 +115,31 @@
     PXOPT_LOOKUP_STR(note,        config->args, "-set_note", false, false);
     PXOPT_LOOKUP_BOOL(image_only, config->args, "-image_only", false);
+    PXOPT_LOOKUP_BOOL(destreaked, config->args, "-destreaked", false);
     PXOPT_LOOKUP_BOOL(pretend,    config->args, "-pretend", false);
     PXOPT_LOOKUP_BOOL(simple,     config->args, "-simple", false);
 
     // find the cam_id of all the exposures that we want to queue up.
-    psString query = pxDataGet("addtool_find_cam_id.sql");
-    if (!query) {
-        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+    psString bare_query = pxDataGet("addtool_find_cam_id.sql");
+    if (!bare_query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
         psFree(where);
         return false;
     }
+
+    // prevent queueing an addRun if a given exposure has already been added to
+    // the given dvo database
+    psString dvodb_string = NULL;
+    if (dvodb) {
+        // user supplied dvodb
+        psStringAppend(&dvodb_string, "(previous_dvodb = '%s')", dvodb);
+    } else {
+        // inherit dvodb from camRun, avoid matching NULL
+        psStringAppend(&dvodb_string, "(camRun.dvodb IS NOT NULL AND previous_dvodb = camRun.dvodb)");
+    }
+    // Take the bare query and add the dvodb selector
+    psString query = NULL;
+    psStringAppend(&query, bare_query, dvodb_string);
+    psFree(dvodb_string);
+    psFree(bare_query);
 
     // use psDBGenerateWhereConditionSQL because the SQL ends in a WHERE
@@ -131,6 +148,13 @@
         psStringAppend(&query, " AND %s", whereClause);
         psFree(whereClause);
+    } else {
+        psError(PS_ERR_UNKNOWN, true, "search parameters are required");
+        return false;
     }
     psFree(where);
+
+    if (destreaked) {
+        psStringAppend(&query, " AND (camRun.magicked > 0)");
+    }
 
     if (!p_psDBRunQuery(config->dbh, query)) {
@@ -214,12 +238,12 @@
         // queue the exp
         if (!pxaddQueueByCamID(config,
-			       row->cam_id,
-			       workdir     ? workdir   : row->workdir,
-			       reduction   ? reduction : row->reduction,
-			       label       ? label     : row->label,
-			       data_group  ? data_group : (label ? label : row->label),
-			       dvodb       ? dvodb     : row->dvodb,
+                               row->cam_id,
+                               workdir     ? workdir   : row->workdir,
+                               reduction   ? reduction : row->reduction,
+                               label       ? label     : row->label,
+                               data_group  ? data_group : (row->data_group ? row->data_group :  (label ? label : row->label)),
+                               dvodb       ? dvodb     : row->dvodb,
                                note        ? note      : NULL,
-			       image_only
+                               image_only
         )) {
             if (!psDBRollback(config->dbh)) {
@@ -256,8 +280,9 @@
     PXOPT_COPY_STR(config->args, where, "-state",     "addRun.state", "==");
     PXOPT_COPY_STR(config->args, where, "-reduction", "addRun.reduction", "==");
+    PXOPT_COPY_STR(config->args, where, "-dvodb", "addRun.dvodb", "==");
 
     if (!psListLength(where->list)) {
         psFree(where);
-        psError(PXTOOLS_ERR_DATA, false, "search parameters are required");
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
         return false;
     }
@@ -266,5 +291,6 @@
 
     // pxUpdateRun gets parameters from config->args and runs the update query
-    bool result = pxUpdateRun(config, where, &query, "addRun", false);
+    bool result = pxUpdateRun(config, where, &query, "addRun", "add_id", 
+        "addProcessedExp", false);
 
     psFree(query);
@@ -272,36 +298,4 @@
 
     return result;
-
-
-#ifdef notdef
-    PXOPT_LOOKUP_STR(state, config->args, "-set_state", false, false);
-    PXOPT_LOOKUP_STR(label, config->args, "-set_label", false, false);
-
-    if ((!state) && (!label)) {
-        psError(PXTOOLS_ERR_DATA, false, "parameters are required");
-        psFree(where);
-        return false;
-    }
-
-    if (state) {
-        // set addRun.state to state
-        if (!pxaddRunSetStateByQuery(config, where, state)) {
-            psFree(where);
-            return false;
-        }
-    }
-
-    if (label) {
-        // set addRun.label to label
-        if (!pxaddRunSetLabelByQuery(config, where, label)) {
-            psFree(where);
-            return false;
-        }
-    }
-
-    psFree(where);
-
-    return true;
-#endif
 }
 
@@ -322,5 +316,5 @@
     psString query = pxDataGet("addtool_find_pendingexp.sql");
     if (!query) {
-        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
         return false;
     }
@@ -388,5 +382,5 @@
     psString query = pxDataGet("addtool_find_pendingexp.sql");
     if (!query) {
-        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
         return false;
     }
@@ -430,5 +424,5 @@
         dtime_addstar,
         path_base,
-	fault
+        fault
         );
 
@@ -482,5 +476,5 @@
         !psMetadataLookupBool(NULL, config->args, "-all")) {
         psFree(where);
-        psError(PXTOOLS_ERR_DATA, false, "search parameters (or -all) are required");
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters (or -all) are required");
         return false;
     }
@@ -488,5 +482,5 @@
     psString query = pxDataGet("addtool_find_processedexp.sql");
     if (!query) {
-        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
         return false;
     }
@@ -496,5 +490,5 @@
         psStringAppend(&query, " WHERE %s", whereClause);
         psFree(whereClause);
-    } 
+    }
 
     // we either add AND (condition) or WHERE (condition):
@@ -502,5 +496,5 @@
         // list only faulted rows
         psStringAppend(&query, " %s", " AND addProcessedExp.fault != 0");
-    } 
+    }
     if (where->list && !faulted) {
         // don't list faulted rows
@@ -510,5 +504,5 @@
         // list only faulted rows
         psStringAppend(&query, " %s", " WHERE addProcessedExp.fault != 0");
-    } 
+    }
     if (!where->list && !faulted) {
         // don't list faulted rows
@@ -571,5 +565,5 @@
     if (!psListLength(where->list) && !psMetadataLookupBool(NULL, config->args, "-all")) {
         psFree(where);
-        psError(PXTOOLS_ERR_DATA, false, "search parameters are required");
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
         return false;
     }
@@ -584,5 +578,5 @@
         psString query = pxDataGet("addtool_reset_faulted_runs.sql");
         if (!query) {
-            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+            psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
             psFree(where);
             return false;
@@ -616,5 +610,5 @@
                 psError(PS_ERR_UNKNOWN, false, "database error");
             }
-            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+            psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
             psFree(where);
             return false;
