Index: branches/pap/ippTools/src/pstamptool.c
===================================================================
--- branches/pap/ippTools/src/pstamptool.c	(revision 27708)
+++ branches/pap/ippTools/src/pstamptool.c	(revision 28003)
@@ -40,4 +40,5 @@
 static bool updatereqMode(pxConfig *config);
 static bool revertreqMode(pxConfig *config);
+static bool pendingcleanupMode(pxConfig *config);
 static bool addjobMode(pxConfig *config);
 static bool listjobMode(pxConfig *config);
@@ -51,4 +52,5 @@
 static bool pendingdependentMode(pxConfig *config);
 static bool updatedependentMode(pxConfig *config);
+static bool revertdependentMode(pxConfig *config);
 
 # define MODECASE(caseName, func) \
@@ -80,4 +82,5 @@
         MODECASE(PSTAMPTOOL_MODE_UPDATEREQ, updatereqMode);
         MODECASE(PSTAMPTOOL_MODE_REVERTREQ, revertreqMode);
+        MODECASE(PSTAMPTOOL_MODE_PENDINGCLEANUP, pendingcleanupMode);
         MODECASE(PSTAMPTOOL_MODE_ADDJOB, addjobMode);
         MODECASE(PSTAMPTOOL_MODE_LISTJOB, listjobMode);
@@ -91,4 +94,5 @@
         MODECASE(PSTAMPTOOL_MODE_PENDINGDEPENDENT, pendingdependentMode);
         MODECASE(PSTAMPTOOL_MODE_UPDATEDEPENDENT, updatedependentMode);
+        MODECASE(PSTAMPTOOL_MODE_REVERTDEPENDENT, revertdependentMode);
         default:
             psAbort("invalid option (this should not happen)");
@@ -263,4 +267,5 @@
         NULL,   // outProduct
         uri,
+        NULL,   // outdir
         0       // fault
         )) {
@@ -299,4 +304,6 @@
     }
     psFree(where);
+
+    psStringAppend(&query, " ORDER BY priority DESC, req_id");
 
     // treat limit == 0 as "no limit"
@@ -337,5 +344,5 @@
 }
 
-static bool listreqMode(pxConfig *config)
+static bool pendingcleanupMode(pxConfig *config)
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
@@ -343,21 +350,23 @@
     psMetadata *where = psMetadataAlloc();
     PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
-    PXOPT_COPY_S64(config->args, where, "-not_req_id", "req_id", "!=");
-    PXOPT_COPY_STR(config->args, where, "-name", "name", "==");
-
-    PXOPT_LOOKUP_U64(limit,   config->args, "-limit",  false, false);
+    pxAddLabelSearchArgs(config, where, "-label", "label", "LIKE");
+
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
 
-    if (!psListLength(where->list)) {
-        psError(PS_ERR_UNKNOWN, true, "-req_id or -name must be supplied");
-        return false;
-    }
-
-    psString query = psStringCopy("SELECT * from pstampRequest");
-
-    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-    psStringAppend(&query, " WHERE %s", whereClause);
-    psFree(whereClause);
-    psFree(where);
+    psString query = pxDataGet("pstamptool_pendingcleanup.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, "pstampRequest");
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    }
+    psFree(where);
+
+    psStringAppend(&query, " ORDER BY priority DESC, req_id");
 
     // treat limit == 0 as "no limit"
@@ -381,10 +390,7 @@
     }
     if (!psArrayLength(output)) {
-        psTrace("pstamptool", PS_LOG_INFO, "request not found");
-        // This causes main to exit with PS_EXIT_DATA_ERROR which the script is looking for
-        psError(PXTOOLS_ERR_CONFIG, true, "request not found");
-        psFree(output);
-        // we return false so that the caller can determine that a request does not exist
-        return false;
+        psTrace("pstamptool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
     }
 
@@ -401,21 +407,26 @@
 }
 
-static bool completedreqMode(pxConfig *config)
-{
-    PS_ASSERT_PTR_NON_NULL(config, false);
-
-    psMetadata *where = psMetadataAlloc();
-    pxAddLabelSearchArgs(config, where, "-label", "label", "LIKE");
-
-    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+static bool listreqMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-not_req_id", "req_id", "!=");
+    PXOPT_COPY_STR(config->args, where, "-name", "name", "==");
+
+    PXOPT_LOOKUP_U64(limit,   config->args, "-limit",  false, false);
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
 
-    psString query = pxDataGet("pstamptool_completedreq.sql");
-
-    if (psListLength(where->list)) {
-        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-        psStringAppend(&query, " AND %s", whereClause);
-        psFree(whereClause);
-    }
+    if (!psListLength(where->list)) {
+        psError(PS_ERR_UNKNOWN, true, "-req_id or -name must be supplied");
+        return false;
+    }
+
+    psString query = psStringCopy("SELECT * from pstampRequest");
+
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringAppend(&query, " WHERE %s", whereClause);
+    psFree(whereClause);
     psFree(where);
 
@@ -432,4 +443,5 @@
         return false;
     }
+    psFree(query);
 
     psArray *output = p_psDBFetchResult(config->dbh);
@@ -438,9 +450,11 @@
         return false;
     }
-
     if (!psArrayLength(output)) {
-        psTrace("pstamptool", PS_LOG_INFO, "no rows found");
-        psFree(output);
-        return true;
+        psTrace("pstamptool", PS_LOG_INFO, "request not found");
+        // This causes main to exit with PS_EXIT_DATA_ERROR which the script is looking for
+        psError(PXTOOLS_ERR_CONFIG, true, "request not found");
+        psFree(output);
+        // we return false so that the caller can determine that a request does not exist
+        return false;
     }
 
@@ -457,23 +471,103 @@
 }
 
+static bool completedreqMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    pxAddLabelSearchArgs(config, where, "-label", "label", "LIKE");
+
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+
+    psString query = pxDataGet("pstamptool_completedreq.sql");
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    }
+    psFree(where);
+
+    psStringAppend(&query, " ORDER BY priority DESC, req_id");
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    if (!psArrayLength(output)) {
+        psTrace("pstamptool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    // negative simple so the default is true
+    if (!ippdbPrintMetadatas(stdout, output, "pstampRequest", !simple)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print array");
+        psFree(output);
+        return false;
+    }
+
+    psFree(output);
+
+    return true;
+}
+
 static bool updatereqMode(pxConfig *config)
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    PXOPT_LOOKUP_S64(req_id,     config->args, "-req_id",     true, false);
-    PXOPT_LOOKUP_STR(state,      config->args, "-state",      false, false);
-    PXOPT_LOOKUP_STR(outProduct, config->args, "-outProduct", false, false);
-    PXOPT_LOOKUP_STR(fault,      config->args, "-fault",      false, false);
-    PXOPT_LOOKUP_STR(uri,        config->args, "-uri",        false, false);
-    PXOPT_LOOKUP_STR(name,       config->args, "-name",       false, false);
-    PXOPT_LOOKUP_STR(reqType,    config->args, "-reqType",    false, false);
-
-    psString query = NULL;
-    psStringAppend(&query, "UPDATE pstampRequest SET");
-
+    // PXOPT_LOOKUP_S64(req_id,     config->args, "-req_id",   true, false);
+    PXOPT_LOOKUP_STR(state,      config->args, "-set_state",      false, false);
+    PXOPT_LOOKUP_STR(label,      config->args, "-set_label",      false, false);
+    PXOPT_LOOKUP_STR(outProduct, config->args, "-set_outProduct", false, false);
+    PXOPT_LOOKUP_S16(fault,      config->args, "-set_fault",          false, false);
+    PXOPT_LOOKUP_STR(uri,        config->args, "-set_uri",        false, false);
+    PXOPT_LOOKUP_STR(outdir,     config->args, "-set_outdir",        false, false);
+    PXOPT_LOOKUP_STR(name,       config->args, "-set_name",       false, false);
+    PXOPT_LOOKUP_STR(reqType,    config->args, "-set_reqType",    false, false);
+    PXOPT_LOOKUP_BOOL(clearfault,config->args, "-clearfault",    false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-req_id",     "req_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-req_id_max", "req_id", "<=");
+    PXOPT_COPY_S32(config->args, where, "-fault",      "fault", "==");
+    PXOPT_COPY_STR(config->args, where, "-state",      "state", "==");
+    pxAddLabelSearchArgs(config, where, "-label",      "pstampRequest.label", "LIKE");
+    if (!psListLength(where->list)) {
+        psFree(where);
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+        return false;
+    }
+
+    psString query = psStringCopy("UPDATE pstampRequest SET");
+
+    psString stateCheck = NULL;
     char c = ' ';
     if (state) {
         psStringAppend(&query, "%c state = '%s'", c, state);
         c = ',';
+        if (!strcmp(state, "goto_cleaned")) {
+            psStringAppend(&stateCheck, " AND state != 'cleaned'");
+        }
+    }
+    if (label) {
+        psStringAppend(&query, "%c label = '%s'", c, label);
+        c = ',';
     }
     if (outProduct) {
@@ -481,6 +575,17 @@
         c = ',';
     }
-    if (fault) {
-        psStringAppend(&query, "%c fault = %s", c, fault);
+    if (outdir) {
+        psStringAppend(&query, "%c outdir = '%s'", c, outdir);
+        c = ',';
+    }
+    if (clearfault) {
+        if (fault) {
+            psError(PXTOOLS_ERR_CONFIG, true, "only one of -fault and -clearfault is allowed");
+            return false;
+        }
+        psStringAppend(&query, "%c fault = 0", c);
+        c = ',';
+    } else if (fault) {
+        psStringAppend(&query, "%c fault = %d", c, fault);
         c = ',';
     }
@@ -497,10 +602,17 @@
         c = ',';
     }
-    if (!state && !outProduct && !fault && !uri && !name && !reqType) {
-        psError(PS_ERR_UNKNOWN, true, "at least one of state, outProduct, fault, uri, name, and reqType must be specified");
-        return false;
-    }
-
-    psStringAppend(&query, " WHERE req_id = %" PRId64, req_id);
+    if (c != ',') {
+        psError(PS_ERR_UNKNOWN, true, "at least one set option is required");
+        return false;
+    }
+
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringAppend(&query, "\nWHERE %s", whereClause);
+    psFree(whereClause);
+    psFree(where);
+
+    if (stateCheck) {
+        psStringAppend(&query, "%s", stateCheck);
+    }
 
     if (!p_psDBRunQuery(config->dbh, query)) {
@@ -510,11 +622,6 @@
     }
 
-    psU64 affected = psDBAffectedRows(config->dbh);
-    // note zero is not an error
-    if (affected > 1) {
-        psError(PS_ERR_UNKNOWN, false, "should have affected one row but %"
-                                        PRIu64 " rows were modified", affected);
-        return false;
-    }
+    // psU64 affected = psDBAffectedRows(config->dbh);
+    // psLogMsg("pstamptool", PS_LOG_INFO, "Updated %" PRIu64 " pstampRequests", affected);
 
     return true;
@@ -528,5 +635,5 @@
 
     PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
-    PXOPT_COPY_S64(config->args, where, "-fault", "req_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-fault", "fault", "==");
     PXOPT_COPY_STR(config->args, where, "-state", "pstampRequest.state", "==");
     pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "LIKE");
@@ -703,5 +810,5 @@
     PXOPT_COPY_S64(config->args, where, "-job_id", "job_id", "==");
     PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
-    pxAddLabelSearchArgs(config, where, "-label", "label", "LIKE");
+    pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "LIKE");
 
     PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
@@ -722,4 +829,6 @@
     psFree(where);
 
+    psStringAppend(&query, " ORDER BY priority DESC, req_id");
+
     // treat limit == 0 as "no limit"
     if (limit) {
@@ -763,32 +872,51 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    PXOPT_LOOKUP_S64(job_id,    config->args, "-job_id", true, false);
-    PXOPT_LOOKUP_STR(state,     config->args, "-state",  true, false);
-    PXOPT_LOOKUP_STR(fault,     config->args, "-fault",  false, false);
-
-    psString faultStr = NULL;
-    if (!fault) {
-        faultStr = psStringCopy("");
-    } else {
-        psStringAppend(&faultStr, ", fault = '%s'", fault);
-    }
-
-    char *query ="UPDATE pstampJob"
-        " SET state = '%s' %s"
-        " WHERE job_id = %" PRId64;
-
-    if (!p_psDBRunQueryF(config->dbh, query, state, faultStr, job_id)) {
+    PXOPT_LOOKUP_S64(job_id,    config->args, "-job_id", false, false);
+    PXOPT_LOOKUP_S64(dep_id,    config->args, "-dep_id", false, false);
+
+    if (!job_id && !dep_id) {
+        psError(PS_ERR_UNKNOWN, true, "at least -job_id or -dep_id is required");
+        return false;
+    }
+
+    PXOPT_LOOKUP_STR(state,     config->args, "-set_state",  false, false);
+    PXOPT_LOOKUP_S32(fault,     config->args, "-set_fault",  false, false);
+    
+    if (!state && !fault) {
+        psError(PS_ERR_UNKNOWN, true, "at least one of -set_state and -set_fault is required");
+        return false;
+    }
+
+    psMetadata *where = psMetadataAlloc();
+
+    PXOPT_COPY_S64(config->args, where, "-job_id", "job_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-dep_id", "dep_id", "==");
+
+    psString query = pxDataGet("pstamptool_updatejob.sql");
+
+    char c = ' ';
+    if (state) {
+        psStringAppend(&query, "\n %c pstampJob.state = '%s'", c, state);
+        c = ',';
+    }
+    if (fault) {
+        psStringAppend(&query, "\n %c pstampJob.fault = %d", c, fault);
+        c = ',';
+    }
+    
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringAppend(&query, " WHERE %s", whereClause);
+    psFree(whereClause);
+    psFree(where);
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
         psError(PS_ERR_UNKNOWN, false, "database error");
         psFree(query);
         return false;
     }
-    psFree(faultStr);
+    psFree(query);
 
     psU64 affected = psDBAffectedRows(config->dbh);
-    if (affected != 1) {
-        psError(PS_ERR_UNKNOWN, false, "should have affected one row but %"
-                                        PRIu64 " rows were modified", affected);
-        return false;
-    }
+    psLogMsg("pstamptool", PS_LOG_INFO, "Updated %" PRIu64 " pstampJobs", affected);
 
     return true;
@@ -952,7 +1080,9 @@
     PXOPT_LOOKUP_STR(stage,       config->args, "-stage",   true, false);
     PXOPT_LOOKUP_S64(stage_id,    config->args, "-stage_id", true, false);
+    PXOPT_LOOKUP_STR(component,   config->args, "-component",  true, false);
     PXOPT_LOOKUP_STR(imagedb,     config->args, "-imagedb",  true, false);
-    PXOPT_LOOKUP_STR(rlabel,      config->args, "-rlabel",  false, false);
-    PXOPT_LOOKUP_BOOL(no_magic,   config->args, "-no_magic", false);
+    PXOPT_LOOKUP_STR(rlabel,      config->args, "-rlabel",  true, false);
+    PXOPT_LOOKUP_STR(outdir,      config->args, "-outdir",  true, false);
+    PXOPT_LOOKUP_BOOL(need_magic, config->args, "-need_magic", false);
     PXOPT_LOOKUP_BOOL(no_create,  config->args, "-no_create", false);
 
@@ -961,4 +1091,5 @@
     PXOPT_COPY_STR(config->args, where, "-imagedb", "imagedb", "==");
     PXOPT_COPY_S64(config->args, where, "-stage_id", "stage_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-component", "component", "==");
 
     // start a transaction eraly so it will contain any row level locks
@@ -968,15 +1099,15 @@
     }
 
-    psString query = pxDataGet("pstamptool_pendingdependent.sql");
+    psString query = pxDataGet("pstamptool_getdependent.sql");
     if (!query) {
         psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
         return false;
     }
-    psString whereClause = psDBGenerateWhereSQL(where, "WHERE");
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     if (!no_create) {
         // This will lock the row until the transaction is committed
-        psStringAppend(&query, " %s FOR UPDATE", whereClause);
+        psStringAppend(&query, " AND %s FOR UPDATE", whereClause);
     } else {
-        psStringAppend(&query, " %s", whereClause);
+        psStringAppend(&query, " AND %s", whereClause);
     }
     psFree(whereClause);
@@ -1027,7 +1158,10 @@
         stage,
         stage_id,
+        component,
         imagedb,
         rlabel,
-        no_magic
+        need_magic,
+        outdir,
+        0               // fault
         )) {
         if (!psDBRollback(config->dbh)) {
@@ -1038,4 +1172,14 @@
     }
 
+    // if we try and get this after commit zero is returned
+    psS64 dep_id = psDBLastInsertID(config->dbh);
+    if (!dep_id) {
+        psError(PS_ERR_UNKNOWN, false, "psDBLastInsertID returned NULL");
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+        }
+        return false;
+    }
+
     if (!psDBCommit(config->dbh)) {
         // rollback
@@ -1047,5 +1191,4 @@
     }
 
-    psS64 dep_id = psDBLastInsertID(config->dbh);
     printf("%" PRId64 "\n", dep_id);
 
@@ -1058,4 +1201,10 @@
 
     psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_STR(config->args, where, "-stage", "stage", "==");
+    PXOPT_COPY_STR(config->args, where, "-imagedb", "imagedb", "==");
+    PXOPT_COPY_S64(config->args, where, "-stage_id", "stage_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-dep_id", "dep_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-rlabel", "rlabel", "==");
+    pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "==");
 
     PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
@@ -1069,9 +1218,11 @@
 
     if (psListLength(where->list)) {
-        psString whereClause = psDBGenerateWhereConditionSQL(where, "pstampDependent");
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
         psStringAppend(&query, " AND %s", whereClause);
         psFree(whereClause);
     }
     psFree(where);
+
+    psStringAppend(&query, " ORDER BY priority DESC, req_id");
 
     // treat limit == 0 as "no limit"
@@ -1116,11 +1267,24 @@
 
     PXOPT_LOOKUP_S64(dep_id,    config->args, "-dep_id", true, false);
-    PXOPT_LOOKUP_STR(state,     config->args, "-set_state",  true, false);
-
-    char *query ="UPDATE pstampDependent"
-        " SET state = '%s'"
-        " WHERE dep_id = %" PRId64;
-
-    if (!p_psDBRunQueryF(config->dbh, query, state, dep_id)) {
+    PXOPT_LOOKUP_STR(state,     config->args, "-set_state",  false, false);
+    PXOPT_LOOKUP_S16(fault,     config->args, "-set_fault",  false, false);
+
+    if (!fault && !state) {
+        psError(PS_ERR_UNKNOWN, true, "at least one of -set_state or fault is required");
+        return false;
+    }
+    psString query = psStringCopy("UPDATE pstampDependent SET");
+    bool needComma = false;
+    if (state) {
+        psStringAppend(&query, " state = '%s'", state);
+        needComma = true;
+    }
+    if (fault) {
+        psStringAppend(&query, "%s fault = %d", needComma ? ", " : "", fault);
+        needComma = true;
+    }
+    psStringAppend(&query, " WHERE dep_id = %" PRId64, dep_id);
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
         psError(PS_ERR_UNKNOWN, false, "database error");
         psFree(query);
@@ -1137,2 +1301,35 @@
     return true;
 }
+static bool revertdependentMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-fault", "pstampDependent.fault", "==");
+    PXOPT_COPY_S64(config->args, where, "-dep_id", "dep_id", "==");
+    pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "==");
+
+    if (!psListLength(where->list)) {
+        psFree(where);
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+        return false;
+    }
+    psString query = pxDataGet("pstamptool_revertdependent.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringAppend(&query, " AND %s", whereClause);
+    psFree(whereClause);
+    psFree(where);
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+
+    return true;
+}
