Index: trunk/ippTools/src/magicdstool.c
===================================================================
--- trunk/ippTools/src/magicdstool.c	(revision 29358)
+++ trunk/ippTools/src/magicdstool.c	(revision 29561)
@@ -39,4 +39,5 @@
 static bool advancerunMode(pxConfig *config);
 static bool revertdestreakedfileMode(pxConfig *config);
+static bool updatedestreakedfileMode(pxConfig *config);
 static bool clearstatefaultsMode(pxConfig *config);
 static bool getskycellsMode(pxConfig *config);
@@ -45,4 +46,7 @@
 static bool completedrevertMode(pxConfig *config);
 static bool tocleanupMode(pxConfig *config);
+static bool tofullfileMode(pxConfig *config);
+static bool tocleanedfileMode(pxConfig *config);
+static bool setfiletoupdateMode(pxConfig *config);
 
 static bool setmagicDSRunState(pxConfig *config, psS64 magic_id, psString extraSetString, psMetadata *where, const char *state);
@@ -73,4 +77,5 @@
         MODECASE(MAGICDSTOOL_MODE_ADVANCERUN,          advancerunMode);
         MODECASE(MAGICDSTOOL_MODE_REVERTDESTREAKEDFILE,revertdestreakedfileMode);
+        MODECASE(MAGICDSTOOL_MODE_UPDATEDESTREAKEDFILE,updatedestreakedfileMode);
         MODECASE(MAGICDSTOOL_MODE_CLEARSTATEFAULTS,    clearstatefaultsMode);
         MODECASE(MAGICDSTOOL_MODE_GETSKYCELLS,         getskycellsMode);
@@ -79,4 +84,7 @@
         MODECASE(MAGICDSTOOL_MODE_COMPLETEDREVERT,     completedrevertMode);
         MODECASE(MAGICDSTOOL_MODE_TOCLEANUP,           tocleanupMode);
+        MODECASE(MAGICDSTOOL_MODE_TOFULLFILE,          tofullfileMode);
+        MODECASE(MAGICDSTOOL_MODE_TOCLEANEDFILE,       tocleanedfileMode);
+        MODECASE(MAGICDSTOOL_MODE_SETFILETOUPDATE,     setfiletoupdateMode);
         default:
             psAbort("invalid option (this should not happen)");
@@ -558,4 +566,9 @@
     PXOPT_LOOKUP_STR(state, config->args, "-set_state", true, false);
 
+    if (!strcmp(state, "update")) {
+        fprintf(stderr, "'-updaterun -set_state update' is not supported. Use -setfiletoupdate");
+        return false;
+    }
+
     // optional
     PXOPT_LOOKUP_STR(set_label, config->args, "-set_label", false, false);
@@ -907,4 +920,71 @@
         return false;
     }
+
+    return true;
+}
+static bool updatedestreakedfileMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    // required values
+    PXOPT_LOOKUP_S64(magic_ds_id, config->args, "-magic_ds_id", true, false);
+    PXOPT_LOOKUP_STR(component, config->args, "-component", true, false);
+
+    // default values
+    PXOPT_LOOKUP_S16(fault, config->args, "-fault", false, false);
+    PXOPT_LOOKUP_STR(backup_path_base, config->args, "-backup_path_base", false, false);
+    PXOPT_LOOKUP_STR(recovery_path_base, config->args, "-recovery_path_base", false, false);
+    PXOPT_LOOKUP_STR(data_state, config->args, "-data_state", false, false);
+    PXOPT_LOOKUP_F32(streak_frac, config->args, "-streak_frac", false, false);
+    PXOPT_LOOKUP_F32(nondiff_frac, config->args, "-nondiff_frac", false, false);
+    PXOPT_LOOKUP_F32(run_time, config->args, "-run_time", false, false);
+
+    psString query = psStringCopy("UPDATE magicDSFile");
+
+
+    char *initial_separator = " SET";
+    char *sep = initial_separator;
+    if (fault) {
+        psStringAppend(&query, "%s fault = %d", sep, fault);
+        sep = ", ";
+    }
+    if (backup_path_base) {
+        psStringAppend(&query, "%s backup_path_base = '%s'", sep, backup_path_base);
+        sep = ", ";
+    }
+    if (recovery_path_base) {
+        psStringAppend(&query, "%s recovery_path_base = '%s'", sep, recovery_path_base);
+        sep = ", ";
+    }
+    if (data_state) {
+        psStringAppend(&query, "%s data_state = '%s'", sep, data_state);
+        sep = ", ";
+    }
+    if (streak_frac) {
+        psStringAppend(&query, "%s streak_frac = '%f'", sep, streak_frac);
+        sep = ", ";
+    }
+    if (nondiff_frac) {
+        psStringAppend(&query, "%s nondiff_frac = '%f'", sep, nondiff_frac);
+        sep = ", ";
+    }
+    if (run_time) {
+        psStringAppend(&query, "%s run_time = '%f'", sep, run_time);
+        sep = ", ";
+    }
+    if (sep == initial_separator) {
+        psFree(query);
+        psError(PS_ERR_UNKNOWN, true, "must set at least one value");
+        return false;
+    }
+
+    psStringAppend(&query, "\nWHERE magic_ds_id = %" PRId64 " AND component = '%s'\n", magic_ds_id, component);
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
 
     return true;
@@ -1019,8 +1099,28 @@
     PXOPT_COPY_S64(config->args, where, "-magic_ds_id", "magicDSRun.magic_ds_id", "==");
     PXOPT_COPY_STR(config->args, where, "-component", "component", "==");
+    PXOPT_COPY_STR(config->args, where, "-state", "state", "==");
     PXOPT_COPY_S16(config->args, where, "-fault", "fault", "==");
     pxAddLabelSearchArgs (config, where, "-label", "label", "==");
 
-    psString query = pxDataGet("magicdstool_revertdestreakedfile.sql");
+    PXOPT_LOOKUP_STR(state, config->args, "-state", false, false);
+
+    psString queryFile = NULL;
+    if (state) {
+        if (! strcmp(state, "new") ) {
+            queryFile = "magicdstool_revertdestreakedfile.sql";
+        } else if (!strcmp(state, "update")) {
+            queryFile = "magicdstool_revertupdated.sql";
+        } else {
+            psError(PXTOOLS_ERR_SYS, true, "%s is not a valid value for state", state);
+            return false;
+        }
+    } else {
+        queryFile = "magicdstool_revertdestreakedfile.sql";
+    }
+    psString query = pxDataGet(queryFile);
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
 
     if (psListLength(where->list)) {
@@ -1241,4 +1341,5 @@
           (strcmp(state, "censored") == 0) ||
           (strcmp(state, "cleaned") == 0) ||
+          (strcmp(state, "update") == 0) ||
           (strcmp(state, "goto_restored") == 0) ||
           (strcmp(state, "goto_censored") == 0) ||
@@ -1520,2 +1621,125 @@
     return true;
 }
+
+// update magicDSFile.data_state to given value.
+// afterwards, if all files in the magicDSRun have the new state, 
+// update the state for it as well
+// shared code for the modes -tocleanedfile -tofullfile
+
+static bool change_file_data_state(pxConfig *config, psString data_state)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    // magic_id, component
+    PXOPT_LOOKUP_S64(magic_ds_id, config->args, "-magic_ds_id", true, false);
+    PXOPT_LOOKUP_STR(component, config->args, "-component", true, false);
+
+    psString query = pxDataGet("magicdstool_change_file_data_state.sql");
+
+    if (!psDBTransaction(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+    if (!strcmp(data_state, "full")) {
+        // if -tofullfile optoinally set the magicked value for the component
+        PXOPT_LOOKUP_BOOL(setmagicked, config->args, "-setmagicked", false);
+        // set the image file's magicked flag
+        if (!setMagicked(config, magic_ds_id, component)) {
+            psError(PS_ERR_UNKNOWN, false, "setMagicked failed");
+            if (!psDBRollback(config->dbh)) {
+                psError(PS_ERR_UNKNOWN, false, "database error");
+            }
+            return false;
+        }
+    }
+
+    if (!p_psDBRunQueryF(config->dbh, query, data_state, magic_ds_id, component)) {
+        psFree(query);
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        // rollback
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+        }
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+    psFree(query);
+    if (psDBAffectedRows(config->dbh) < 1) {
+        psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row");
+        return false;
+    }
+
+    query = pxDataGet("magicdstool_change_run_state.sql");
+    if (!p_psDBRunQueryF(config->dbh, query, data_state, magic_ds_id, data_state)) {
+        psFree(query);
+        // rollback
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+        }
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+    psFree(query);
+
+    if (!psDBCommit(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    return true;
+}
+static bool tocleanedfileMode(pxConfig *config)
+{
+    return change_file_data_state(config, "cleaned");
+}
+static bool tofullfileMode(pxConfig *config)
+{
+    return change_file_data_state(config, "full");
+}
+/*
+static bool topurgedimfileMode(pxConfig *config)
+{
+    return change_imfile_data_state(config, "purged", "goto_purged");
+}
+static bool toscrubbedfileMode(pxConfig *config)
+{
+  return change_file_data_state(config, "scrubbed", "goto_scrubbed");
+}
+*/
+
+// a very specfic function to queue a cleaned magicDSFile to be updated
+static bool setfiletoupdateMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+
+    PXOPT_LOOKUP_S64(magic_ds_id, config->args, "-magic_ds_id", true, false);
+    PXOPT_LOOKUP_STR(component, config->args, "-component", false, false);
+    PXOPT_LOOKUP_STR(label, config->args, "-set_label", false, false);
+
+    psString query = pxDataGet("magicdstool_setfiletoupdate.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    psString setHook = psStringCopy("");
+    if (label) {
+        psStringAppend(&setHook, "\n , magicDSRun.label = '%s'", label);
+    }
+
+    if (component) {
+        psStringAppend(&query, " AND (magicDSFile.component = '%s')", component);
+    }
+
+    if (!p_psDBRunQueryF(config->dbh, query, setHook, magic_ds_id)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    psFree(setHook);
+    psFree(query);
+
+    return true;
+}
+
+
