Index: trunk/ippTools/src/addtool.c
===================================================================
--- trunk/ippTools/src/addtool.c	(revision 26911)
+++ trunk/ippTools/src/addtool.c	(revision 26915)
@@ -99,4 +99,5 @@
     PXOPT_COPY_S64(config->args, where,  "-cam_id",    "camRun.cam_id", "==");
     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", "==");
 
@@ -119,10 +120,26 @@
 
     // find the cam_id of all the exposures that we want to queue up.
-    psString query = pxDataGet("addtool_find_cam_id.sql");
-    if (!query) {
+    psString bare_query = pxDataGet("addtool_find_cam_id.sql");
+    if (!bare_query) {
         psError(PXTOOLS_ERR_DATA, 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,4 +148,7 @@
         psStringAppend(&query, " AND %s", whereClause);
         psFree(whereClause);
+    } else {
+        psError(PS_ERR_UNKNOWN, true, "search parameters are required");
+        return false;
     }
     psFree(where);
