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/magicdstool.c

    r25015 r27840  
    3333
    3434static bool definebyqueryMode(pxConfig *config);
    35 static psS64 definerunMode(pxConfig *config);
     35static bool definecopyMode(pxConfig *config);
    3636static bool updaterunMode(pxConfig *config);
    3737static bool todestreakMode(pxConfig *config);
    3838static bool adddestreakedfileMode(pxConfig *config);
     39static bool advancerunMode(pxConfig *config);
    3940static bool revertdestreakedfileMode(pxConfig *config);
     41static bool clearstatefaultsMode(pxConfig *config);
    4042static bool getskycellsMode(pxConfig *config);
    4143static bool toremoveMode(pxConfig *config);
    42 static bool torestoreMode(pxConfig *config);
    4344static bool torevertMode(pxConfig *config);
    44 
    45 static bool setmagicDSRunState(pxConfig *config, psS64 magic_id, const char *state);
    46 static bool magicDSRunComplete(pxConfig *config, bool setmagicked);
    47 static bool magicDSGetIDs(pxConfig *config, psString stage, psS64 magic_id, psS64 *stage_id, psS64 *cam_id);
     45static bool completedrevertMode(pxConfig *config);
     46static bool tocleanupMode(pxConfig *config);
     47
     48static bool setmagicDSRunState(pxConfig *config, psS64 magic_id, psString extraSetString, psMetadata *where, const char *state);
    4849
    4950# define MODECASE(caseName, func) \
     
    6667    switch (config->mode) {
    6768        MODECASE(MAGICDSTOOL_MODE_DEFINEBYQUERY,       definebyqueryMode);
    68         MODECASE(MAGICDSTOOL_MODE_DEFINERUN,           definerunMode);
     69        MODECASE(MAGICDSTOOL_MODE_DEFINECOPY,          definecopyMode);
    6970        MODECASE(MAGICDSTOOL_MODE_UPDATERUN,           updaterunMode);
    7071        MODECASE(MAGICDSTOOL_MODE_TODESTREAK,          todestreakMode);
    7172        MODECASE(MAGICDSTOOL_MODE_ADDDESTREAKEDFILE,   adddestreakedfileMode);
     73        MODECASE(MAGICDSTOOL_MODE_ADVANCERUN,          advancerunMode);
    7274        MODECASE(MAGICDSTOOL_MODE_REVERTDESTREAKEDFILE,revertdestreakedfileMode);
     75        MODECASE(MAGICDSTOOL_MODE_CLEARSTATEFAULTS,    clearstatefaultsMode);
    7376        MODECASE(MAGICDSTOOL_MODE_GETSKYCELLS,         getskycellsMode);
    7477        MODECASE(MAGICDSTOOL_MODE_TOREMOVE,            toremoveMode);
    75         MODECASE(MAGICDSTOOL_MODE_TORESTORE,           torestoreMode);
    7678        MODECASE(MAGICDSTOOL_MODE_TOREVERT,            torevertMode);
     79        MODECASE(MAGICDSTOOL_MODE_COMPLETEDREVERT,     completedrevertMode);
     80        MODECASE(MAGICDSTOOL_MODE_TOCLEANUP,           tocleanupMode);
    7781        default:
    7882            psAbort("invalid option (this should not happen)");
     
    105109    PXOPT_LOOKUP_STR(workdir, config->args, "-workdir", false, false);
    106110    PXOPT_LOOKUP_STR(recoveryroot, config->args, "-recoveryroot", false, false);
    107     PXOPT_LOOKUP_BOOL(re_place, config->args, "-replace", false);
     111    PXOPT_LOOKUP_BOOL(noreplace, config->args, "-noreplace", false);
    108112    PXOPT_LOOKUP_STR(set_label, config->args, "-set_label", false, false);
     113    PXOPT_LOOKUP_STR(set_data_group, config->args, "-set_data_group", false, false);
     114    PXOPT_LOOKUP_STR(note, config->args, "-set_note", false, false);
    109115    PXOPT_LOOKUP_BOOL(rerun, config->args, "-rerun", false);
    110     PXOPT_LOOKUP_BOOL(dry_run, config->args, "-dry_run", false);
     116    PXOPT_LOOKUP_BOOL(pretend, config->args, "-pretend", false);
    111117    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
    112118    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     
    119125    PXOPT_COPY_S64(config->args, where, "-warp_id", "warp_id", "==");
    120126    PXOPT_COPY_S64(config->args, where, "-diff_id", "diff_id", "==");
    121     PXOPT_COPY_S64(config->args, where, "-magic_id","magic_id", "==");
     127    PXOPT_COPY_S64(config->args, where, "-magic_id","magicRun.magic_id", "==");
    122128    PXOPT_COPY_S32(config->args, where, "-streaks_max","streaks", "<=");
    123129
    124     pxAddLabelSearchArgs (config, where, "-label", "magicRun.label", "==");
     130    pxAddLabelSearchArgs (config, where, "-label", "magicRun.label", "=="); // define using magicRun label
    125131
    126132    ippStage stageNum = ippStringToStage(stage);
    127    
     133
    128134    psString query = NULL;
    129135    switch (stageNum) {
     
    145151    case IPP_STAGE_FAKE:
    146152    case IPP_STAGE_STACK:
    147         psError(PXTOOLS_ERR_DATA, true, "%sRuns do not need to be destreaked", stage);
     153        psError(PXTOOLS_ERR_CONFIG, true, "%sRuns do not need to be destreaked", stage);
    148154        return false;
    149155    case IPP_STAGE_NONE:
    150         psError(PXTOOLS_ERR_DATA, true, "%s is not a valid stage", stage);
     156        psError(PXTOOLS_ERR_CONFIG, true, "%s is not a valid stage", stage);
    151157        return false;
    152158    default:
     
    157163
    158164    if (!query) {
    159         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     165        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
    160166        return false;
    161167    }
     
    231237    // Parse the list of runs ready to be destreaked
    232238
    233     if (!dry_run && !psDBTransaction(config->dbh)) {
     239    if (!pretend && !psDBTransaction(config->dbh)) {
    234240        psError(PS_ERR_UNKNOWN, false, "database error");
    235241        return false;
     
    245251        psS64 cam_id = psMetadataLookupS64(NULL, row, "cam_id");
    246252        psString magicRunLabel = psMetadataLookupStr(NULL, row, "label");
     253        psString magicRunDataGroup = psMetadataLookupStr(NULL, row, "data_group");
    247254        psString magicRunWorkdir = psMetadataLookupStr(NULL, row, "workdir");
    248        
     255
    249256        // if workdir is not supplied use the magicRun's
    250257        if (!workdir) {
     
    266273                cam_id,
    267274                set_label ? set_label : magicRunLabel,
     275                set_data_group ? set_data_group : magicRunDataGroup,
    268276                outroot,
    269277                recoveryroot,
    270                 re_place,
    271                 0); // remove
     278                noreplace ? 0 :1,   // re_place
     279                0,      // remove
     280                0,      // fault
     281                note);  // remove
    272282
    273283        psFree(outroot);
     
    276286        }
    277287
    278         if (!dry_run) {
     288        if (!pretend) {
    279289            if (!magicDSRunInsertObject(config->dbh, run)) {
    280290                psError(PS_ERR_UNKNOWN, false, "database error");
     
    295305    }
    296306
    297     if (!dry_run && !psDBCommit(config->dbh)) {
     307    if (!pretend && !psDBCommit(config->dbh)) {
    298308        psError(PS_ERR_UNKNOWN, false, "database error");
    299309        return false;
     
    312322}
    313323
    314 static psS64 definerunMode(pxConfig *config)
     324
     325// XXX This currently allows multiple destreak runs to be queued on the same exposure if there are multiple
     326// magicRuns selected!
     327static bool definecopyMode(pxConfig *config)
     328{
     329    // Required
     330    PXOPT_LOOKUP_STR(stage, config->args, "-stage", true, false);
     331    PXOPT_LOOKUP_STR(workdir, config->args, "-workdir", true, false);
     332
     333    // Optional
     334    PXOPT_LOOKUP_STR(recoveryroot, config->args, "-recoveryroot", false, false);
     335    PXOPT_LOOKUP_BOOL(noreplace, config->args, "-noreplace", false);
     336    PXOPT_LOOKUP_STR(set_label, config->args, "-set_label", false, false);
     337    PXOPT_LOOKUP_STR(set_data_group, config->args, "-set_data_group", false, false);
     338    PXOPT_LOOKUP_STR(note, config->args, "-set_note", false, false);
     339    PXOPT_LOOKUP_BOOL(rerun, config->args, "-rerun", false);
     340    PXOPT_LOOKUP_BOOL(pretend, config->args, "-pretend", false);
     341    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     342    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     343
     344    // search args
     345    psMetadata *where = psMetadataAlloc();
     346    PXOPT_COPY_S64(config->args, where, "-exp_id",  "chipRun.exp_id", "==");
     347    PXOPT_COPY_S64(config->args, where, "-chip_id", "chipRun.chip_id", "==");
     348    PXOPT_COPY_S64(config->args, where, "-cam_id",  "camRun.cam_id", "==");
     349    PXOPT_COPY_S64(config->args, where, "-warp_id", "warpRun.warp_id", "==");
     350    PXOPT_COPY_S64(config->args, where, "-diff_id", "diffRun.diff_id", "==");
     351    PXOPT_COPY_S64(config->args, where, "-magic_id", "magicRun.magic_id", "==");
     352    PXOPT_COPY_S32(config->args, where, "-streaks_max", "magicMask.streaks", "<=");
     353
     354    pxAddLabelSearchArgs (config, where, "-magic_label", "magicRun.label", "=="); // define magic label
     355    psString labelName = NULL;                                                    // Name of label
     356    psStringAppend(&labelName, "%sRun.label", stage);
     357    pxAddLabelSearchArgs (config, where, "-stage_label", labelName, "=="); // define stageRun label
     358    psFree(labelName);
     359
     360    ippStage stageNum = ippStringToStage(stage);
     361
     362    psString query = NULL;
     363    switch (stageNum) {
     364      case IPP_STAGE_RAW:
     365        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Raw stage is not appropriate for a copied destreak");
     366        return false;
     367      case IPP_STAGE_CHIP:
     368        query = pxDataGet("magicdstool_definecopy_chip.sql");
     369        break;
     370      case IPP_STAGE_WARP:
     371        query = pxDataGet("magicdstool_definecopy_warp.sql");
     372        break;
     373      case IPP_STAGE_CAMERA:
     374      case IPP_STAGE_DIFF:
     375      case IPP_STAGE_FAKE:
     376        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "%s has not been coded.", stage);
     377        return false;
     378      case IPP_STAGE_STACK:
     379        psError(PXTOOLS_ERR_CONFIG, true, "Stacks do not need to be destreaked");
     380        return false;
     381      case IPP_STAGE_NONE:
     382        psError(PXTOOLS_ERR_CONFIG, true, "%s is not a valid stage", stage);
     383        return false;
     384      default:
     385        psError(PXTOOLS_ERR_PROG, true, "ippStageToString returned %d for invalid stage %s",
     386                stageNum, stage);
     387        return false;
     388    }
     389
     390    if (!query) {
     391        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     392        return false;
     393    }
     394    const char *rerun_flag =  rerun ? "" : "\n"; // String to give query to activate (or not) rerun
     395
     396    if (stageNum != IPP_STAGE_DIFF) {
     397        if (psListLength(where->list)) {
     398            psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     399            psStringAppend(&query, "\nAND %s", whereClause);
     400            psFree(whereClause);
     401        }
     402        psFree(where);
     403
     404        // treat limit == 0 as "no limit"
     405        if (limit) {
     406            psString limitString = psDBGenerateLimitSQL(limit);
     407            psStringAppend(&query, " %s", limitString);
     408            psFree(limitString);
     409        }
     410        if (!p_psDBRunQueryF(config->dbh, query, set_label, rerun_flag)) {
     411            psError(PS_ERR_UNKNOWN, false, "database error");
     412            psFree(query);
     413            return false;
     414        }
     415    } else {
     416        // diff stage query has two types bothways and !bothways
     417        // so we need to send the rerun flag and the where data twice
     418        psString whereString = psStringCopy("");
     419        if (psListLength(where->list)) {
     420            psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     421            psStringAppend(&whereString, "\nAND %s", whereClause);
     422            psFree(whereClause);
     423        }
     424        psFree(where);
     425
     426        // treat limit == 0 as "no limit"
     427        if (limit) {
     428            psString limitString = psDBGenerateLimitSQL(limit);
     429            psStringAppend(&query, " %s", limitString);
     430            psFree(limitString);
     431        }
     432
     433        if (!p_psDBRunQueryF(config->dbh, query, rerun_flag, whereString, rerun_flag, whereString)) {
     434            psError(PS_ERR_UNKNOWN, false, "database error");
     435            psFree(whereString);
     436            psFree(query);
     437            return false;
     438        }
     439        psFree(whereString);
     440    }
     441    psFree(query);
     442
     443    psArray *output = p_psDBFetchResult(config->dbh);
     444    if (!output) {
     445        psErrorCode err = psErrorCodeLast();
     446        switch (err) {
     447          case PS_ERR_DB_CLIENT:
     448            psError(PXTOOLS_ERR_SYS, false, "database error");
     449          case PS_ERR_DB_SERVER:
     450            psError(PXTOOLS_ERR_PROG, false, "database error");
     451          default:
     452            psError(PXTOOLS_ERR_PROG, false, "unknown error");
     453        }
     454
     455        return false;
     456    }
     457    if (!psArrayLength(output)) {
     458        psTrace("magictool", PS_LOG_INFO, "no rows found");
     459        psFree(output);
     460        return true;
     461    }
     462
     463    // Parse the list of runs ready to be destreaked
     464
     465    if (!pretend && !psDBTransaction(config->dbh)) {
     466        psError(PS_ERR_UNKNOWN, false, "database error");
     467        return false;
     468    }
     469
     470    psArray *list = psArrayAllocEmpty(16); // List of runs, to print
     471    for (long i = 0; i < psArrayLength(output); i++) {
     472        psMetadata *row = output->data[i]; // Row of interest
     473        psS64 stage_id = psMetadataLookupS64(NULL, row, "stage_id");
     474        psS64 exp_id = psMetadataLookupS64(NULL, row, "exp_id");
     475        psS64 magic_id = psMetadataLookupS64(NULL, row, "magic_id");
     476        psS64 inv_magic_id = psMetadataLookupS64(NULL, row, "inv_magic_id");
     477        psS64 cam_id = psMetadataLookupS64(NULL, row, "cam_id");
     478        psString magicRunLabel = psMetadataLookupStr(NULL, row, "label");
     479        psString magicRunDataGroup = psMetadataLookupStr(NULL, row, "data_group");
     480
     481        psString outroot = NULL;
     482        // set outroot to workdir/exp_id/stage for example /somewhere/424242/chip
     483        psStringAppend(&outroot, "%s/%" PRId64 "/%s", workdir, exp_id, stage);
     484
     485        // create a new magicRun for this group
     486        magicDSRunRow *run = magicDSRunRowAlloc(
     487                0, // magic_ds_id
     488                magic_id,
     489                inv_magic_id,
     490                "new",
     491                stage,
     492                stage_id,
     493                cam_id,
     494                set_label ? set_label : magicRunLabel,
     495                set_data_group ? set_data_group : magicRunDataGroup,
     496                outroot,
     497                recoveryroot,
     498                noreplace ? 0 :1,   // re_place
     499                0,      // remove
     500                0,      // fault
     501                note);  // remove
     502
     503        psFree(outroot);
     504        if (!run) {
     505            psAbort("failed to alloc magicDSRun object");
     506        }
     507
     508        if (!pretend) {
     509            if (!magicDSRunInsertObject(config->dbh, run)) {
     510                psError(PS_ERR_UNKNOWN, false, "database error");
     511                psFree(run);
     512                psFree(output);
     513                psFree(list);
     514                if (!psDBRollback(config->dbh)) {
     515                    psError(PS_ERR_UNKNOWN, false, "database error");
     516                }
     517                return false;
     518            }
     519            psS64 magic_ds_id = psDBLastInsertID(config->dbh); // Assigned identifier
     520            run->magic_ds_id = magic_ds_id;
     521        }
     522
     523        psArrayAdd(list, list->n, run);
     524        psFree(run);
     525    }
     526
     527    if (!pretend && !psDBCommit(config->dbh)) {
     528        psError(PS_ERR_UNKNOWN, false, "database error");
     529        return false;
     530    }
     531    psFree(output);
     532
     533    if (!magicDSRunPrintObjects(stdout, list, !simple)) {
     534        psError(PS_ERR_UNKNOWN, false, "failed to print object");
     535        psFree(list);
     536        return false;
     537    }
     538
     539    psFree(list);
     540
     541    return true;
     542}
     543
     544
     545static bool updaterunMode(pxConfig *config)
    315546{
    316547    PS_ASSERT_PTR_NON_NULL(config, false);
    317548
    318549    // required
    319     PXOPT_LOOKUP_S64(magic_id, config->args, "-magic_id", true, false);
     550    PXOPT_LOOKUP_STR(state, config->args, "-set_state", true, false);
     551
     552    // optional
     553    PXOPT_LOOKUP_STR(set_label, config->args, "-set_label", false, false);
     554    PXOPT_LOOKUP_STR(set_data_group, config->args, "-set_data_group", false, false);
     555    psString setString = NULL;
     556    if (set_label) {
     557        psStringAppend(&setString, ", label = '%s'", set_label);
     558    }
     559    if (set_data_group) {
     560        psStringAppend(&setString, ", data_group = '%s'", set_data_group);
     561    }
     562
     563    PXOPT_LOOKUP_S64(magic_ds_id, config->args, "-magic_ds_id", false, false);
     564    if (magic_ds_id) {
     565
     566        return setmagicDSRunState(config, magic_ds_id, setString, NULL, state);
     567
     568    } else if (!strcmp(state, "full")) {
     569        psError(PS_ERR_UNKNOWN, true, "magic_ds_id is required to update run state to full");
     570        return false;
     571    }
     572    // we can transition by query as well
     573
     574    psMetadata *where = psMetadataAlloc();
     575    PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
     576    PXOPT_COPY_S64(config->args, where, "-stage_id", "stage_id", "==");
     577    PXOPT_COPY_STR(config->args, where, "-stage", "stage", "==");
     578    PXOPT_COPY_STR(config->args, where, "-state", "state", "==");
     579    PXOPT_COPY_STR(config->args, where, "-data_group", "data_group", "LIKE");
     580
     581    if (psListLength(where->list) < 2) {
     582        psError(PS_ERR_UNKNOWN, true, "at least 2 search arguments are required");
     583        return false;
     584    }
     585
     586
     587    PXOPT_LOOKUP_BOOL(noreplace, config->args, "-noreplace", false);
     588    if (!noreplace) {
     589        psMetadataAddS32(where, PS_LIST_TAIL, "re_place", 0, ">", 0);
     590    }
     591    bool result = setmagicDSRunState(config, magic_ds_id, setString, where, state);
     592    psFree(where);
     593
     594    return result;
     595}
     596
     597
     598static bool todestreakMode(pxConfig *config)
     599{
     600    PS_ASSERT_PTR_NON_NULL(config, false);
     601
    320602    PXOPT_LOOKUP_STR(stage, config->args, "-stage", true, false);
    321     PXOPT_LOOKUP_STR(outroot, config->args, "-outroot", true, false);
    322 
    323     // optional
    324     PXOPT_LOOKUP_STR(recoveryroot, config->args, "-recoveryroot", false, false);
    325     PXOPT_LOOKUP_BOOL(re_place, config->args, "-replace", false);
    326     PXOPT_LOOKUP_BOOL(remove, config->args, "-remove", false);
    327     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
    328     PXOPT_LOOKUP_STR(label, config->args, "-label", false, false);
    329 
    330     psS64 stage_id = 0, cam_id = 0;
    331 
    332     if (!magicDSGetIDs(config, stage, magic_id, &stage_id, &cam_id)) {
    333         psError(PS_ERR_UNKNOWN, false, "failed to get ids");
    334         return false;
    335     }
    336 
    337     magicDSRunRow *run = magicDSRunRowAlloc(
    338             0,          // ID
    339             magic_id,
    340             0,          // inv_magic_id
    341             "new",      // state
    342             stage,
    343             stage_id,
    344             cam_id,
    345             label,
    346             outroot,
    347             recoveryroot,
    348             re_place,
    349             remove
    350     );
    351 
    352     if (!run) {
    353         psError(PS_ERR_UNKNOWN, false, "failed to alloc magicRun object");
    354         return false;
    355     }
    356     if (!magicDSRunInsertObject(config->dbh, run)) {
    357         psError(PS_ERR_UNKNOWN, false, "database error");
    358         psFree(run);
    359         return false;
    360     }
    361 
    362     psS64 magic_ds_id = psDBLastInsertID(config->dbh);
    363     run->magic_ds_id = magic_ds_id;
    364 
    365     if (!magicDSRunPrintObject(stdout, run, !simple)) {
    366             psError(PS_ERR_UNKNOWN, false, "failed to print object");
    367             psFree(run);
    368             return false;
    369     }
    370 
    371     psFree(run);
    372 
    373     return magic_id;
    374 }
    375 
    376 
    377 static bool updaterunMode(pxConfig *config)
    378 {
    379     PS_ASSERT_PTR_NON_NULL(config, false);
    380 
    381     // required
    382     PXOPT_LOOKUP_S64(magic_ds_id, config->args, "-magic_ds_id", true, false);
    383     PXOPT_LOOKUP_STR(state, config->args, "-state", true, false);
    384 
    385     if (state) {
    386         // set detRun.state to state
    387         return setmagicDSRunState(config, magic_ds_id, state);
    388     }
    389 
    390     return true;
    391 }
    392 
    393 
    394 static bool todestreakMode(pxConfig *config)
    395 {
    396     PS_ASSERT_PTR_NON_NULL(config, false);
    397603
    398604    psMetadata *where = psMetadataAlloc();
    399     PXOPT_COPY_S64(config->args, where, "-magic_ds_id", "magic_ds_id", "==");
     605    PXOPT_COPY_S64(config->args, where, "-magic_ds_id", "magicDSRun.magic_ds_id", "==");
    400606    PXOPT_COPY_S64(config->args, where, "-magic_id", "magic_id", "==");
    401     pxAddLabelSearchArgs (config, where, "-label", "label", "==");
    402     PXOPT_COPY_STR(config->args, where, "-stage", "stage", "==");
     607    pxAddLabelSearchArgs (config, where, "-label", "magicDSRun.label", "==");
    403608
    404609    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
    405610    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
    406611
    407     // look for "inputs" that need to processed
    408     psString query = pxDataGet("magicdstool_todestreak.sql");
     612    psString sql_file = NULL;
     613    psStringAppend(&sql_file, "magicdstool_todestreak_%s.sql", stage);
     614
     615    psString query = pxDataGet(sql_file);
    409616    if (!query) {
    410         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
    411         return false;
    412     }
     617        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement from %s", sql_file);
     618        psFree(sql_file);
     619        return false;
     620    }
     621    psFree(sql_file);
    413622
    414623    if (psListLength(where->list)) {
    415624        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
    416         psStringAppend(&query, " WHERE %s", whereClause);
     625        psStringAppend(&query, " AND %s", whereClause);
    417626        psFree(whereClause);
    418627    }
     
    472681{
    473682    // first query the magicDSRun to find the stage and the stage_id
    474     psString query = "SELECT stage, stage_id from magicDSRun where magic_ds_id = %" PRId64;
     683    psString query = "SELECT stage, stage_id, magic_id from magicDSRun where magic_ds_id = %" PRId64;
    475684
    476685    if (!p_psDBRunQueryF(config->dbh, query, magic_ds_id)) {
     
    499708    psString stage= psMetadataLookupStr(NULL, row, "stage");
    500709    psS64 stage_id = psMetadataLookupS64(NULL, row, "stage_id");
     710    psS64 magic_id = psMetadataLookupS64(NULL, row, "magic_id");
    501711
    502712    ippStage stageNum = ippStringToStage(stage);
     
    526736    }
    527737
    528     if (!p_psDBRunQueryF(config->dbh, query, magic_ds_id, stage_id, component)) {
     738    if (!p_psDBRunQueryF(config->dbh, query, magic_id, stage_id, component)) {
    529739        psError(PS_ERR_UNKNOWN, false, "database error");
    530740        return false;
     
    545755{
    546756    // first query the magicDSRun to find the stage and the stage_id
    547     psString query = "SELECT stage, stage_id from magicDSRun where magic_ds_id = %" PRId64;
     757    psString query = "SELECT stage, stage_id, magic_id from magicDSRun where magic_ds_id = %" PRId64;
    548758
    549759    if (!p_psDBRunQueryF(config->dbh, query, magic_ds_id)) {
     
    572782    psString stage = psMetadataLookupStr(NULL, row, "stage");
    573783    psS64 stage_id = psMetadataLookupS64(NULL, row, "stage_id");
     784    psS64 magic_id = psMetadataLookupS64(NULL, row, "magic_id");
    574785
    575786    ippStage stageNum = ippStringToStage(stage);
     
    597808        return false;
    598809    }
    599     if (!p_psDBRunQueryF(config->dbh, query, magic_ds_id, stage_id)) {
     810    if (!p_psDBRunQueryF(config->dbh, query, magic_id, stage_id)) {
    600811        psError(PS_ERR_UNKNOWN, false, "database error");
    601812        return false;
     
    625836    PXOPT_LOOKUP_STR(recovery_path_base, config->args, "-recovery_path_base", false, false);
    626837    PXOPT_LOOKUP_BOOL(setmagicked, config->args, "-setmagicked", false);
     838    PXOPT_LOOKUP_F32(streak_frac, config->args, "-streak_frac", false, false);
     839    PXOPT_LOOKUP_F32(nondiff_frac, config->args, "-nondiff_frac", false, false);
     840    PXOPT_LOOKUP_F32(run_time, config->args, "-run_time", false, false);
    627841
    628842    if (setmagicked && (fault != 0)) {
     
    647861    }
    648862
    649     if (!magicDSFileInsert(config->dbh, magic_ds_id, component, backup_path_base, recovery_path_base, fault, "full")) {
     863    if (!magicDSFileInsert(config->dbh,
     864            magic_ds_id,
     865            component,
     866            backup_path_base,
     867            recovery_path_base,
     868            streak_frac,
     869            nondiff_frac,
     870            run_time,
     871            fault,
     872            "full"  // data_state
     873        )) {
    650874            // rollback
    651875        if (!psDBRollback(config->dbh)) {
     
    656880    }
    657881
    658     if (!magicDSRunComplete(config, setmagicked)) {
    659             // rollback
    660         if (!psDBRollback(config->dbh)) {
    661             psError(PS_ERR_UNKNOWN, false, "database error");
    662         }
    663         psError(PS_ERR_UNKNOWN, false, "database error");
    664         return false;
    665     }
    666 
    667882    if (!psDBCommit(config->dbh)) {
    668883        psError(PS_ERR_UNKNOWN, false, "database error");
     
    673888}
    674889
    675 static bool magicDSGetIDs(pxConfig *config, psString stage, psS64 magic_id, psS64 *stage_id, psS64 *cam_id)
     890
     891static bool advancerunMode(pxConfig *config)
    676892{
    677893    PS_ASSERT_PTR_NON_NULL(config, false);
    678     PS_ASSERT_PTR_NON_NULL(stage, false);
    679     PS_ASSERT_PTR_NON_NULL(stage_id, false);
    680     PS_ASSERT_PTR_NON_NULL(cam_id, false);
    681 
    682     int stageNum = ippStringToStage(stage);;
    683     if (stageNum == IPP_STAGE_NONE) {
    684         psError(PXTOOLS_ERR_DATA, false, "%s is not a valid value for stage", stage);
    685         return false;
    686     }
    687 
    688     psString query = pxDataGet("magicdstool_getrunids.sql");
    689     if (!query) {
    690         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
    691         return false;
    692     }
    693 
    694     if (!p_psDBRunQueryF(config->dbh, query, magic_id)) {
    695         psError(PS_ERR_UNKNOWN, false, "database error");
    696         psFree(query);
    697         return false;
    698     }
    699     psFree(query);
    700 
    701     psArray *output = p_psDBFetchResult(config->dbh);
    702     if (!output) {
    703         psError(PS_ERR_UNKNOWN, false, "database error");
    704         return false;
    705     }
    706     if (!psArrayLength(output)) {
    707         psTrace("magicdstool", PS_LOG_INFO, "no rows found");
    708         psFree(output);
    709         return true;
    710     }
    711     if (psArrayLength(output) > 1) {
    712         psError(PS_ERR_UNKNOWN, true, "unexpected number of rows found %ld for magic_id %" PRId64,
    713             psArrayLength(output), magic_id);
    714         return false;
    715     }
    716     psMetadata *row = output->data[0];
    717 
    718     *cam_id = psMetadataLookupS64(NULL, row, "cam_id");
    719     switch (stageNum) {
    720     case IPP_STAGE_RAW:
    721         *stage_id = psMetadataLookupS64(NULL, row, "exp_id");
    722         break;
    723     case IPP_STAGE_CHIP:
    724         *stage_id = psMetadataLookupS64(NULL, row, "chip_id");
    725         break;
    726     case IPP_STAGE_CAMERA:
    727         *stage_id = *cam_id;
    728         return true;
    729     case IPP_STAGE_WARP:
    730         *stage_id = psMetadataLookupS64(NULL, row, "warp_id");
    731         break;
    732     case IPP_STAGE_DIFF:
    733         *stage_id = psMetadataLookupS64(NULL, row, "diff_id");
    734         break;
    735     }
    736 
    737     return true;
    738 }
    739 
    740 static bool magicDSRunComplete(pxConfig *config, bool setmagicked)
    741 {
    742     PS_ASSERT_PTR_NON_NULL(config, false);
     894
     895    psMetadata *where = psMetadataAlloc();
     896    PXOPT_COPY_S64(config->args, where, "-magic_ds_id", "magicDSRun.magic_ds_id", "==");
     897    pxAddLabelSearchArgs (config, where, "-label", "magicDSRun.label", "==");
     898
     899    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
    743900
    744901    // look for completed magicDSRuns
    745902    psString query = pxDataGet("magicdstool_completed_runs.sql");
    746903    if (!query) {
    747         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
    748         return false;
     904        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     905        return false;
     906    }
     907
     908    if (psListLength(where->list)) {
     909        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     910        psStringAppend(&query, " WHERE %s", whereClause);
     911        psFree(whereClause);
    749912    }
    750913
     
    766929        return true;
    767930    }
     931    if (!psDBTransaction(config->dbh)) {
     932        psError(PS_ERR_UNKNOWN, false, "database error");
     933        return false;
     934    }
    768935    for (long i = 0; i < psArrayLength(output); i++) {
    769936        psMetadata *row = output->data[i];
     
    771938        psS64 magic_ds_id = psMetadataLookupS64(NULL, row, "magic_ds_id");
    772939
    773         // if requested, set stageRun.magicked
     940        // if re_place, set stageRun.magicked
     941        bool setmagicked = psMetadataLookupBool(NULL, row, "re_place");
    774942        if (setmagicked && !setRunMagicked(config, magic_ds_id)) {
    775943            psError(PS_ERR_UNKNOWN, false, "failed to change stageRun.magicked for magic_ds_id: %" PRId64,
    776944                magic_ds_id);
     945            if (!psDBRollback(config->dbh)) {
     946                psError(PS_ERR_UNKNOWN, false, "database error");
     947            }
    777948            return false;
    778949        }
    779950
    780951        // set magicDSRun.state to 'full'
    781         if (!setmagicDSRunState(config, magic_ds_id, "full")) {
     952        if (!setmagicDSRunState(config, magic_ds_id, NULL, NULL, "full")) {
    782953            psError(PS_ERR_UNKNOWN, false, "failed to change magicDSRun.state for magic_ds_id: %" PRId64,
    783954                magic_ds_id);
    784955            psFree(output);
     956            if (!psDBRollback(config->dbh)) {
     957                psError(PS_ERR_UNKNOWN, false, "database error");
     958            }
    785959            return false;
    786960        }
    787961    }
    788 
     962    if (!psDBCommit(config->dbh)) {
     963        psError(PS_ERR_UNKNOWN, false, "database error");
     964        return false;
     965    }
    789966
    790967    return true;
     
    795972{
    796973    PS_ASSERT_PTR_NON_NULL(config, false);
     974
     975    PXOPT_LOOKUP_BOOL(i_am_sure, config->args, "-i_am_sure", true);
     976    if (!i_am_sure) {
     977        psError(PS_ERR_UNKNOWN, true, "Reverting destreaked files must be done carefully. -i_am_sure is required.");
     978        return false;
     979    }
    797980
    798981    psMetadata *where = psMetadataAlloc();
     
    802985    pxAddLabelSearchArgs (config, where, "-label", "label", "==");
    803986
    804     psString query = psStringCopy("DELETE FROM magicDSFile USING magicDSFile, magicDSRun  WHERE (magicDSRun.magic_ds_id = magicDSFile.magic_ds_id) AND magicDSFile.fault != 0");
     987    psString query = pxDataGet("magicdstool_revertdestreakedfile.sql");
    805988
    806989    if (psListLength(where->list)) {
     
    808991        psStringAppend(&query, " AND %s", whereClause);
    809992        psFree(whereClause);
     993    } else {
     994        psError(PS_ERR_UNKNOWN, true, "search arguments are required");
     995        return false;
    810996    }
    811997    psFree(where);
     
    813999    if (!p_psDBRunQuery(config->dbh, query)) {
    8141000        psError(PS_ERR_UNKNOWN, false, "failed to revert");
    815         return false;
    816     }
     1001        psFree(query);
     1002        return false;
     1003    }
     1004    psFree(query);
    8171005    return true;
    8181006}
    819 
    820 static bool getskycellsMode(pxConfig *config)
    821 {
    822     // required
    823     PXOPT_LOOKUP_S64(magic_ds_id, config->args, "-magic_ds_id", true, false);
     1007static bool clearstatefaultsMode(pxConfig *config)
     1008{
     1009    PS_ASSERT_PTR_NON_NULL(config, false);
    8241010
    8251011    psMetadata *where = psMetadataAlloc();
    826     PXOPT_COPY_STR(config->args, where, "-class_id",    "warpSkyCellMap.class_id", "==");
    827     PXOPT_COPY_STR(config->args, where, "-skycell_id",  "warpSkyCellMap.skycell_id", "==");
    828 
    829     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
    830 
    831     psString query = pxDataGet("magicdstool_getskycells.sql");
    832     if (!query) {
    833         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
    834         return false;
    835     }
     1012    // new state
     1013    PXOPT_LOOKUP_STR(new_state, config->args, "-set_state", false, false);
     1014    // old state (required)
     1015    PXOPT_LOOKUP_STR(state, config->args, "-state", true, false);
     1016
     1017    PXOPT_COPY_STR(config->args, where, "-state", "state", "==");
     1018    PXOPT_COPY_S64(config->args, where, "-magic_ds_id", "magicDSRun.magic_ds_id", "==");
     1019    PXOPT_COPY_S16(config->args, where, "-fault", "fault", "==");
     1020    pxAddLabelSearchArgs (config, where, "-label", "label", "==");
     1021
     1022    psString query = pxDataGet("magicdstool_clearstatefaults.sql");
    8361023
    8371024    if (psListLength(where->list)) {
    8381025        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
    839         psStringAppend(&query, " AND %s", whereClause);
     1026        psStringAppend(&query, " WHERE %s", whereClause);
    8401027        psFree(whereClause);
     1028    } else {
     1029        psError(PS_ERR_UNKNOWN, true, "search arguments are required");
     1030        return false;
    8411031    }
    8421032    psFree(where);
    8431033
    844     if (!p_psDBRunQueryF(config->dbh, query, magic_ds_id)) {
    845         psError(PS_ERR_UNKNOWN, false, "database error");
     1034    if (!new_state) {
     1035        if (!strcmp(state, "failed_revert")) {
     1036            new_state = "new";
     1037        } else if (!strcmp(state, "failed_cleanup")) {
     1038            new_state = "goto_cleaned";
     1039        } else {
     1040            psError(PS_ERR_UNKNOWN, true, "unexpected value for state: %s", state);
     1041            return false;
     1042        }
     1043    }
     1044    if (!p_psDBRunQueryF(config->dbh, query, new_state)) {
     1045        psError(PS_ERR_UNKNOWN, false, "failed to revert");
    8461046        psFree(query);
    8471047        return false;
    8481048    }
    8491049    psFree(query);
    850 
     1050    return true;
     1051}
     1052
     1053static bool completedrevertMode(pxConfig *config)
     1054{
     1055    PS_ASSERT_PTR_NON_NULL(config, false);
     1056
     1057    psMetadata *where = psMetadataAlloc();
     1058    PXOPT_COPY_S64(config->args, where, "-magic_ds_id", "magicDSRun.magic_ds_id", "==");
     1059    pxAddLabelSearchArgs (config, where, "-label", "label", "==");
     1060
     1061    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     1062
     1063    psString query = pxDataGet("magicdstool_completedrevert.sql");
     1064    // treat limit == 0 as "no limit"
     1065    if (limit) {
     1066        psString limitString = psDBGenerateLimitSQL(limit);
     1067        psStringAppend(&query, " %s", limitString);
     1068        psFree(limitString);
     1069    }
     1070
     1071    psString whereString = NULL;
     1072    if (psListLength(where->list)) {
     1073        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1074        psStringAppend(&whereString, "\nAND %s", whereClause);
     1075        psFree(whereClause);
     1076    }
     1077    psFree(where);
     1078
     1079    if (!p_psDBRunQueryF(config->dbh, query, whereString ? whereString : "")) {
     1080        psFree(whereString);
     1081        psError(PS_ERR_UNKNOWN, false, "failed to revert");
     1082        return false;
     1083    }
     1084    psFree(whereString);
     1085    psFree(query);
    8511086    psArray *output = p_psDBFetchResult(config->dbh);
    8521087    if (!output) {
     
    8681103        return true;
    8691104    }
    870 
    871     if (psArrayLength(output)) {
    872         // negative simple so the default is true
    873         if (!ippdbPrintMetadatas(stdout, output, "magicDiffSkyfile", !simple)) {
    874             psError(PS_ERR_UNKNOWN, false, "failed to print array");
     1105    for (int i=0; i<psArrayLength(output); i++) {
     1106        psMetadata *row = output->data[i];
     1107        psS64 magic_ds_id = psMetadataLookupS64(NULL, row, "magic_ds_id");
     1108        psString old_state = psMetadataLookupStr(NULL, row, "state");
     1109        psString new_state;
     1110        if (!strcmp(old_state, "goto_censored")) {
     1111            new_state = "censored";
     1112        } else if (!strcmp(old_state, "goto_restored")) {
     1113            new_state = "restored";
     1114        } else {
     1115            psError(PXTOOLS_ERR_PROG, true, "unexpected state found: %s", old_state);
    8751116            psFree(output);
    8761117            return false;
    8771118        }
    878     }
    879 
     1119        char *query2 = "UPDATE magicDSRun SET state = '%s' WHERE magic_ds_id = %" PRId64;
     1120        if (!p_psDBRunQueryF(config->dbh, query2, new_state, magic_ds_id)) {
     1121            psError(PS_ERR_UNKNOWN, false, "failed to set run magicDSRun.state to %s", new_state);
     1122            return false;
     1123        }
     1124    }
    8801125    psFree(output);
    8811126
     
    8831128}
    8841129
    885 static bool setmagicDSRunState(pxConfig *config, psS64 magic_ds_id, const char *state)
    886 {
    887     PS_ASSERT_PTR_NON_NULL(state, false);
    888 
    889     // check that state is a valid string value
    890     if (!(
    891             (strncmp(state, "new", 4) == 0)
    892             || (strncmp(state, "full", 5) == 0)
    893         )
    894     ) {
    895         psError(PS_ERR_UNKNOWN, false,
    896                 "invalid magicDSRun state: %s", state);
    897         return false;
    898     }
    899 
    900     char *query = "UPDATE magicDSRun SET state = '%s' WHERE magic_ds_id = %" PRId64;
    901     if (!p_psDBRunQueryF(config->dbh, query, state, magic_ds_id)) {
    902         psError(PS_ERR_UNKNOWN, false,
    903                 "failed to change state for magic_id %" PRId64, magic_ds_id);
    904         return false;
    905     }
    906 
    907     return true;
    908 }
    909 
    910 static bool toremoveMode(pxConfig *config)
    911 {
    912     PS_ASSERT_PTR_NON_NULL(config, false);
     1130static bool getskycellsMode(pxConfig *config)
     1131{
     1132    // required
     1133    PXOPT_LOOKUP_S64(magic_ds_id, config->args, "-magic_ds_id", true, false);
    9131134
    9141135    psMetadata *where = psMetadataAlloc();
    915     PXOPT_COPY_S64(config->args, where, "-magic_ds_id", "magic_ds_id", "==");
    916     PXOPT_COPY_S64(config->args, where, "-magic_id", "magic_id", "==");
    917     pxAddLabelSearchArgs (config, where, "-label", "label", "==");
    918 
    919     PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     1136    PXOPT_COPY_S64(config->args, where, "-magic_ds_id", "magicDSRun.magic_ds_id", "==");
     1137    PXOPT_COPY_STR(config->args, where, "-class_id",    "warpSkyCellMap.class_id", "==");
     1138    PXOPT_COPY_STR(config->args, where, "-skycell_id",  "warpSkyCellMap.skycell_id", "==");
     1139
    9201140    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
    9211141
    922     // look for "inputs" that need to processed
    923     psString query = pxDataGet("magicdstool_toremove.sql");
     1142    psString query = pxDataGet("magicdstool_getskycells.sql");
    9241143    if (!query) {
    925         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
    926         return false;
    927     }
    928 
     1144        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     1145        return false;
     1146    }
     1147
     1148    psString whereClause = NULL;
    9291149    if (psListLength(where->list)) {
    930         psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
    931         psStringAppend(&query, " WHERE %s", whereClause);
    932         psFree(whereClause);
     1150        whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1151        psStringPrepend(&whereClause, "\n AND ");
    9331152    }
    9341153    psFree(where);
    9351154
    936     // treat limit == 0 as "no limit"
    937     if (limit) {
    938         psString limitString = psDBGenerateLimitSQL(limit);
    939         psStringAppend(&query, " %s", limitString);
    940         psFree(limitString);
    941     }
    942 
    943     if (!p_psDBRunQuery(config->dbh, query)) {
     1155    if (!p_psDBRunQueryF(config->dbh, query, whereClause, whereClause)) {
    9441156        psError(PS_ERR_UNKNOWN, false, "database error");
    9451157        psFree(query);
     
    9701182    if (psArrayLength(output)) {
    9711183        // negative simple so the default is true
    972         if (!ippdbPrintMetadatas(stdout, output, "toremove", !simple)) {
     1184        if (!ippdbPrintMetadatas(stdout, output, "magicDiffSkyfile", !simple)) {
    9731185            psError(PS_ERR_UNKNOWN, false, "failed to print array");
    9741186            psFree(output);
     
    9811193    return true;
    9821194}
    983 static bool torestoreMode(pxConfig *config)
     1195
     1196static bool validDSRunState(const char *state)
     1197{
     1198    if (!((strcmp(state, "new") == 0) ||
     1199          (strcmp(state, "full") == 0) ||
     1200          (strcmp(state, "drop") == 0) ||
     1201          (strcmp(state, "failed_revert") == 0) ||
     1202          (strcmp(state, "failed_cleanup") == 0) ||
     1203          (strcmp(state, "restored") == 0) ||
     1204          (strcmp(state, "censored") == 0) ||
     1205          (strcmp(state, "cleaned") == 0) ||
     1206          (strcmp(state, "goto_restored") == 0) ||
     1207          (strcmp(state, "goto_censored") == 0) ||
     1208          (strcmp(state, "goto_cleaned") == 0))
     1209        ) {
     1210        return false;
     1211    } else {
     1212        return true;
     1213    }
     1214}
     1215
     1216static bool setmagicDSRunState(pxConfig *config, psS64 magic_ds_id, psString extraSetStr, psMetadata *where, const char *state)
     1217{
     1218    PS_ASSERT_PTR_NON_NULL(state, false);
     1219
     1220    if (!validDSRunState(state)) {
     1221        psError(PS_ERR_UNKNOWN, false,
     1222                "invalid magicDSRun state: %s", state);
     1223        return false;
     1224    }
     1225
     1226    psString query = NULL;
     1227    psStringAppend(&query, "UPDATE magicDSRun SET state = '%s' %s\n", state, extraSetStr ? extraSetStr : "");
     1228    if (magic_ds_id) {
     1229        psStringAppend(&query, " WHERE magic_ds_id = %" PRId64, magic_ds_id);
     1230    } else if (where && psListLength(where->list)) {
     1231        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1232        psStringAppend(&query, " WHERE %s", whereClause);
     1233        psFree(whereClause);
     1234    } else {
     1235        psError(PS_ERR_UNKNOWN, true, "search arguments are required");
     1236        return false;
     1237    }
     1238
     1239    if (!strcmp(state, "goto_cleaned")) {
     1240        // Don't set state back to goto_cleaned if it is already cleaned
     1241        psStringAppend(&query, " AND (magicDSRun.state != 'cleaned')");
     1242
     1243        // don't clean up magicDSRun's where stage is camera
     1244        psStringAppend(&query, " AND (magicDSRun.stage != 'camera')");
     1245    }
     1246
     1247    if (!p_psDBRunQuery(config->dbh, query)) {
     1248        psError(PS_ERR_UNKNOWN, false,
     1249                "failed to change state for magic_id %" PRId64, magic_ds_id);
     1250        return false;
     1251    }
     1252
     1253    return true;
     1254}
     1255
     1256static bool toremoveMode(pxConfig *config)
    9841257{
    9851258    PS_ASSERT_PTR_NON_NULL(config, false);
     
    9941267
    9951268    // look for "inputs" that need to processed
    996     psString query = pxDataGet("magicdstool_torestore.sql");
     1269    psString query = pxDataGet("magicdstool_toremove.sql");
    9971270    if (!query) {
    998         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     1271        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
    9991272        return false;
    10001273    }
     
    10431316    if (psArrayLength(output)) {
    10441317        // negative simple so the default is true
    1045         if (!ippdbPrintMetadatas(stdout, output, "torestore", !simple)) {
     1318        if (!ippdbPrintMetadatas(stdout, output, "toremove", !simple)) {
    10461319            psError(PS_ERR_UNKNOWN, false, "failed to print array");
    10471320            psFree(output);
     
    10551328}
    10561329
    1057 
    10581330static bool torevertMode(pxConfig *config)
    10591331{
     
    10751347    psString query = pxDataGet(sql_file);
    10761348    if (!query) {
    1077         psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement from %s", sql_file);
     1349        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement from %s", sql_file);
    10781350        psFree(sql_file);
    10791351        return false;
     
    11371409
    11381410
     1411static bool tocleanupMode(pxConfig *config)
     1412{
     1413    PS_ASSERT_PTR_NON_NULL(config, false);
     1414
     1415    psMetadata *where = psMetadataAlloc();
     1416
     1417    PXOPT_COPY_STR(config->args, where, "-stage", "stage", "==");
     1418    PXOPT_COPY_S64(config->args, where, "-magic_ds_id", "magic_ds_id", "==");
     1419    PXOPT_COPY_S64(config->args, where, "-magic_id", "magic_id", "==");
     1420    pxAddLabelSearchArgs (config, where, "-label", "magicDSRun.label", "==");
     1421
     1422    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     1423    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     1424
     1425    psString query = pxDataGet("magicdstool_tocleanup.sql");
     1426    if (!query) {
     1427        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     1428        return false;
     1429    }
     1430
     1431    if (psListLength(where->list)) {
     1432        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1433        psStringAppend(&query, " AND %s", whereClause);
     1434        psFree(whereClause);
     1435    }
     1436    psFree(where);
     1437
     1438    // treat limit == 0 as "no limit"
     1439    if (limit) {
     1440        psString limitString = psDBGenerateLimitSQL(limit);
     1441        psStringAppend(&query, " %s", limitString);
     1442        psFree(limitString);
     1443    }
     1444
     1445    if (!p_psDBRunQuery(config->dbh, query)) {
     1446        psError(PS_ERR_UNKNOWN, false, "database error");
     1447        psFree(query);
     1448        return false;
     1449    }
     1450    psFree(query);
     1451
     1452    psArray *output = p_psDBFetchResult(config->dbh);
     1453    if (!output) {
     1454        psErrorCode err = psErrorCodeLast();
     1455        switch (err) {
     1456            case PS_ERR_DB_CLIENT:
     1457                psError(PXTOOLS_ERR_SYS, false, "database error");
     1458            case PS_ERR_DB_SERVER:
     1459                psError(PXTOOLS_ERR_PROG, false, "database error");
     1460            default:
     1461                psError(PXTOOLS_ERR_PROG, false, "unknown error");
     1462        }
     1463
     1464        return false;
     1465    }
     1466    if (!psArrayLength(output)) {
     1467        psTrace("magicdstool", PS_LOG_INFO, "no rows found");
     1468        psFree(output);
     1469        return true;
     1470    }
     1471
     1472    if (psArrayLength(output)) {
     1473        // negative simple so the default is true
     1474        if (!ippdbPrintMetadatas(stdout, output, "tocleanup", !simple)) {
     1475            psError(PS_ERR_UNKNOWN, false, "failed to print array");
     1476            psFree(output);
     1477            return false;
     1478        }
     1479    }
     1480
     1481    psFree(output);
     1482
     1483    return true;
     1484}
Note: See TracChangeset for help on using the changeset viewer.