IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 3, 2010, 8:50:52 AM (16 years ago)
Author:
eugene
Message:

updates from trunk

Location:
branches/simtest_nebulous_branches
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/simtest_nebulous_branches

  • branches/simtest_nebulous_branches/ippTools/src

    • Property svn:ignore
      •  

        old new  
         1*.la
         2*.lo
        13.deps
        24.gdb_history
         
        46Makefile
        57Makefile.in
         8addtool
         9caltool
         10camtool
         11chiptool
        612config.h
        713config.h.in
        8 stamp-h1
        9 *.la
        10 *.lo
         14detselect
         15dettool
         16difftool
         17disttool
         18dqstatstool
         19faketool
         20flatcorr
         21guidetool
         22magicdstool
         23magictool
         24pstamptool
         25pubtool
         26pxadmin
         27pxdata.c
         28pxinject
        1129pxtoolsErrorCodes.c
        1230pxtoolsErrorCodes.h
        13 pxadmin
        14 pxinject
        15 pztool
        1631pzgetexp
        1732pzgetimfiles
         33pztool
         34receivetool
        1835regtool
        19 guidetool
        20 chiptool
        21 camtool
         36stacktool
         37stamp-h1
        2238warptool
        23 difftool
        24 stacktool
        25 faketool
        26 dettool
        27 detselect
        28 pxdata.c
        29 magictool
        30 magicdstool
        31 caltool
        32 flatcorr
        33 pstamptool
        34 disttool
        35 receivetool
        36 
        37 pubtool
  • branches/simtest_nebulous_branches/ippTools/src/difftool.c

    r24955 r27840  
    3737static bool todiffskyfileMode(pxConfig *config);
    3838static bool adddiffskyfileMode(pxConfig *config);
     39static bool advanceMode(pxConfig *config);
    3940static bool diffskyfileMode(pxConfig *config);
    4041static bool revertdiffskyfileMode(pxConfig *config);
     
    4243static bool definewarpstackMode(pxConfig *config);
    4344static bool definewarpwarpMode(pxConfig *config);
     45static bool definestackstackMode(pxConfig *config);
    4446static bool pendingcleanuprunMode(pxConfig *config);
    4547static bool pendingcleanupskyfileMode(pxConfig *config);
     
    5052
    5153static bool setdiffRunState(pxConfig *config, psS64 diff_id, const char *state, psS64 magicked);
    52 static bool diffRunComplete(pxConfig *config);
     54static bool change_skyfile_data_state(pxConfig *config, psString data_state, psString run_state);
     55static bool tocleanedskyfileMode(pxConfig *config);
     56static bool topurgedskyfileMode(pxConfig *config);
     57static bool toscrubbedskyfileMode(pxConfig *config);
     58static bool tofullskyfileMode(pxConfig *config);
     59static bool listrunMode(pxConfig *config);
     60static bool setskyfiletoupdateMode(pxConfig *config);
     61
     62
    5363
    5464# define MODECASE(caseName, func) \
     
    7686        MODECASE(DIFFTOOL_MODE_TODIFFSKYFILE,         todiffskyfileMode);
    7787        MODECASE(DIFFTOOL_MODE_ADDDIFFSKYFILE,        adddiffskyfileMode);
     88        MODECASE(DIFFTOOL_MODE_ADVANCE,               advanceMode);
    7889        MODECASE(DIFFTOOL_MODE_DIFFSKYFILE,           diffskyfileMode);
    7990        MODECASE(DIFFTOOL_MODE_REVERTDIFFSKYFILE,     revertdiffskyfileMode);
    8091        MODECASE(DIFFTOOL_MODE_DEFINEPOPRUN,          definepoprunMode);
    81         MODECASE(DIFFTOOL_MODE_DEFINEWARPSTACK,         definewarpstackMode);
     92        MODECASE(DIFFTOOL_MODE_DEFINEWARPSTACK,       definewarpstackMode);
    8293        MODECASE(DIFFTOOL_MODE_DEFINEWARPWARP,        definewarpwarpMode);
     94        MODECASE(DIFFTOOL_MODE_DEFINESTACKSTACK,      definestackstackMode);
    8395        MODECASE(DIFFTOOL_MODE_PENDINGCLEANUPRUN,     pendingcleanuprunMode);
    8496        MODECASE(DIFFTOOL_MODE_PENDINGCLEANUPSKYFILE, pendingcleanupskyfileMode);
     
    8799        MODECASE(DIFFTOOL_MODE_EXPORTRUN,             exportrunMode);
    88100        MODECASE(DIFFTOOL_MODE_IMPORTRUN,             importrunMode);
     101        MODECASE(DIFFTOOL_MODE_TOCLEANEDSKYFILE,      tocleanedskyfileMode);
     102        MODECASE(DIFFTOOL_MODE_TOPURGEDSKYFILE,       topurgedskyfileMode);
     103        MODECASE(DIFFTOOL_MODE_TOSCRUBBEDSKYFILE,     toscrubbedskyfileMode);
     104        MODECASE(DIFFTOOL_MODE_TOFULLSKYFILE,         tofullskyfileMode);
     105        MODECASE(DIFFTOOL_MODE_LISTRUN,               listrunMode);
     106        MODECASE(DIFFTOOL_MODE_SETSKYFILETOUPDATE,    setskyfiletoupdateMode);
     107
    89108        default:
    90109            psAbort("invalid option (this should not happen)");
     
    114133
    115134    // required options
    116     PXOPT_LOOKUP_STR(workdir, config->args, "-workdir", true, false);
     135    PXOPT_LOOKUP_STR(workdir, config->args, "-set_workdir", true, false);
    117136    PXOPT_LOOKUP_STR(tess_id, config->args, "-tess_id", true, false);
    118137    PXOPT_LOOKUP_BOOL(bothways, config->args, "-bothways", false);
    119138    PXOPT_LOOKUP_BOOL(exposure, config->args, "-exposure", false);
    120     PXOPT_LOOKUP_STR(label, config->args, "-label", false, false);
    121     PXOPT_LOOKUP_STR(reduction, config->args, "-reduction", false, false);
     139    PXOPT_LOOKUP_STR(label, config->args, "-set_label", false, false);
     140    PXOPT_LOOKUP_STR(data_group, config->args, "-set_data_group", false, false);
     141    PXOPT_LOOKUP_STR(dist_group, config->args, "-set_dist_group", false, false);
     142    PXOPT_LOOKUP_STR(reduction, config->args, "-set_reduction", false, false);
     143    PXOPT_LOOKUP_S16(diff_mode, config->args, "-set_diff_mode", false, false);
     144    PXOPT_LOOKUP_STR(note, config->args, "-set_note", false, false);
    122145
    123146    // default
     
    130153            workdir,
    131154            label,
     155            data_group ? data_group : label,
     156            dist_group,
    132157            reduction,
    133158            NULL,       // dvodb
     
    136161            bothways,
    137162            exposure,
    138             false
     163            false,
     164            diff_mode,
     165            note
    139166    );
    140167    if (!run) {
     
    167194    PS_ASSERT_PTR_NON_NULL(config, false);
    168195
    169     // required options
    170     PXOPT_LOOKUP_S64(diff_id, config->args, "-diff_id", true, false);
    171     PXOPT_LOOKUP_STR(state, config->args, "-state", true, false);
    172 
    173     if (state) {
    174         // set detRun.state to state
    175         return setdiffRunState(config, diff_id, state, false);
    176     }
    177 
    178     return true;
     196    psMetadata *where = psMetadataAlloc();
     197
     198    PXOPT_COPY_S64(config->args, where, "-diff_id",  "diff_id",   "==");
     199    PXOPT_COPY_STR(config->args, where, "-label",     "label",     "==");
     200    PXOPT_COPY_STR(config->args, where, "-data_group","data_group",     "==");
     201    PXOPT_COPY_STR(config->args, where, "-state",     "state",     "==");
     202    if (!psListLength(where->list)) {
     203        psFree(where);
     204        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
     205        return false;
     206    }
     207
     208    psString query = psStringCopy("UPDATE diffRun");
     209
     210    // pxUpdateRun gets parameters from config->args and updates
     211    bool result = pxUpdateRun(config, where, &query, "diffRun", "diff_id", "diffSkyfile", true);
     212
     213    psFree(query);
     214    psFree(where);
     215
     216    return result;
    179217}
    180218
     
    331369    psString query = pxDataGet("difftool_inputskyfile.sql");
    332370    if (!query) {
    333         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
    334         return false;
    335     }
    336 
    337     psString whereClause = NULL;
     371        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     372        return false;
     373    }
     374
     375    psString whereClause = psStringCopy("");
    338376    if (psListLength(where->list)) {
    339377        whereClause = psDBGenerateWhereConditionSQL(where, NULL);
    340         psStringPrepend(&whereClause, "\n AND ");
     378        psStringPrepend(&whereClause, "\n WHERE ");
    341379    }
    342380    psFree(where);
    343381
    344382    // Add condition to get only templates or only inputs
     383    psString templateClause = psStringCopy("");
    345384    {
    346         psString templateClause = NULL;
    347385        if (template) {
    348             psStringAppend(&templateClause, " %s", " template != 0");
     386            psStringAppend(&templateClause, "\n WHERE %s", " template != 0");
    349387        } else if (input) {
    350             psStringAppend(&templateClause, " %s", " template = 0");
    351         }
    352         if (templateClause) {
    353             psStringAppend(&whereClause, "\n AND %s", templateClause);
    354         }
    355         psFree(templateClause);
     388            psStringAppend(&templateClause, "\n WHERE %s", " template = 0");
     389        }
    356390    }
    357391
     
    364398    }
    365399
    366     if (!p_psDBRunQueryF(config->dbh, query, whereClause, whereClause, whereClause, whereClause)) {
    367         psError(PS_ERR_UNKNOWN, false, "database error");
     400    if (!p_psDBRunQueryF(config->dbh, query, whereClause, whereClause, whereClause, whereClause, templateClause)) {
     401        psError(PS_ERR_UNKNOWN, false, "database error");
     402        psFree(templateClause);
    368403        psFree(whereClause);
    369404        psFree(query);
    370405        return false;
    371406    }
     407    psFree(templateClause);
    372408    psFree(whereClause);
    373409    psFree(query);
     
    421457    psString query = pxDataGet("difftool_todiffskyfile.sql");
    422458    if (!query) {
    423         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     459        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
    424460        return false;
    425461    }
     
    555591    }
    556592
    557     if (!diffRunComplete(config)) {
    558         if (!psDBRollback(config->dbh)) {
    559             psError(PS_ERR_UNKNOWN, false, "database error");
    560         }
    561         psError(PS_ERR_UNKNOWN, false, "database error");
    562         return false;
    563     }
    564 
    565593    // point of no return
    566594    if (!psDBCommit(config->dbh)) {
     
    569597    }
    570598
     599
     600    return true;
     601}
     602
     603static bool advanceMode(pxConfig *config)
     604{
     605    PS_ASSERT_PTR_NON_NULL(config, false);
     606
     607    psMetadata *where = psMetadataAlloc();
     608    PXOPT_COPY_S64(config->args, where,  "-diff_id", "diffRun.diff_id", "==");
     609    pxAddLabelSearchArgs (config, where, "-label", "diffRun.label", "==");
     610
     611    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     612
     613    // look for completed diffRuns
     614    psString query = pxDataGet("difftool_completed_runs.sql");
     615    if (!query) {
     616        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     617        return false;
     618    }
     619
     620    psString whereString = psStringCopy("");
     621    if (psListLength(where->list)) {
     622        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     623        psStringAppend(&whereString, "\n AND %s", whereClause);
     624        psFree(whereClause);
     625    }
     626    psFree(where);
     627
     628    // treat limit == 0 as "no limit"
     629    if (limit) {
     630        psString limitString = psDBGenerateLimitSQL(limit);
     631        psStringAppend(&query, " %s", limitString);
     632        psFree(limitString);
     633    }
     634
     635    if (!psDBTransaction(config->dbh)) {
     636        psError(PS_ERR_UNKNOWN, false, "database error");
     637        psFree(whereString);
     638        return false;
     639    }
     640
     641    if (!p_psDBRunQueryF(config->dbh, query, whereString)) {
     642        psError(PS_ERR_UNKNOWN, false, "database error");
     643        psFree(query);
     644        psFree(whereString);
     645        if (!psDBRollback(config->dbh)) {
     646            psError(PS_ERR_UNKNOWN, false, "database error");
     647        }
     648        return false;
     649    }
     650    psFree(query);
     651    psFree(whereString);
     652
     653    psArray *output = p_psDBFetchResult(config->dbh);
     654    if (!output) {
     655        psError(PS_ERR_UNKNOWN, false, "database error");
     656        if (!psDBRollback(config->dbh)) {
     657            psError(PS_ERR_UNKNOWN, false, "database error");
     658        }
     659        return false;
     660    }
     661    if (!psArrayLength(output)) {
     662        psTrace("difftool", PS_LOG_INFO, "no rows found");
     663        psFree(output);
     664        return true;
     665    }
     666
     667    for (long i = 0; i < psArrayLength(output); i++) {
     668        psMetadata *row = output->data[i];
     669
     670        psS64 diff_id = psMetadataLookupS64(NULL, row, "diff_id");
     671        psS64 magicked = psMetadataLookupS64(NULL, row, "magicked");
     672
     673        // set diffRun.state to 'full'
     674        if (!setdiffRunState(config, diff_id, "full", magicked)) {
     675            psError(PS_ERR_UNKNOWN, false, "failed to change diffRun.state for diff_id: %" PRId64,
     676                diff_id);
     677            psFree(output);
     678            if (!psDBRollback(config->dbh)) {
     679                psError(PS_ERR_UNKNOWN, false, "database error");
     680            }
     681            return false;
     682        }
     683    }
     684    psFree(output);
     685
     686    if (!psDBCommit(config->dbh)) {
     687        psError(PS_ERR_UNKNOWN, false, "database error");
     688        return false;
     689    }
    571690
    572691    return true;
     
    581700    PXOPT_COPY_S64(config->args, where,  "-diff_id", "diffSkyfile.diff_id", "==");
    582701    PXOPT_COPY_STR(config->args, where, "-skycell_id", "diffInputSkyfile.skycell_id", "==");
    583     PXOPT_COPY_S64(config->args, where,  "-diff_skyfile_id", "diffInputSkyfile.diff_skyfile_id", "==");
     702    PXOPT_COPY_S64(config->args, where, "-diff_skyfile_id", "diffInputSkyfile.diff_skyfile_id", "==");
    584703    PXOPT_COPY_STR(config->args, where, "-tess_id", "diffRun.tess_id", "==");
    585704    PXOPT_COPY_S16(config->args, where, "-fault", "diffSkyfile.fault", "==");
    586     PXOPT_COPY_S64(config->args, where, "-exp_id", "rawExp.exp_id", "==");
    587     PXOPT_COPY_STR(config->args, where, "-exp_name", "rawExp.exp_name", "==");
    588     PXOPT_COPY_STR(config->args, where, "-warp_id", "warpRun.warp_id", "==");
    589 
     705    PXOPT_COPY_S64(config->args, where,  "-magicked", "diffSkyfile.magicked", "==");
     706    pxAddLabelSearchArgs (config, where, "-label", "diffRun.label", "LIKE");
     707    pxAddLabelSearchArgs (config, where, "-data_group", "diffRun.data_group", "LIKE");
     708
     709    PXOPT_LOOKUP_BOOL(pstamp_order, config->args, "-pstamp_order", false);
     710    PXOPT_LOOKUP_BOOL(template, config->args, "-template", false);
     711    if (!template) {
     712        PXOPT_COPY_S64(config->args, where, "-exp_id", "rawInput.exp_id", "==");
     713        PXOPT_COPY_STR(config->args, where, "-exp_name", "rawInput.exp_name", "==");
     714        PXOPT_COPY_STR(config->args, where, "-warp_id", "warpInput.warp_id", "==");
     715        PXOPT_COPY_TIME(config->args, where, "-dateobs_begin", "rawInput.dateobs",  ">=");
     716        PXOPT_COPY_TIME(config->args, where, "-dateobs_end",   "rawInput.dateobs",  "<=");
     717        PXOPT_COPY_STR(config->args, where, "-filter",     "rawInput.filter", "LIKE");
     718    } else {
     719        PXOPT_COPY_S64(config->args, where, "-exp_id", "rawTemplate.exp_id", "==");
     720        PXOPT_COPY_STR(config->args, where, "-exp_name", "rawTemplate.exp_name", "==");
     721        PXOPT_COPY_STR(config->args, where, "-warp_id", "warpTemplate.warp_id", "==");
     722        PXOPT_COPY_TIME(config->args, where, "-dateobs_begin", "rawTemplate.dateobs",  ">=");
     723        PXOPT_COPY_TIME(config->args, where, "-dateobs_end",   "rawTemplate.dateobs",  "<=");
     724        PXOPT_COPY_STR(config->args, where, "-filter",     "rawTemplate.filter", "LIKE");
     725    }
     726
     727    PXOPT_LOOKUP_BOOL(all, config->args, "-all", false);
    590728    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
    591729    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
    592730
     731
     732    psString where2 = NULL;
     733    pxmagicAddWhere(config, &where2, "diffSkyfile");
     734    pxspaceAddWhere(config, &where2, template ? "rawTemplate" : "rawInput");
    593735    psString query = pxDataGet("difftool_skyfile.sql");
    594736    if (!query) {
    595         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     737        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
    596738        return false;
    597739    }
     
    601743        psStringAppend(&query, " WHERE %s", whereClause);
    602744        psFree(whereClause);
     745    } else if (where2) {
     746        psStringAppend(&query, " WHERE diffRun.diff_id is not null %s", where2);
     747    } else if (!all) {
     748        psError(PXTOOLS_ERR_CONFIG, true, "search parameters or -all are required");
     749        return false;
    603750    }
    604751    psFree(where);
    605752
     753    if (pstamp_order) {
     754        if (template) {
     755            psStringAppend(&query, " ORDER BY rawTemplate.exp_id, diff_id DESC");
     756        } else {
     757            psStringAppend(&query, " ORDER BY rawInput.exp_id, diff_id DESC");
     758        }
     759    }
     760           
    606761    // treat limit == 0 as "no limit"
    607762    if (limit) {
     
    659814    psMetadata *where = psMetadataAlloc();
    660815    PXOPT_COPY_S64(config->args, where,  "-diff_id", "diffSkyfile.diff_id", "==");
    661     PXOPT_COPY_STR(config->args, where,  "-label", "diffRun.label", "==");
     816    PXOPT_COPY_STR(config->args, where,  "-skycell_id", "diffSkyfile.skycell_id", "==");
     817    pxAddLabelSearchArgs(config, where, "-label", "diffRun.label", "==");
    662818    PXOPT_COPY_S16(config->args, where, "-fault",     "fault", "==");
    663819
    664820    if (!psListLength(where->list) && !psMetadataLookupBool(NULL, config->args, "-all")) {
    665821        psFree(where);
    666         psError(PXTOOLS_ERR_DATA, false, "search parameters are required");
    667         return false;
    668     }
    669 
    670     if (!psDBTransaction(config->dbh)) {
    671         psError(PS_ERR_UNKNOWN, false, "database error");
    672         psFree(where);
    673         return false;
    674     }
    675 
    676     // Update state to 'new'
     822        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
     823        return false;
     824    }
     825
    677826    {
    678         psString query = pxDataGet("difftool_revertdiffskyfile_update.sql");
     827        psString query = pxDataGet("difftool_revertdiffskyfile_delete.sql");
    679828        if (!query) {
    680             psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
    681             if (!psDBRollback(config->dbh)) {
    682                 psError(PS_ERR_UNKNOWN, false, "database error");
    683             }
     829            psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     830            return false;
     831        }
     832        psString query_updated = pxDataGet("difftool_revertdiffskyfile_updated.sql");
     833        if (!query_updated) {
     834            psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
    684835            return false;
    685836        }
     
    688839            psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
    689840            psStringAppend(&query, " AND %s", whereClause);
     841            psStringAppend(&query_updated, " AND %s", whereClause);
    690842            psFree(whereClause);
    691843        }
     
    694846            psError(PS_ERR_UNKNOWN, false, "database error");
    695847            psFree(query);
    696             if (!psDBRollback(config->dbh)) {
    697                 psError(PS_ERR_UNKNOWN, false, "database error");
    698             }
    699848            return false;
    700849        }
    701850        psFree(query);
     851        psLogMsg("difftool", PS_LOG_INFO, "Deleted %" PRIu64 " rows", psDBAffectedRows(config->dbh));
     852
     853        if (!p_psDBRunQuery(config->dbh, query_updated)) {
     854            psError(PS_ERR_UNKNOWN, false, "database error");
     855            psFree(query_updated);
     856            return false;
     857        }
     858        psFree(query_updated);
    702859
    703860        psLogMsg("difftool", PS_LOG_INFO, "Updated %" PRIu64 " rows", psDBAffectedRows(config->dbh));
    704861    }
    705862
    706     // Delete product
    707     {
    708         psString query = pxDataGet("difftool_revertdiffskyfile_delete.sql");
    709         if (!query) {
    710             psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
    711             if (!psDBRollback(config->dbh)) {
    712                 psError(PS_ERR_UNKNOWN, false, "database error");
    713             }
    714             return false;
    715         }
    716 
    717         if (psListLength(where->list)) {
    718             psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
    719             psStringAppend(&query, " AND %s", whereClause);
    720             psFree(whereClause);
    721         }
    722 
    723         if (!p_psDBRunQuery(config->dbh, query)) {
    724             psError(PS_ERR_UNKNOWN, false, "database error");
    725             psFree(query);
    726             if (!psDBRollback(config->dbh)) {
    727                 psError(PS_ERR_UNKNOWN, false, "database error");
    728             }
    729             return false;
    730         }
    731         psFree(query);
    732 
    733         psLogMsg("difftool", PS_LOG_INFO, "Deleted %" PRIu64 " rows", psDBAffectedRows(config->dbh));
    734     }
    735 
    736863    psFree(where);
    737864
    738     if (!psDBCommit(config->dbh)) {
    739         psError(PS_ERR_UNKNOWN, false, "database error");
    740         return false;
    741     }
    742865
    743866    return true;
     
    755878    }
    756879
    757     char *query = "UPDATE diffRun SET state = '%s', magicked = %" PRId64 " WHERE diff_id = %"PRId64;
    758 
    759     if (!p_psDBRunQueryF(config->dbh, query, state, magicked, diff_id)) {
     880    if (magicked) {
     881      char *query = "UPDATE diffRun SET state = '%s', magicked = %" PRId64 " WHERE diff_id = %"PRId64;
     882
     883      if (!p_psDBRunQueryF(config->dbh, query, state, magicked, diff_id)) {
    760884        psError(PS_ERR_UNKNOWN, false,
    761885                "failed to change state for diff_id %"PRId64, diff_id);
    762886        return false;
     887      }
     888    }
     889    else {
     890      char *query = "UPDATE diffRun SET state = '%s' WHERE diff_id = %"PRId64;
     891
     892      if (!p_psDBRunQueryF(config->dbh, query, state, diff_id)) {
     893        psError(PS_ERR_UNKNOWN, false,
     894                "failed to change state for diff_id %"PRId64, diff_id);
     895        return false;
     896      }
    763897    }
    764898
    765899    return true;
    766900}
     901
     902
     903#ifdef notdef
     904static bool setdiffRunStateByLabel(pxConfig *config, const char *label, const char *state) {
     905  PS_ASSERT_PTR_NON_NULL(state,false);
     906
     907  // check that state is a valid string value
     908  if (!pxIsValidState(state)) {
     909    psError(PS_ERR_UNKNOWN, false, "invalid diffRun state: %s", state);
     910    return false;
     911  }
     912
     913  char *query = "UPDATE diffRun SET state = '%s' WHERE label = '%s'";
     914  if (!p_psDBRunQueryF(config->dbh,query,state,label)) {
     915    psError(PS_ERR_UNKNOWN, false,
     916            "failed to change state for label %s", label);
     917    return(false);
     918  }
     919
     920  return true;
     921}
     922#endif
    767923
    768924// Generate a single populated run
     
    772928                         const char *tess_id, // Tessellation identifier
    773929                         const char *label, // label
     930                         const char *data_group, // data_group
     931                         const char *dist_group, // dist_group
    774932                         const char *reduction, // reduction
     933                         const char *note,      // note
    775934                         psS64 input_warp_id, // Warp identifier for input image, PS_MAX_S64 for none
    776935                         psS64 input_stack_id, // Stack identifier for input image, PS_MAX_S64 for none
     
    793952        return false;
    794953    }
     954    psS16 diff_mode = IPP_DIFF_MODE_UNDEFINED;
     955    if ((input_warp_id != PS_MAX_S64) && (template_warp_id != PS_MAX_S64)) {
     956      diff_mode = IPP_DIFF_MODE_WARP_WARP;
     957    }
     958    else if ((input_warp_id != PS_MAX_S64) && (template_stack_id != PS_MAX_S64)) {
     959      diff_mode = IPP_DIFF_MODE_WARP_STACK;
     960    }
     961    else if ((input_stack_id != PS_MAX_S64) && (template_warp_id != PS_MAX_S64)) {
     962      diff_mode = IPP_DIFF_MODE_STACK_WARP;
     963    }
     964    else if ((input_stack_id != PS_MAX_S64) && (template_stack_id != PS_MAX_S64)) {
     965      diff_mode = IPP_DIFF_MODE_STACK_STACK;
     966    }
     967
    795968
    796969    // default
     
    803976            workdir,
    804977            label,
     978            data_group ? data_group : label,
     979            dist_group,
    805980            reduction,
    806981            NULL,       // dvodb
     
    809984            false,
    810985            false,
    811             0       // magicked
     986            0,       // magicked
     987            diff_mode, // diff_mode
     988            note
    812989    );
    813990
     
    8831060    PXOPT_LOOKUP_STR(tess_id, config->args, "-tess_id", true, false); // required options
    8841061    PXOPT_LOOKUP_STR(label, config->args, "-label", false, false);
     1062    PXOPT_LOOKUP_STR(data_group, config->args, "-set_data_group", false, false);
     1063    PXOPT_LOOKUP_STR(dist_group, config->args, "-set_dist_group", false, false);
    8851064    PXOPT_LOOKUP_STR(reduction, config->args, "-reduction", false, false);
    8861065    PXOPT_LOOKUP_S64(template_warp_id, config->args, "-template_warp_id", false, false);
     
    8891068    PXOPT_LOOKUP_S64(input_stack_id, config->args, "-input_stack_id", false, false);
    8901069    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     1070    PXOPT_LOOKUP_STR(note, config->args, "-set_note", false, false);
    8911071
    8921072    if (template_stack_id && template_warp_id) {
     
    9111091
    9121092    psArray *list = psArrayAllocEmpty(16); // List of runs, to print
    913 
    914     if (!populatedrun(list, workdir, skycell_id, tess_id, label, reduction,
     1093    // Populated Run will generate the diff_mode value
     1094    if (!populatedrun(list, workdir, skycell_id, tess_id, label, data_group ? data_group : label, dist_group, reduction, note,
    9151095                      input_warp_id ? input_warp_id : PS_MAX_S64,
    9161096                      input_stack_id ? input_stack_id : PS_MAX_S64,
     
    9391119
    9401120    psMetadata *expWhere = psMetadataAlloc();
    941     psMetadata *warpWhere = psMetadataAlloc();
     1121    psMetadata *warp1Where = psMetadataAlloc(); // First set of restrictions on warp
     1122    psMetadata *warp2Where = psMetadataAlloc(); // Second set of restriction on warp
    9421123    psMetadata *stackWhere = psMetadataAlloc();
    9431124
    9441125    PXOPT_COPY_S64(config->args, expWhere, "-exp_id", "exp_id", "==");
    9451126    PXOPT_COPY_STR(config->args, expWhere, "-filter", "filter", "==");
    946     PXOPT_COPY_S64(config->args, warpWhere, "-warp_id", "warpRun.warp_id", "==");
    947     PXOPT_COPY_STR(config->args, warpWhere, "-skycell_id", "warpSkyfile.skycell_id", "==");
    948     PXOPT_COPY_STR(config->args, warpWhere, "-tess_id", "warpRun.tess_id", "==");
    949     PXOPT_COPY_STR(config->args, warpWhere, "-warp_label", "warpRun.label", "==");
    950     PXOPT_COPY_F32(config->args, warpWhere,  "-good_frac", "warpSkyfile.good_frac", ">=");
     1127    PXOPT_COPY_STR(config->args, expWhere, "-comment", "comment", "LIKE");
     1128    PXOPT_COPY_S64(config->args, warp1Where, "-warp_id", "warpRun.warp_id", "==");
     1129    PXOPT_COPY_STR(config->args, warp1Where, "-warp_label", "warpRun.label", "==");
     1130    PXOPT_COPY_STR(config->args, warp1Where, "-tess_id", "warpRun.tess_id", "==");
     1131    PXOPT_COPY_STR(config->args, warp1Where, "-data_group", "warpRun.data_group", "==");
     1132    PXOPT_COPY_S64(config->args, warp2Where, "-warp_id", "warpRun.warp_id", "==");
     1133    PXOPT_COPY_STR(config->args, warp2Where, "-tess_id", "warpRun.tess_id", "==");
     1134    PXOPT_COPY_STR(config->args, warp2Where, "-data_group", "warpRun.data_group", "==");
     1135    PXOPT_COPY_STR(config->args, warp2Where, "-skycell_id", "warpSkyfile.skycell_id", "==");
     1136    PXOPT_COPY_STR(config->args, warp2Where, "-warp_label", "warpRun.label", "==");
     1137    PXOPT_COPY_F32(config->args, warp2Where,  "-good_frac", "warpSkyfile.good_frac", ">=");
    9511138    PXOPT_COPY_STR(config->args, stackWhere, "-stack_label", "stackRun.label", "==");
    9521139
    953     PXOPT_LOOKUP_STR(workdir, config->args, "-workdir", true, false); // required options
    954     PXOPT_LOOKUP_STR(reduction, config->args, "-reduction", false, false); // option
    955     PXOPT_LOOKUP_STR(label, config->args, "-label", false, false); // option
    956     PXOPT_LOOKUP_TIME(registered, config->args, "-registered", false, false);
     1140    PXOPT_LOOKUP_STR(workdir, config->args, "-set_workdir", true, false); // required option
     1141    PXOPT_LOOKUP_STR(reduction, config->args, "-set_reduction", false, false); // option
     1142    PXOPT_LOOKUP_STR(label, config->args, "-set_label", false, false); // option
     1143    PXOPT_LOOKUP_STR(data_group, config->args, "-set_data_group", false, false);
     1144    PXOPT_LOOKUP_STR(dist_group, config->args, "-set_dist_group", false, false);
     1145    PXOPT_LOOKUP_STR(note, config->args, "-set_note", false, false);
     1146    PXOPT_LOOKUP_TIME(registered, config->args, "-set_registered", false, false);
     1147
    9571148    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
    9581149    PXOPT_LOOKUP_BOOL(newTemplates, config->args, "-new-templates", false);
     
    9641155    psString query = pxDataGet("difftool_definewarpstack_part1.sql");
    9651156    if (!query) {
    966         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
    967         return false;
    968     }
    969 
    970     psString warpQuery = NULL;
     1157        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     1158        return false;
     1159    }
     1160
     1161    psString warp1Query = NULL;
     1162    psString warp2Query = NULL;
    9711163    psString stackQuery = NULL;
    9721164    psString expQuery = NULL;
     
    9801172    }
    9811173    psFree(expWhere);
    982     if (psListLength(warpWhere->list)) {
    983         psString whereClause = psDBGenerateWhereConditionSQL(warpWhere, NULL);
    984         psStringAppend(&warpQuery, "\n AND %s", whereClause);
     1174    if (psListLength(warp1Where->list)) {
     1175        psString whereClause = psDBGenerateWhereConditionSQL(warp1Where, NULL);
     1176        psStringAppend(&warp1Query, "\n AND %s", whereClause);
    9851177        psFree(whereClause);
    9861178    } else {
    987         warpQuery = psStringCopy("\n");
    988     }
    989     psFree(warpWhere);
    990 
    991     if (!available) {
    992         // diff what's available, even if warp run has some faults and is incomplete
    993         psStringAppend(&warpQuery, " AND warpRun.state = 'full'");
    994     }
     1179        warp1Query = psStringCopy("\n");
     1180    }
     1181    psFree(warp1Where);
     1182    if (psListLength(warp2Where->list)) {
     1183        psString whereClause = psDBGenerateWhereConditionSQL(warp2Where, NULL);
     1184        psStringAppend(&warp2Query, "\n AND %s", whereClause);
     1185        psFree(whereClause);
     1186    } else {
     1187        warp2Query = psStringCopy("\n");
     1188    }
     1189    psFree(warp2Where);
    9951190
    9961191    // don't queue for exposures that have already been diff'd unless requested
     
    10111206    psFree(stackWhere);
    10121207
    1013     psTrace("difftool", 1, query, warpQuery, diffQuery, expQuery, stackQuery);
     1208    psTrace("difftool", 1, query, warp1Query, warp2Query, diffQuery, expQuery, stackQuery);
    10141209
    10151210    if (!psDBTransaction(config->dbh)) {
     
    10181213    }
    10191214
    1020     if (!p_psDBRunQueryF(config->dbh, query, warpQuery, expQuery, diffQuery)) {
     1215    if (!p_psDBRunQueryF(config->dbh, query, warp1Query, warp2Query, expQuery, diffQuery)) {
    10211216        psError(PS_ERR_UNKNOWN, false, "database error");
    10221217        psFree(query);
     
    10781273        return false;
    10791274    }
     1275    psFree(warp1Query);
    10801276    psFree(query);
    10811277    query = NULL;
     
    11091305        if (!p_psDBRunQuery(config->dbh, "DELETE FROM skycellsToDiff")) {
    11101306            psError(PS_ERR_UNKNOWN, false, "database error");
    1111             psFree(warpQuery);
     1307            psFree(warp2Query);
    11121308            psFree(stackQuery);
    11131309            psFree(skycell_query);
     
    11201316        if (!mdok) {
    11211317            psError(PXTOOLS_ERR_PROG, false, "warp_id not found --- ignoring row %ld", i);
    1122             psFree(warpQuery);
     1318            psFree(warp2Query);
    11231319            psFree(stackQuery);
    11241320            psFree(skycell_query);
     
    11311327        if (!mdok) {
    11321328            psError(PXTOOLS_ERR_PROG, false, "skycell_count not found");
    1133             psFree(warpQuery);
     1329            psFree(warp2Query);
    11341330            psFree(stackQuery);
    11351331            psFree(skycell_query);
     
    11421338        if (!mdok) {
    11431339            psError(PXTOOLS_ERR_PROG, false, "tess_id not found");
    1144             psFree(warpQuery);
     1340            psFree(warp2Query);
    11451341            psFree(stackQuery);
    11461342            psFree(skycell_query);
     
    11501346            return false;
    11511347        }
     1348
    11521349        psString filter = psMetadataLookupStr(&mdok, row, "filter");
    11531350        if (!mdok) {
    11541351            psError(PXTOOLS_ERR_PROG, false, "filter not found");
    1155             psFree(warpQuery);
     1352            psFree(warp2Query);
    11561353            psFree(stackQuery);
    11571354            psFree(skycell_query);
     
    11611358            return false;
    11621359        }
    1163         if (!p_psDBRunQueryF(config->dbh, skycell_query, stackQuery, warp_id, filter, warpQuery)) {
    1164             psError(PS_ERR_UNKNOWN, false, "database error");
    1165             psFree(warpQuery);
     1360
     1361        psString warp_data_group = psMetadataLookupStr(&mdok, row, "data_group");
     1362        if (!mdok) {
     1363          psError(PXTOOLS_ERR_PROG, false, "warp data_group not found");
     1364          psFree(warp2Query);
     1365          psFree(stackQuery);
     1366          psFree(skycell_query);
     1367          if (!psDBRollback(config->dbh)) {
     1368            psError(PS_ERR_UNKNOWN, false, "database error");
     1369          }
     1370          return false;
     1371        }
     1372        if (warp_data_group) {
     1373          data_group = warp_data_group;
     1374        }
     1375       
     1376        if (!p_psDBRunQueryF(config->dbh, skycell_query, stackQuery, warp_id, filter, warp2Query)) {
     1377            psError(PS_ERR_UNKNOWN, false, "database error");
     1378            psFree(warp2Query);
    11661379            psFree(stackQuery);
    11671380            psFree(skycell_query);
     
    11741387
    11751388        if (num == 0) {
    1176             psTrace("difftool", PS_LOG_INFO, "no skycells with stack found for %" PRId64, warp_id);
     1389            psTrace("difftool", PS_LOG_INFO, "no skycells with stack found for warp_id %" PRId64, warp_id);
    11771390            continue;
    11781391        }
    11791392
    11801393        if (!available && (num != skycell_count)) {
    1181             psTrace("difftool", PS_LOG_INFO, "%" PRId64 " skyfiles with stack found for warp_id %"
    1182                 PRId64 " need %" PRId64, num, skycell_count, warp_id);
     1394            psTrace("difftool", PS_LOG_INFO, "%" PRId64 " skyfiles with stack found for warp_id %" PRId64
     1395                    " but need %" PRId64, num, warp_id, skycell_count);
    11831396            continue;
    11841397        }
     
    11901403                workdir,
    11911404                label,
     1405                data_group ? data_group : label,
     1406                dist_group,
    11921407                reduction,
    11931408                NULL,       // dvodb
     
    11961411                false,                  // bothways
    11971412                true,                   // exposure
    1198                 0       // magicked
     1413                0,       // magicked
     1414                IPP_DIFF_MODE_WARP_STACK,
     1415                note
    11991416        );
    12001417
     
    12121429        if (!p_psDBRunQuery(config->dbh, query)) {
    12131430            psError(PS_ERR_UNKNOWN, false, "database error");
    1214             psFree(warpQuery);
     1431            psFree(warp2Query);
    12151432            psFree(stackQuery);
    12161433            psFree(skycell_query);
     
    12261443        if (!p_psDBRunQuery(config->dbh, query)) {
    12271444            psError(PS_ERR_UNKNOWN, false, "database error");
    1228             psFree(warpQuery);
     1445            psFree(warp2Query);
    12291446            psFree(stackQuery);
    12301447            psFree(skycell_query);
     
    12411458            psError(PS_ERR_UNKNOWN, false, "failed to change diffRun.state for diff_id: %" PRId64,
    12421459                run->diff_id);
    1243             psFree(warpQuery);
     1460            psFree(warp2Query);
    12441461            psFree(stackQuery);
    12451462            psFree(skycell_query);
     
    12551472    }
    12561473    psFree(output);
    1257     psFree(warpQuery);
     1474    psFree(warp2Query);
    12581475    psFree(stackQuery);
    12591476    psFree(skycell_query);
     
    12651482    }
    12661483
    1267     if (!diffRunPrintObjects(stdout, list, !simple)) {
     1484    if (numGood && !diffRunPrintObjects(stdout, list, !simple)) {
    12681485        psError(PS_ERR_UNKNOWN, false, "failed to print object");
    12691486        psFree(list);
     
    13431560    // Additional controls
    13441561    PXOPT_LOOKUP_BOOL(rerun, config->args, "-rerun", false);
    1345     PXOPT_LOOKUP_BOOL(available, config->args, "-available", false);
    13461562
    13471563    // Settings to apply to defined run
    1348     PXOPT_LOOKUP_STR(workdir, config->args, "-workdir", true, false); // required options
    1349     PXOPT_LOOKUP_STR(reduction, config->args, "-reduction", false, false); // option
    1350     PXOPT_LOOKUP_STR(label, config->args, "-label", false, false); // option
    1351     PXOPT_LOOKUP_TIME(registered, config->args, "-registered", false, false);
     1564    PXOPT_LOOKUP_STR(workdir, config->args, "-set_workdir", true, false); // required options
     1565    PXOPT_LOOKUP_STR(reduction, config->args, "-set_reduction", false, false); // option
     1566    PXOPT_LOOKUP_STR(label, config->args, "-set_label", false, false); // option
     1567    PXOPT_LOOKUP_STR(data_group, config->args, "-set_data_group", false, false); // option
     1568    PXOPT_LOOKUP_STR(dist_group, config->args, "-set_dist_group", false, false); // option
     1569    PXOPT_LOOKUP_STR(note, config->args, "-set_note", false, false); // option
     1570    PXOPT_LOOKUP_TIME(registered, config->args, "-set_registered", false, false);
     1571
    13521572    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
    13531573    PXOPT_LOOKUP_BOOL(pretend, config->args, "-pretend", false);
     
    13641584        psString tempCreate = pxDataGet("difftool_definewarpwarp_temp_create.sql"); // Create temp table SQL
    13651585        if (!tempCreate) {
    1366             psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     1586            psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
    13671587            psFree(selectWhere);
    13681588            psFree(insertWhere);
     
    13871607        psString tempInsert = pxDataGet("difftool_definewarpwarp_temp_insert.sql"); // Insert to temp table
    13881608        if (!tempInsert) {
    1389             psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     1609            psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
    13901610            psFree(selectWhere);
    13911611            psFree(insertWhere);
     
    14191639    psString select = pxDataGet("difftool_definewarpwarp_select.sql");
    14201640    if (!select) {
    1421         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     1641        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
    14221642        psFree(selectWhere);
    14231643        psFree(insertWhere);
     
    14321652    if (psListLength(selectWhere->list)) {
    14331653        psString new = psDBGenerateWhereConditionSQL(selectWhere, NULL);
    1434         psStringAppend(&whereClause, "\n%s %s", whereClause ? "AND" : "WHERE", new);
     1654        psStringAppend(&whereClause, "\nAND %s", new);
    14351655        psFree(new);
    14361656    }
    14371657    psFree(selectWhere);
    14381658
    1439     if (!available) {
    1440         psStringAppend(&whereClause,
    1441                        "\n%s inputWarpRun.state = 'full'"
    1442                        "AND templateWarpRun.state = 'full'",
    1443                        whereClause ? "AND" : "WHERE");
    1444     }
    1445 
    14461659    if (!rerun) {
    1447         psStringAppend(&whereClause, "\n%s diffs.diff_id IS NULL", whereClause ? "AND" : "WHERE");
     1660        psStringAppend(&whereClause, "\nAND diffs.diff_id IS NULL");
    14481661    }
    14491662
     
    15221735        const char *template = psMetadataLookupStr(NULL, row, "template_warp_id");
    15231736        const char *tess_id = psMetadataLookupStr(NULL, row, "tess_id");
     1737        psString input_data_group = psMetadataLookupStr(NULL, row, "input_data_group");
     1738        if (input_data_group) {
     1739          data_group = input_data_group;
     1740        }
     1741
    15241742        if (!input_id || !template || !tess_id) {
    15251743            psError(PXTOOLS_ERR_PROG, false, "Identifiers not found");
     
    15321750            return false;
    15331751        }
    1534 
    1535         diffRunRow *run = diffRunRowAlloc(0, "reg", workdir, label, reduction, NULL, registered,
    1536                                           tess_id, true, true, false); // Run to insert
     1752       
     1753        diffRunRow *run = diffRunRowAlloc(0,
     1754                                          "reg",
     1755                                          workdir,
     1756                                          label,
     1757                                          data_group ? data_group : label,
     1758                                          dist_group,
     1759                                          reduction,
     1760                                          NULL,  // dvodb
     1761                                          registered,
     1762                                          tess_id,
     1763                                          true,  // bothways
     1764                                          true,  // exposure
     1765                                          false, // magicked
     1766                                          IPP_DIFF_MODE_WARP_WARP,
     1767                                          note); // Run to insert
    15371768        if (!diffRunInsertObject(config->dbh, run)) {
    15381769            psError(PS_ERR_UNKNOWN, false, "database error");
     
    16061837}
    16071838
     1839static bool definestackstackMode(pxConfig *config) {
     1840  PS_ASSERT_PTR_NON_NULL(config, false);
     1841
     1842  psMetadata *stack1Where = psMetadataAlloc();
     1843  psMetadata *stack2Where = psMetadataAlloc();
     1844
     1845  PXOPT_COPY_STR(config->args, stack1Where, "-tess_id", "stackRun.tess_id", "==");
     1846  PXOPT_COPY_STR(config->args, stack2Where, "-tess_id", "stackRun.tess_id", "==");
     1847  PXOPT_COPY_STR(config->args, stack1Where, "-filter", "stackRun.filter", "==");
     1848  PXOPT_COPY_STR(config->args, stack2Where, "-filter", "stackRun.filter", "==");
     1849  PXOPT_COPY_STR(config->args, stack1Where, "-skycell_id", "stackRun.skycell_id", "==");
     1850  PXOPT_COPY_STR(config->args, stack2Where, "-skycell_id", "stackRun.skycell_id", "==");
     1851  PXOPT_COPY_STR(config->args, stack1Where, "-input_label", "stackRun.label","==");
     1852  PXOPT_COPY_STR(config->args, stack2Where, "-template_label", "stackRun.label","==");
     1853  PXOPT_COPY_F32(config->args, stack1Where, "-good_frac", "stackSumSkyfile.good_frac", ">=");
     1854  PXOPT_COPY_F32(config->args, stack2Where, "-good_frac", "stackSumSkyfile.good_frac", ">=");
     1855
     1856  PXOPT_LOOKUP_STR(workdir, config->args, "-set_workdir", true, false); // required option
     1857  PXOPT_LOOKUP_STR(label, config->args, "-set_label", false, false); // option
     1858  PXOPT_LOOKUP_STR(reduction, config->args, "-set_reduction", false, false); // option
     1859  PXOPT_LOOKUP_TIME(registered, config->args, "-set_registered", false, false);
     1860  PXOPT_LOOKUP_STR(data_group, config->args, "-set_data_group", false, false);
     1861  PXOPT_LOOKUP_STR(dist_group, config->args, "-set_dist_group", false, false);
     1862  PXOPT_LOOKUP_STR(note, config->args, "-set_note", false, false);
     1863
     1864  PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     1865  PXOPT_LOOKUP_BOOL(reRun, config->args, "-rerun", false);
     1866  PXOPT_LOOKUP_BOOL(newTemplates,config->args,"-new-templates", false);
     1867
     1868  PXOPT_LOOKUP_BOOL(available, config->args, "-available", false);
     1869  PXOPT_LOOKUP_BOOL(pretend, config->args, "-pretend", false);
     1870
     1871  if (!(label)) {
     1872    PXOPT_LOOKUP_STR(label,config->args, "-input_label",true,false);
     1873  }
     1874
     1875  // Organize the config information into queries.
     1876  psString stack1Query = NULL;
     1877  psString stack2Query = NULL;
     1878
     1879  if (psListLength(stack1Where->list)) {
     1880    psString whereClause = psDBGenerateWhereConditionSQL(stack1Where, NULL);
     1881    psStringAppend(&stack1Query, "\n AND %s", whereClause);
     1882    psFree(whereClause);
     1883  } else {
     1884    stack1Query = psStringCopy("\n");
     1885  }
     1886  psFree(stack1Where);
     1887
     1888  if (psListLength(stack2Where->list)) {
     1889    psString whereClause = psDBGenerateWhereConditionSQL(stack2Where, NULL);
     1890    psStringAppend(&stack2Query, "\n AND %s", whereClause);
     1891    psFree(whereClause);
     1892  } else {
     1893    stack2Query = psStringCopy("\n");
     1894  }
     1895  psFree(stack2Where);
     1896
     1897  // don't queue for stacks that have already been diffed unless requested
     1898  psString diffQuery = NULL;
     1899  if (! (reRun || newTemplates) ) {
     1900    psStringAppend(&diffQuery, "\n AND diffExp.diff_id IS NULL");
     1901  } else {
     1902    diffQuery = psStringCopy("\n");
     1903  }
     1904
     1905  // find the distinct set of data_groups and filters
     1906  psString query = pxDataGet("difftool_definestackstack_part0.sql");
     1907  if (!query) {
     1908    psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     1909    return(false);
     1910  }
     1911  psTrace("difftool",1,query,stack2Query,stack1Query,diffQuery,stack1Query);
     1912/*   exit(10); */
     1913
     1914  if (!psDBTransaction(config->dbh)) {
     1915    psError(PS_ERR_UNKNOWN, false, "database error");
     1916    return(false);
     1917  }
     1918
     1919  if (!p_psDBRunQueryF(config->dbh, query, stack2Query, stack1Query, diffQuery, stack1Query)) {
     1920    psError(PS_ERR_UNKNOWN, false, "database error");
     1921    psFree(query);
     1922    if (!psDBRollback(config->dbh)) {
     1923      psError(PS_ERR_UNKNOWN, false, "database error");
     1924    }
     1925    return false;
     1926  }
     1927
     1928  psFree(query);
     1929
     1930  psArray *output = p_psDBFetchResult(config->dbh);
     1931  if (!output) {
     1932    psErrorCode err = psErrorCodeLast();
     1933    switch (err) {
     1934    case PS_ERR_DB_CLIENT:
     1935      psError(PXTOOLS_ERR_SYS, false, "database error");
     1936      break;
     1937    case PS_ERR_DB_SERVER:
     1938      psError(PXTOOLS_ERR_PROG, false, "database error");
     1939      break;
     1940    default:
     1941      psError(PXTOOLS_ERR_PROG, false, "unknown error");
     1942      break;
     1943    }
     1944    if (!psDBRollback(config->dbh)) {
     1945      psError(PS_ERR_UNKNOWN, false, "database error");
     1946    }
     1947    return false;
     1948  }
     1949  if (!psArrayLength(output)) {
     1950    psTrace("difftool", PS_LOG_INFO, "no rows found");
     1951    psFree(output);
     1952    if (!psDBCommit(config->dbh)) {
     1953      psError(PS_ERR_UNKNOWN, false, "database error");
     1954      return false;
     1955    }
     1956    return true;
     1957  }
     1958
     1959  query = pxDataGet("difftool_definestackstack_part1.sql");
     1960  if (pretend) {
     1961    // negative simple so the default is true
     1962    if (!ippdbPrintMetadatas(stdout, output, "diffRunTemp", !simple)) {
     1963      psError(PS_ERR_UNKNOWN, false, "failed to print array");
     1964      psFree(output);
     1965      return false;
     1966    }
     1967    psFree(output);
     1968    return true;
     1969  }
     1970
     1971  psArray *list = psArrayAllocEmpty(16); // List of runs defined, to print
     1972  for (long i = 0; i < output->n; i++) {
     1973    psMetadata *row = output->data[i]; // Output row from query
     1974    bool mdok;                      // Status of MD lookup
     1975
     1976    psString tess_id = psMetadataLookupStr(&mdok,row,"INPUT_tess_id");
     1977    psString this_data_group = psMetadataLookupStr(&mdok,row,"INPUT_data_group");
     1978    psString this_dist_group = psMetadataLookupStr(&mdok,row,"INPUT_dist_group");
     1979    psString this_label = psMetadataLookupStr(&mdok,row,"INPUT_label");
     1980
     1981    psString this_stack1Query = psStringCopy(stack1Query);
     1982
     1983    psString thisWhere = psDBGenerateWhereConditionSQL(row,NULL);
     1984    psStringSubstitute(&thisWhere,"stackRun.","INPUT_");
     1985    psStringAppend(&this_stack1Query,"\n AND %s", thisWhere);
     1986    psFree(thisWhere);
     1987
     1988    psTrace("difftool",1, query,stack2Query,this_stack1Query,diffQuery,this_stack1Query);
     1989    if (!psDBTransaction(config->dbh)) {
     1990      psError(PS_ERR_UNKNOWN, false, "database error");
     1991      return(false);
     1992    }
     1993
     1994    if (!p_psDBRunQueryF(config->dbh, query, stack2Query, this_stack1Query, diffQuery, this_stack1Query)) {
     1995      psError(PS_ERR_UNKNOWN, false, "database error");
     1996      psFree(query);
     1997      if (!psDBRollback(config->dbh)) {
     1998        psError(PS_ERR_UNKNOWN, false, "database error");
     1999      }
     2000      return false;
     2001    }
     2002    psFree(this_stack1Query);
     2003
     2004    psArray *diff_id_output = p_psDBFetchResult(config->dbh);
     2005    if (!diff_id_output) {
     2006      psErrorCode err = psErrorCodeLast();
     2007      switch (err) {
     2008      case PS_ERR_DB_CLIENT:
     2009        psError(PXTOOLS_ERR_SYS, false, "database error");
     2010        break;
     2011      case PS_ERR_DB_SERVER:
     2012        psError(PXTOOLS_ERR_PROG, false, "database error");
     2013        break;
     2014      default:
     2015        psError(PXTOOLS_ERR_PROG, false, "unknown error");
     2016        break;
     2017      }
     2018      if (!psDBRollback(config->dbh)) {
     2019        psError(PS_ERR_UNKNOWN, false, "database error");
     2020      }
     2021      return false;
     2022    }
     2023    if (!psArrayLength(diff_id_output)) {
     2024      psTrace("difftool", PS_LOG_INFO, "no rows found");
     2025      psFree(diff_id_output);
     2026      if (!psDBCommit(config->dbh)) {
     2027        psError(PS_ERR_UNKNOWN, false, "database error");
     2028        return false;
     2029      }
     2030      return true;
     2031    }
     2032
     2033    // ok we've got one create the diffRun
     2034    diffRunRow *run = diffRunRowAlloc(
     2035                                      0,          // ID
     2036                                      "reg",      // state
     2037                                      workdir,
     2038                                      label ? label : this_label,
     2039                                      data_group ? data_group : this_data_group,
     2040                                      dist_group ? dist_group : this_dist_group,
     2041                                      reduction,
     2042                                      NULL,       // dvodb
     2043                                      registered,
     2044                                      tess_id,
     2045                                      false,                 // bothways
     2046                                      false,                 // exposure
     2047                                      0,       // magicked
     2048                                      IPP_DIFF_MODE_STACK_STACK, // diff_mode
     2049                                      note
     2050                                      );
     2051    // Commit to database
     2052    if (!diffRunInsertObject(config->dbh, run)) {
     2053      psError(PS_ERR_UNKNOWN, false, "database error");
     2054      psFree(run);
     2055      if (!psDBRollback(config->dbh)) {
     2056        psError(PS_ERR_UNKNOWN, false, "database error");
     2057      }
     2058      return false;
     2059    }
     2060/*     diffRunPrintObject(stdout,run,1); */
     2061    run->diff_id = psDBLastInsertID(config->dbh);
     2062    for (long j = 0; j < diff_id_output->n; j++) {
     2063      psMetadata *input_row = diff_id_output->data[j]; // Output row from query
     2064      bool mdok;
     2065      psString in_skycell_id  = psMetadataLookupStr(&mdok,input_row,"skycell_id");
     2066      psS64 in_input_stack_id = psMetadataLookupS64(&mdok,input_row,"stack_id");
     2067      psS64 in_template_stack_id = psMetadataLookupS64(&mdok,input_row,"max_stack_id");
     2068      psString in_tess_id = psMetadataLookupStr(&mdok,input_row,"tess_id");
     2069      psTrace("difftool",1,"%s %" PRId64 " %" PRId64 " %s\n",
     2070              in_skycell_id, in_input_stack_id, in_template_stack_id, in_tess_id);
     2071      diffInputSkyfileRow *input = diffInputSkyfileRowAlloc(
     2072                                                            run->diff_id,   // ID
     2073                                                            in_skycell_id,
     2074                                                            PS_MAX_S64, // warp1_id -> NULL
     2075                                                            in_input_stack_id, // stack1
     2076                                                            PS_MAX_S64, // warp2_id -> NULL
     2077                                                            in_template_stack_id, // stack2
     2078                                                            in_tess_id,
     2079                                                            0 // diff_skyfile_id
     2080                                                            );
     2081      // Commit to database the input
     2082      if (!diffInputSkyfileInsertObject(config->dbh, input)) {
     2083        psError(PS_ERR_UNKNOWN, false, "database error");
     2084        psFree(input);
     2085        if (!psDBRollback(config->dbh)) {
     2086          psError(PS_ERR_UNKNOWN, false, "database error");
     2087        }
     2088        return false;
     2089      }
     2090
     2091/*       diffInputSkyfilePrintObject(stdout,input,1); */
     2092      psFree(input);
     2093    }
     2094
     2095    if (!setdiffRunState(config, run->diff_id, "new", false)) {
     2096        psError(PS_ERR_UNKNOWN, false, "failed to change diffRun.state for diff_id: %" PRId64, run->diff_id);
     2097        psFree(stack1Query);
     2098        psFree(stack2Query);
     2099        psFree(diffQuery);
     2100        psFree(run);
     2101        psFree(list);
     2102        if (!psDBRollback(config->dbh)) {
     2103            psError(PS_ERR_UNKNOWN, false, "database error");
     2104        }
     2105        return false;
     2106    }
     2107    psArrayAdd(list, list->n, run);
     2108    psFree(run);
     2109  }
     2110
     2111  if (!psDBCommit(config->dbh)) {
     2112    psError(PS_ERR_UNKNOWN, false, "database error");
     2113    psFree(list);
     2114    return false;
     2115  }
     2116
     2117  if (!diffRunPrintObjects(stdout, list, !simple)) {
     2118    psError(PS_ERR_UNKNOWN, false, "failed to print object");
     2119    psFree(list);
     2120    return false;
     2121  }
     2122
     2123  psFree(query);
     2124  psFree(stack1Query);
     2125  psFree(stack2Query);
     2126  psFree(diffQuery);
     2127  psFree(output);
     2128  psFree(list);
     2129
     2130    if (!psDBCommit(config->dbh)) {
     2131        psError(PS_ERR_UNKNOWN, false, "database error");
     2132        psFree(list);
     2133        return false;
     2134    }
     2135
     2136  return(true);
     2137}
    16082138
    16092139static bool pendingcleanuprunMode(pxConfig *config)
     
    16192149    psString query = pxDataGet("difftool_pendingcleanuprun.sql");
    16202150    if (!query) {
    1621         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
    1622         return false;
    1623     }
     2151        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     2152        return false;
     2153    }
     2154    // pxDataGet/psStringSubstitute workaround
     2155    psString queryCopy = psStringCopy(query);
     2156    psFree(query);
     2157    query = queryCopy;
    16242158
    16252159    if (where && psListLength(where->list)) {
    16262160        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
    1627         psStringAppend(&query, " AND %s", whereClause);
     2161        psStringAppend(&whereClause, " AND ");
     2162        psStringSubstitute(&query,whereClause,"@INNERCONSTRAINT@");
    16282163        psFree(whereClause);
     2164    }
     2165    else {
     2166      psStringSubstitute(&query,NULL,"@INNERCONSTRAINT@");
    16292167    }
    16302168    psFree(where);
     
    16362174        psFree(limitString);
    16372175    }
    1638 
     2176    //    fprintf(stderr,"%s",query);
     2177
     2178    //fprintf(stderr,"%s",query);
    16392179    if (!p_psDBRunQuery(config->dbh, query)) {
    16402180        psError(PS_ERR_UNKNOWN, false, "database error");
     
    16842224    psString query = pxDataGet("difftool_pendingcleanupskyfile.sql");
    16852225    if (!query) {
    1686         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     2226        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
    16872227        return false;
    16882228    }
     
    17442284    psString query = pxDataGet("difftool_donecleanup.sql");
    17452285    if (!query) {
    1746         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     2286        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
    17472287        return false;
    17482288    }
     
    17992339    psMetadata *where = psMetadataAlloc();
    18002340    PXOPT_COPY_S64(config->args, where, "-diff_id",   "diff_id",   "==");
     2341    PXOPT_COPY_STR(config->args, where, "-skycell_id", "skycell_id",   "==");
    18012342
    18022343    if (!pxSetFaultCode(config->dbh, "diffSkyfile", where, fault)) {
     
    18102351}
    18112352
    1812 static bool diffRunComplete(pxConfig *config)
    1813 {
    1814     PS_ASSERT_PTR_NON_NULL(config, false);
    1815 
    1816     // look for completed diffRuns
    1817     psString query = pxDataGet("difftool_completed_runs.sql");
    1818     if (!query) {
    1819         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
    1820         return false;
    1821     }
    1822 
    1823     if (!p_psDBRunQuery(config->dbh, query)) {
    1824         psError(PS_ERR_UNKNOWN, false, "database error");
    1825         psFree(query);
    1826         return false;
    1827     }
    1828     psFree(query);
    1829 
    1830     psArray *output = p_psDBFetchResult(config->dbh);
    1831     if (!output) {
    1832         psError(PS_ERR_UNKNOWN, false, "database error");
    1833         return false;
    1834     }
    1835     if (!psArrayLength(output)) {
    1836         psTrace("difftool", PS_LOG_INFO, "no rows found");
    1837         psFree(output);
    1838         return true;
    1839     }
    1840     for (long i = 0; i < psArrayLength(output); i++) {
    1841         psMetadata *row = output->data[i];
    1842 
    1843         psS64 diff_id = psMetadataLookupS64(NULL, row, "diff_id");
    1844         psS64 magicked = psMetadataLookupS64(NULL, row, "magicked");
    1845 
    1846         // set diffRun.state to 'stop'
    1847         if (!setdiffRunState(config, diff_id, "full", magicked)) {
    1848             psError(PS_ERR_UNKNOWN, false, "failed to change diffRun.state for diff_id: %" PRId64,
    1849                 diff_id);
    1850             psFree(output);
    1851             return false;
    1852         }
    1853     }
    1854 
    1855     return true;
    1856 }
     2353static bool change_skyfile_data_state(pxConfig *config, psString data_state, psString run_state) {
     2354  PS_ASSERT_PTR_NON_NULL(config, false);
     2355
     2356  // diff_id, skycell_id are required
     2357  PXOPT_LOOKUP_S64(diff_id, config->args, "-diff_id", true, false);
     2358  PXOPT_LOOKUP_STR(skycell_id, config->args, "-skycell_id", true, false);
     2359
     2360
     2361  psS64 magicked = 0;
     2362  if (!strcmp(data_state, "full")) {
     2363      PXOPT_LOOKUP_S64(set_magicked, config->args, "-magicked", 0, false);
     2364      magicked = set_magicked;
     2365  }
     2366
     2367  psString query = pxDataGet("difftool_change_skyfile_data_state.sql");
     2368
     2369  if (!psDBTransaction(config->dbh)) {
     2370    psError(PS_ERR_UNKNOWN, false, "database error");
     2371    return(false);
     2372  }
     2373
     2374  psString set_magicked_skyfile = psStringCopy("");
     2375  psString set_magicked_run = psStringCopy("");
     2376  if (magicked != 0 && !strcmp(data_state, "full")) {
     2377    psStringAppend(&set_magicked_skyfile,  "\n , diffSkyfile.magicked = %" PRId64, magicked);
     2378    psStringAppend(&set_magicked_run,      "\n , diffRun.magicked = %" PRId64, magicked);
     2379
     2380  } else if (!strcmp(data_state, "cleaned") || !strcmp(data_state, "purged")) {
     2381    psStringAppend(&set_magicked_skyfile, "\n, diffSkyfile.magicked = IF(diffSkyfile.magicked = 0, 0, -1)");
     2382    psStringAppend(&set_magicked_run, "\n, diffRun.magicked = IF(diffRun.magicked = 0, 0, -1)");
     2383  }
     2384
     2385  // Uses the unconstrained (diffRun.state [NEED NOT EQUAL] run_state) version from warptool.c
     2386
     2387  if (!p_psDBRunQueryF(config->dbh, query, data_state, set_magicked_skyfile, diff_id, skycell_id)) {
     2388    psError(PS_ERR_UNKNOWN, false, "database error");
     2389    // rollback
     2390    if (!psDBRollback(config->dbh)) {
     2391      psError(PS_ERR_UNKNOWN, false, "database error");
     2392    }
     2393    psError(PS_ERR_UNKNOWN, false, "database error");
     2394    psFree(set_magicked_skyfile);
     2395    return(false);
     2396  }
     2397  psFree(set_magicked_skyfile);
     2398  psFree(query);
     2399
     2400  query = pxDataGet("difftool_change_run_state.sql");
     2401  if (!p_psDBRunQueryF(config->dbh, query, data_state, set_magicked_run, diff_id, data_state)) {
     2402    // rollback
     2403    if (!psDBRollback(config->dbh)) {
     2404      psError(PS_ERR_UNKNOWN, false, "database error");
     2405    }
     2406    psError(PS_ERR_UNKNOWN, false, "database error");
     2407    psFree(set_magicked_run);
     2408    return(false);
     2409  }
     2410
     2411  if (!psDBCommit(config->dbh)) {
     2412    psError(PS_ERR_UNKNOWN, false, "database error");
     2413    psFree(set_magicked_run);
     2414    return(false);
     2415  }
     2416  psFree(set_magicked_run);
     2417
     2418  return(true);
     2419}
     2420
     2421static bool tocleanedskyfileMode(pxConfig *config) {
     2422  return change_skyfile_data_state(config, "cleaned","goto_cleaned");
     2423}
     2424static bool topurgedskyfileMode(pxConfig *config) {
     2425  return change_skyfile_data_state(config, "purged", "goto_purged");
     2426}
     2427static bool toscrubbedskyfileMode(pxConfig *config) {
     2428  return change_skyfile_data_state(config, "scrubbed", "goto_scrubbed");
     2429}
     2430static bool tofullskyfileMode(pxConfig *config) {
     2431  return change_skyfile_data_state(config, "full", "update");
     2432}
     2433
    18572434
    18582435bool exportrunMode(pxConfig *config)
     
    18782455  }
    18792456
     2457  if (!pxExportVersion(config, f)) {
     2458    psError(PS_ERR_UNKNOWN, false, "failed to write dbversion output file");
     2459    return false;
     2460  }
    18802461  psMetadata *where = psMetadataAlloc();
    18812462  PXOPT_COPY_S64(config->args, where, "-diff_id", "diff_id", "==");
     
    18902471    psString query = pxDataGet(tables[i].sqlFilename);
    18912472    if (!query) {
    1892       psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     2473      psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
    18932474      return false;
    18942475    }
     
    19692550  psMetadata *input = psMetadataConfigRead (NULL, &nFail, infile, false);
    19702551
    1971   fprintf (stdout, "---- input ----\n");
     2552#ifdef notdef
     2553  fprintf (stderr, "---- input ----\n");
    19722554  psMetadataPrint (stderr, input, 1);
    1973 
     2555#endif
     2556
     2557  if (!pxCheckImportVersion(config, input)) {
     2558      psError(PS_ERR_UNKNOWN, false, "pxCheckImportVersion failed");
     2559      return false;
     2560  }
    19742561  psMetadataItem *item = psMetadataLookup (input, "diffRun");
    19752562  psAssert (item, "entry not in input?");
     
    20212608  return true;
    20222609}
     2610
     2611static bool listrunMode(pxConfig *config)
     2612{
     2613    PS_ASSERT_PTR_NON_NULL(config, false);
     2614
     2615    psMetadata *where = psMetadataAlloc();
     2616    PXOPT_COPY_S64(config->args, where,  "-diff_id", "diffRun.diff_id", "==");
     2617    PXOPT_COPY_STR(config->args, where, "-tess_id", "diffRun.tess_id", "==");
     2618    PXOPT_COPY_S64(config->args, where,  "-magicked", "diffRun.magicked", "==");
     2619    pxAddLabelSearchArgs (config, where, "-label", "diffRun.label", "LIKE");
     2620    pxAddLabelSearchArgs (config, where, "-data_group", "diffRun.data_group", "LIKE");
     2621    pxAddLabelSearchArgs (config, where, "-dist_group", "diffRun.dist_group", "LIKE");
     2622
     2623    PXOPT_LOOKUP_BOOL(template, config->args, "-template", false);
     2624    if (!template) {
     2625        PXOPT_COPY_S64(config->args, where, "-exp_id", "rawInput.exp_id", "==");
     2626        PXOPT_COPY_STR(config->args, where, "-exp_name", "rawInput.exp_name", "==");
     2627        PXOPT_COPY_STR(config->args, where, "-warp_id", "warpInput.warp_id", "==");
     2628        PXOPT_COPY_TIME(config->args, where, "-dateobs_begin", "rawInput.dateobs",  ">=");
     2629        PXOPT_COPY_TIME(config->args, where, "-dateobs_end",   "rawInput.dateobs",  "<=");
     2630        PXOPT_COPY_STR(config->args, where, "-filter",     "rawInput.filter", "LIKE");
     2631    } else {
     2632        PXOPT_COPY_S64(config->args, where, "-exp_id", "rawTemplate.exp_id", "==");
     2633        PXOPT_COPY_STR(config->args, where, "-exp_name", "rawTemplate.exp_name", "==");
     2634        PXOPT_COPY_STR(config->args, where, "-warp_id", "warpTemplate.warp_id", "==");
     2635        PXOPT_COPY_TIME(config->args, where, "-dateobs_begin", "rawTemplate.dateobs",  ">=");
     2636        PXOPT_COPY_TIME(config->args, where, "-dateobs_end",   "rawTemplate.dateobs",  "<=");
     2637        PXOPT_COPY_STR(config->args, where, "-filter",     "rawTemplate.filter", "LIKE");
     2638    }
     2639
     2640    PXOPT_LOOKUP_BOOL(all, config->args, "-all", false);
     2641    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     2642    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     2643    PXOPT_LOOKUP_BOOL(pstamp_order, config->args, "-pstamp_order", false);
     2644
     2645
     2646    psString where2 = NULL;
     2647    pxmagicAddWhere(config, &where2, "diffRun");
     2648    pxspaceAddWhere(config, &where2, template ? "rawTemplate" : "rawInput");
     2649    psString query = pxDataGet("difftool_listrun.sql");
     2650    if (!query) {
     2651        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     2652        return false;
     2653    }
     2654
     2655    if (psListLength(where->list)) {
     2656        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     2657        psStringAppend(&query, " WHERE %s", whereClause);
     2658        psFree(whereClause);
     2659    } else if (where2) {
     2660        psStringAppend(&query, " WHERE diffRun.diff_id is not null %s", where2);
     2661    } else if (!all) {
     2662        psError(PXTOOLS_ERR_CONFIG, true, "search parameters or -all are required");
     2663        return false;
     2664    }
     2665    psFree(where);
     2666
     2667    if (pstamp_order) {
     2668        if (template) {
     2669            psStringAppend(&query, " ORDER BY rawTemplate.exp_id, diff_id DESC");
     2670        } else {
     2671            psStringAppend(&query, " ORDER BY rawInput.exp_id, diff_id DESC");
     2672        }
     2673    }
     2674           
     2675    // treat limit == 0 as "no limit"
     2676    if (limit) {
     2677        psString limitString = psDBGenerateLimitSQL(limit);
     2678        psStringAppend(&query, " %s", limitString);
     2679        psFree(limitString);
     2680    }
     2681
     2682    if (!p_psDBRunQuery(config->dbh, query)) {
     2683        psError(PS_ERR_UNKNOWN, false, "database error");
     2684        psFree(query);
     2685        return false;
     2686    }
     2687    psFree(query);
     2688
     2689    psArray *output = p_psDBFetchResult(config->dbh);
     2690    if (!output) {
     2691        psErrorCode err = psErrorCodeLast();
     2692        switch (err) {
     2693            case PS_ERR_DB_CLIENT:
     2694                psError(PXTOOLS_ERR_SYS, false, "database error");
     2695            case PS_ERR_DB_SERVER:
     2696                psError(PXTOOLS_ERR_PROG, false, "database error");
     2697            default:
     2698                psError(PXTOOLS_ERR_PROG, false, "unknown error");
     2699        }
     2700
     2701        return false;
     2702    }
     2703    if (!psArrayLength(output)) {
     2704        psTrace("difftool", PS_LOG_INFO, "no rows found");
     2705        psFree(output);
     2706        return true;
     2707    }
     2708
     2709    if (psArrayLength(output)) {
     2710        // negative simple so the default is true
     2711        if (!ippdbPrintMetadatas(stdout, output, "diffRun", !simple)) {
     2712            psError(PS_ERR_UNKNOWN, false, "failed to print array");
     2713            psFree(output);
     2714            return false;
     2715        }
     2716    }
     2717
     2718    psFree(output);
     2719
     2720    return true;
     2721}
     2722// a very specfic function to queue a cleaned warpSkyfile to be updated
     2723static bool setskyfiletoupdateMode(pxConfig *config)
     2724{
     2725    PS_ASSERT_PTR_NON_NULL(config, NULL);
     2726
     2727    PXOPT_LOOKUP_S64(diff_id, config->args, "-diff_id", true, false);
     2728    PXOPT_LOOKUP_STR(skycell_id, config->args, "-skycell_id", false, false);
     2729    PXOPT_LOOKUP_STR(label, config->args, "-set_label", false, false);
     2730
     2731    psString query = pxDataGet("difftool_setskyfiletoupdate.sql");
     2732    if (!query) {
     2733        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     2734        return false;
     2735    }
     2736
     2737    psString setHook = psStringCopy("");
     2738    if (label) {
     2739        psStringAppend(&setHook, "\n , diffRun.label = '%s'", label);
     2740    }
     2741
     2742    if (skycell_id) {
     2743        psStringAppend(&query, " AND (diffSkyfile.skycell_id = '%s')", skycell_id);
     2744    }
     2745
     2746    if (!p_psDBRunQueryF(config->dbh, query, setHook, diff_id)) {
     2747        psError(PS_ERR_UNKNOWN, false, "database error");
     2748        return false;
     2749    }
     2750
     2751    psFree(setHook);
     2752    psFree(query);
     2753
     2754    return true;
     2755}
Note: See TracChangeset for help on using the changeset viewer.