IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 26, 2009, 1:59:32 PM (17 years ago)
Author:
beaumont
Message:

merged with trunk

Location:
branches/cnb_branches/cnb_branch_20090301
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/cnb_branches/cnb_branch_20090301

  • branches/cnb_branches/cnb_branch_20090301/ippTools/src

    • Property svn:ignore
      •  

        old new  
        3333pstamptool
        3434disttool
         35receivetool
  • branches/cnb_branches/cnb_branch_20090301/ippTools/src/disttool.c

    r23594 r24244  
    3939static bool processedcomponentMode(pxConfig *config);
    4040static bool toadvanceMode(pxConfig *config);
     41static bool pendingfilesetMode(pxConfig *config);
     42static bool addfilesetMode(pxConfig *config);
     43static bool revertfilesetMode(pxConfig *config);
     44static bool queuercrunMode(pxConfig *config);
     45static bool updatercrunMode(pxConfig *config);
     46static bool revertrcrunMode(pxConfig *config);
     47static bool pendingdestMode(pxConfig *config);
     48
     49static bool definetargetMode(pxConfig *config);
     50static bool updatetargetMode(pxConfig *config);
     51static bool listtargetMode(pxConfig *config);
     52
     53static bool definedsproductMode(pxConfig *config);
     54static bool updatedsproductMode(pxConfig *config);
     55
     56static bool definedestinationMode(pxConfig *config);
     57static bool updatedestinationMode(pxConfig *config);
     58
     59static bool defineinterestMode(pxConfig *config);
     60static bool updateinterestMode(pxConfig *config);
    4161
    4262# define MODECASE(caseName, func) \
     
    6787        MODECASE(DISTTOOL_MODE_PROCESSEDCOMPONENT, processedcomponentMode);
    6888        MODECASE(DISTTOOL_MODE_TOADVANCE, toadvanceMode);
     89        MODECASE(DISTTOOL_MODE_PENDINGFILESET, pendingfilesetMode);
     90        MODECASE(DISTTOOL_MODE_ADDFILESET, addfilesetMode);
     91        MODECASE(DISTTOOL_MODE_REVERTFILESET, revertfilesetMode);
     92        MODECASE(DISTTOOL_MODE_QUEUERCRUN, queuercrunMode);
     93        MODECASE(DISTTOOL_MODE_UPDATERCRUN, updatercrunMode);
     94        MODECASE(DISTTOOL_MODE_REVERTRCRUN, revertrcrunMode);
     95        MODECASE(DISTTOOL_MODE_PENDINGDEST, pendingdestMode);
     96        MODECASE(DISTTOOL_MODE_DEFINETARGET, definetargetMode);
     97        MODECASE(DISTTOOL_MODE_UPDATETARGET, updatetargetMode);
     98        MODECASE(DISTTOOL_MODE_LISTTARGET, listtargetMode);
     99        MODECASE(DISTTOOL_MODE_DEFINEDSPRODUCT, definedsproductMode);
     100        MODECASE(DISTTOOL_MODE_UPDATEDSPRODUCT, updatedsproductMode);
     101        MODECASE(DISTTOOL_MODE_DEFINEDESTINATION, definedestinationMode);
     102        MODECASE(DISTTOOL_MODE_UPDATEDESTINATION, updatedestinationMode);
     103        MODECASE(DISTTOOL_MODE_DEFINEINTEREST, defineinterestMode);
     104        MODECASE(DISTTOOL_MODE_UPDATEINTEREST, updateinterestMode);
    69105        default:
    70106            psAbort("invalid option (this should not happen)");
     
    92128    PS_ASSERT_PTR_NON_NULL(config, false);
    93129
     130    // required
    94131    PXOPT_LOOKUP_STR(stage, config->args, "-stage", true, false);
    95132    PXOPT_LOOKUP_S64(stage_id, config->args, "-stage_id",  true, false);
    96133    PXOPT_LOOKUP_STR(outroot, config->args, "-outroot", true, false);
     134    PXOPT_LOOKUP_S64(target_id, config->args, "-target_id",  true, false);
     135
     136    // optional
    97137    PXOPT_LOOKUP_BOOL(clean, config->args, "-clean", false);
     138    PXOPT_LOOKUP_BOOL(no_magic, config->args, "-no_magic", false);
    98139    PXOPT_LOOKUP_STR(set_label, config->args, "-set_label", false, false);
    99140
     
    101142    // XXX: all of the following concerns will be managed properly by definebyquery
    102143
    103     // TODO: check that stage_id actually exists for stage
    104     // in magicdstool we queue off of a magic_id so the stage_id, exp_id, and cam_id get looked up 
     144    // TODO: should we check that stage_id actually exists for stage
     145    // in magicdstool we queue off of a magic_id so the stage_id, exp_id, and cam_id get looked up
    105146    // when the run is queued
    106     // Should we also check here that the run is full or cleaned and that all of the images
    107     // are magicked. We need to do that at run time as well since the run and magic state can
    108     // change between the time that it is queued.
    109 
    110     if (!distRunInsert(config->dbh, 0, stage, stage_id, set_label, outroot, clean, "new", NULL, 0)) {
     147
     148    if (!distRunInsert(config->dbh,
     149            0,          // dist_id
     150            target_id,
     151            stage,
     152            stage_id,
     153            set_label,
     154            outroot,
     155            clean,
     156            no_magic,
     157            "new",
     158            NULL,       // time_stamp
     159            0           // fault
     160            )) {
    111161        psError(PS_ERR_UNKNOWN, false, "database error");
    112162        return false;
     
    118168static bool definebyqueryMode(pxConfig *config)
    119169{
    120     psError(PS_ERR_PROGRAMMING, true, "-definebyquery is not implemented yet");
    121     return false;
     170    PS_ASSERT_PTR_NON_NULL(config, false);
     171
     172    // required
     173    PXOPT_LOOKUP_STR(stage, config->args,     "-stage", true, false);
     174    PXOPT_LOOKUP_STR(workdir, config->args,   "-workdir", true, false);
     175
     176    // optional
     177    PXOPT_LOOKUP_S64(magic_ds_id, config->args, "-magic_ds_id",  false, false);
     178    PXOPT_LOOKUP_BOOL(no_magic, config->args, "-no_magic", false);
     179    PXOPT_LOOKUP_STR(set_label, config->args, "-set_label", false, false);
     180    PXOPT_LOOKUP_S64(limit, config->args, "-limit", false, false);
     181    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     182   
     183    PXOPT_LOOKUP_BOOL(dry_run, config->args, "-dry_run", false);
     184
     185    // select arguments
     186    psMetadata *where = psMetadataAlloc();
     187
     188    PXOPT_COPY_S64(config->args, where, "-target_id", "distTarget.target_id",    "==");
     189    PXOPT_COPY_S64(config->args, where, "-exp_id",    "rawExp.exp_id",           "==");
     190    PXOPT_COPY_S64(config->args, where, "-chip_id",   "chipRun.chip_id",         "==");
     191    PXOPT_COPY_STR(config->args, where, "-obs_mode",  "rawExp.obs_mode",         "==");
     192
     193    PXOPT_LOOKUP_STR(label, config->args, "-label", false, false);
     194
     195    psString query = NULL;
     196    psString magicRunType = NULL;
     197    psString runJoinStr = NULL;
     198    if (!strcmp(stage, "raw")) {
     199        magicRunType = "rawExp";
     200        runJoinStr = "rawExp.exp_id";
     201        query = pxDataGet("disttool_definebyquery_raw.sql");
     202        if (!query) {
     203            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     204            psFree(where);
     205            return false;
     206        }
     207    } else if (!strcmp(stage, "chip")) {
     208        magicRunType = "chipRun";
     209        runJoinStr = "chipRun.chip_id";
     210        query = pxDataGet("disttool_definebyquery_chip.sql");
     211        if (!query) {
     212            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     213            psFree(where);
     214            return false;
     215        }
     216
     217        if (label) {
     218            psStringAppend(&query, " AND (chipRun.label = '%s')", label);
     219        }
     220    } else if (!strcmp(stage, "camera")) {
     221        magicRunType = "chipRun";    // This is used below to set the magicked business
     222        query = pxDataGet("disttool_definebyquery_camera.sql");
     223        if (!query) {
     224            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     225            psFree(where);
     226            return false;
     227        }
     228
     229        if (label) {
     230            psStringAppend(&query, " AND (camRun.label = '%s')", label);
     231        }
     232    } else if (!strcmp(stage, "fake")) {
     233        magicRunType = "fakeRun";
     234        query = pxDataGet("disttool_definebyquery_fake.sql");
     235        if (!query) {
     236            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     237            psFree(where);
     238            return false;
     239        }
     240
     241        if (label) {
     242            psStringAppend(&query, " AND (fakeRun.label = '%s')", label);
     243        }
     244        // fake stage doesn't require magic
     245        no_magic = true;
     246    } else if (!strcmp(stage, "warp")) {
     247        magicRunType = "warpRun";
     248        runJoinStr = "warpRun.warp_id";
     249        query = pxDataGet("disttool_definebyquery_warp.sql");
     250        if (!query) {
     251            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     252            psFree(where);
     253            return false;
     254        }
     255
     256        if (label) {
     257            psStringAppend(&query, " AND (warpRun.label = '%s')", label);
     258        }
     259
     260    } else if (!strcmp(stage, "diff")) {
     261        magicRunType = "diffRun";
     262        runJoinStr = "diffRun.diff_id";
     263        query = pxDataGet("disttool_definebyquery_diff.sql");
     264        if (!query) {
     265            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     266            psFree(where);
     267            return false;
     268        }
     269
     270        if (label) {
     271            psStringAppend(&query, " AND (diffRun.label = '%s')", label);
     272        }
     273
     274    } else if (!strcmp(stage, "stack")) {
     275        magicRunType = "stackRun";
     276        query = pxDataGet("disttool_definebyquery_stack.sql");
     277        if (!query) {
     278            psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     279            psFree(where);
     280            return false;
     281        }
     282
     283        if (label) {
     284            psStringAppend(&query, " AND (stackRun.label = '%s')", label);
     285        }
     286        // stack stage doesn't require magic (perhaps let the script do this?
     287        no_magic = true;
     288    } else {
     289        psError(PS_ERR_UNKNOWN, true, "unknown value for stage: %s", stage);
     290        psFree(where);
     291        return false;
     292    }
     293
     294    if (psListLength(where->list)) {
     295        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     296        psStringAppend(&query, " AND %s", whereClause);
     297        psFree(whereClause);
     298    }
     299    psFree(where);
     300
     301    psString joinHook = NULL;
     302
     303    if (!no_magic) {
     304        psStringAppend(&query, " AND (distTarget.clean OR %s.magicked)", magicRunType);
     305
     306        // is selecting by magic_ds_id really interesting?
     307        if (magic_ds_id) {
     308            if (strcmp(stage, "camera")) {
     309                // stage other than camera
     310                if (!runJoinStr) {
     311                    psError(PS_ERR_PROGRAMMING, true, "cannot select by magic_ds_id for stage: %s", stage);
     312                    psFree(query);
     313                    return false;
     314                }
     315                psStringAppend(&joinHook, "\nJOIN magicDSRun ON magicDSRun.stage = distTarget.stage"
     316                                              " AND magicDSRun.stage_id = %s", runJoinStr);
     317            } else {
     318                // camera masks are magicked when the chipRun is magicked
     319                // XXX: This is confusing. Is it dangerous?
     320                // Maybe I should add a magicked bit to camRun. Note this isn't
     321                psStringAppend(&joinHook, "\nJOIN magicDSRun ON magicDSRun.stage = 'chip'"
     322                                              " AND magicDSRun.stage_id = chipRun.chip_id");
     323            }
     324            psStringAppend(&query, " AND (magicDSRun.state = 'full' AND magicDSRun.re_place AND (magic_ds_id = %" PRId64 "))", magic_ds_id);
     325        }
     326    }
     327
     328    if (limit) {
     329        psString limitString = psDBGenerateLimitSQL(limit);
     330        psStringAppend(&query, " %s", limitString);
     331        psFree(limitString);
     332    }
     333
     334    if (!p_psDBRunQueryF(config->dbh, query, joinHook ? joinHook : "")) {
     335        psError(PS_ERR_UNKNOWN, false, "database error");
     336        psFree(query);
     337        return false;
     338    }
     339    psFree(query);
     340    psFree(joinHook);
     341
     342    psArray *output = p_psDBFetchResult(config->dbh);
     343    if (!output) {
     344        psError(PS_ERR_UNKNOWN, false, "database error");
     345        return false;
     346    }
     347    if (!psArrayLength(output)) {
     348        psTrace("disttool", PS_LOG_INFO, "no rows found");
     349        psFree(output);
     350        return true;
     351    }
     352
     353
     354    if (dry_run) {
     355        if (!ippdbPrintMetadatas(stdout, output, "newdistRuns", true)) {
     356            psError(PS_ERR_UNKNOWN, false, "failed to print array");
     357            psFree(output);
     358            return false;
     359        }
     360        psFree(output);
     361        return true;
     362    }
     363
     364    if (!psDBTransaction(config->dbh)) {
     365        psError(PS_ERR_UNKNOWN, false, "database error");
     366        return false;
     367    }
     368
     369    psArray *list = psArrayAllocEmpty(limit);
     370    for (long i=0; i < psArrayLength(output); i++) {
     371        psMetadata *md = output->data[i];
     372        psString stage = psMetadataLookupStr(NULL, md, "stage");
     373        psString run_tag = psMetadataLookupStr(NULL, md, "run_tag");
     374        psS64 stage_id = psMetadataLookupS64(NULL, md, "stage_id");
     375        psS64 target_id = psMetadataLookupS64(NULL, md, "target_id");
     376        bool clean = psMetadataLookupBool(NULL, md, "clean");
     377
     378        psString outroot = NULL;
     379        psStringAppend(&outroot, "%s/%s/%s", workdir, run_tag, stage);
     380
     381        distRunRow *row = distRunRowAlloc(
     382                0,      // dist_id
     383                target_id,
     384                stage,
     385                stage_id,
     386                set_label,
     387                outroot,
     388                clean,
     389                no_magic,
     390                "new",
     391                NULL,   // time_stamp
     392                0       // fault
     393                );
     394
     395        if (!row) {
     396            psError(PS_ERR_UNKNOWN, false, "failed to allocate distRunRow");
     397            psFree(outroot);
     398            psFree(output);
     399            return false;
     400        }
     401        if (!distRunInsertObject(config->dbh, row)) {
     402            psError(PS_ERR_UNKNOWN, false, "database error");
     403            psFree(outroot);
     404            psFree(output);
     405            return false;
     406        }
     407        psFree(outroot);
     408        psS64 dist_id = psDBLastInsertID(config->dbh);
     409        row->dist_id = dist_id;
     410        psArrayAdd(list, list->n, row);
     411        psFree(row);
     412    }
     413
     414    if (!psDBCommit(config->dbh)) {
     415        psError(PS_ERR_UNKNOWN, false, "database error");
     416        return false;
     417    }
     418    if (!distRunPrintObjects(stdout, list, !simple)) {
     419        psError(PS_ERR_UNKNOWN, false, "failed to print object");
     420        psFree(list);
     421        return false;
     422    }
     423
     424    psFree(list);
     425    psFree(output);
     426
     427    return true;
    122428}
    123429
     
    138444    PXOPT_LOOKUP_STR(state, config->args, "-set_state", false, false);
    139445    PXOPT_LOOKUP_STR(label, config->args, "-set_label", false, false);
    140     PXOPT_LOOKUP_S16(code, config->args, "-code", false, false);
    141 
    142     if ((!state) && (!label) && (!code)) {
    143         psError(PXTOOLS_ERR_DATA, false, "parameters (-code or -set_state or -set_label) are required");
     446    PXOPT_LOOKUP_S16(fault, config->args, "-fault", false, false);
     447
     448    if ((!state) && (!label) && (!fault)) {
     449        psError(PXTOOLS_ERR_DATA, false, "parameters (-fault or -set_state or -set_label) are required");
    144450        psFree(where);
    145451        return false;
     
    156462    }
    157463
    158     if (code) {
    159         psStringAppend(&query, " , fault = %d", code);
     464    if (fault) {
     465        psStringAppend(&query, " , fault = %d", fault);
    160466    }
    161467
     
    182488    PXOPT_COPY_STR(config->args, where, "-state", "state", "==");
    183489    PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
    184     PXOPT_COPY_S16(config->args, where, "-code", "distComponent.fault", "==");
     490    PXOPT_COPY_S16(config->args, where, "-fault", "fault", "==");
    185491
    186492    // It might be useful to be able to query by the parameters of the underlying runs
     
    296602    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
    297603    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
    298     PXOPT_LOOKUP_BOOL(need_magic, config->args, "-need_magic", false);
    299604
    300605    // look for "inputs" that need to processed
     
    319624    }
    320625
    321     psString    chip_magic = "";
     626    // the query has where hooks for each stage.
     627    // right now we aren't using them.
     628    // XXX: I think that I want to change the query from a union of selects on the various
     629    // stages to separate queries. As it is pending data at the later stages of the pipline
     630    // will get blocked by pending earlier stages
    322631    psString    raw_where = "";
     632    psString    raw_clean_where = "";
    323633    psString    chip_where = "";
    324634    psString    camera_where = "";
     
    328638    psString    stack_where = "";
    329639
    330     if (need_magic) {
    331         chip_magic = psStringCopy("\nAND chipRun.magicked");
    332         raw_where  = psStringCopy("\nAND rawExp.magicked");
    333         chip_where = psStringCopy("\nAND (distRun.clean OR chipRun.magicked)");
    334         // chipRun must be magicked to allow release camera level masks
    335         camera_where = psStringCopy("\nAND (distRun.clean OR chipRun.magicked)");
    336         warp_where = psStringCopy("\nAND (distRun.clean OR warpRun.magicked)");
    337         diff_where = psStringCopy("\nAND (distRun.clean OR diffRun.magicked)");
    338     }
    339 
    340640    if (!p_psDBRunQueryF(config->dbh,
    341641            query,
    342             chip_magic,
    343642            raw_where,
     643            raw_clean_where,
    344644            chip_where,
    345645            camera_where,
     
    397697    // unless fault code is set require filename, bytes, and md5sum
    398698    bool require_fileinfo = false;
    399     PXOPT_LOOKUP_S16(code, config->args, "-code", false, false);
    400     if (!code) {
     699    PXOPT_LOOKUP_S16(fault, config->args, "-fault", false, false);
     700    if (!fault) {
    401701        require_fileinfo = true;
    402702    }
     
    405705    PXOPT_LOOKUP_STR(name, config->args, "-name", require_fileinfo, false);
    406706
    407     if (!distComponentInsert(config->dbh, dist_id, component, bytes, md5sum, "full", name, code)) {
     707    if (!distComponentInsert(config->dbh, dist_id, component, bytes, md5sum, "full", name, fault)) {
    408708        psError(PS_ERR_UNKNOWN, false, "database error");
    409709        return false;
     
    419719    psMetadata *where = psMetadataAlloc();
    420720    PXOPT_COPY_S64(config->args, where, "-dist_id", "dist_id", "==");
     721    PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
    421722
    422723    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     
    555856    return true;
    556857}
     858
     859static bool pendingfilesetMode(pxConfig *config)
     860{
     861    PS_ASSERT_PTR_NON_NULL(config, false);
     862
     863    psMetadata *where = psMetadataAlloc();
     864    PXOPT_COPY_S64(config->args, where, "-dist_id", "dist_id", "==");
     865    PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
     866
     867    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     868    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     869
     870    // look for "inputs" that need to processed
     871    psString query = pxDataGet("disttool_pendingfileset.sql");
     872    if (!query) {
     873        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     874        return false;
     875    }
     876
     877    if (psListLength(where->list)) {
     878        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     879        psStringAppend(&query, " AND %s", whereClause);
     880        psFree(whereClause);
     881    }
     882    psFree(where);
     883
     884    // treat limit == 0 as "no limit"
     885    if (limit) {
     886        psString limitString = psDBGenerateLimitSQL(limit);
     887        psStringAppend(&query, " %s", limitString);
     888        psFree(limitString);
     889    }
     890
     891    if (!p_psDBRunQuery(config->dbh, query)) {
     892        psError(PS_ERR_UNKNOWN, false, "database error");
     893        psFree(query);
     894        return false;
     895    }
     896    psFree(query);
     897
     898    psArray *output = p_psDBFetchResult(config->dbh);
     899    if (!output) {
     900        psErrorCode err = psErrorCodeLast();
     901        switch (err) {
     902            case PS_ERR_DB_CLIENT:
     903                psError(PXTOOLS_ERR_SYS, false, "database error");
     904            case PS_ERR_DB_SERVER:
     905                psError(PXTOOLS_ERR_PROG, false, "database error");
     906            default:
     907                psError(PXTOOLS_ERR_PROG, false, "unknown error");
     908        }
     909
     910        return false;
     911    }
     912    if (!psArrayLength(output)) {
     913        psTrace("disttool", PS_LOG_INFO, "no rows found");
     914        psFree(output);
     915        return true;
     916    }
     917
     918    if (psArrayLength(output)) {
     919        // negative simple so the default is true
     920        if (!ippdbPrintMetadatas(stdout, output, "pendingfileset", !simple)) {
     921            psError(PS_ERR_UNKNOWN, false, "failed to print array");
     922            psFree(output);
     923            return false;
     924        }
     925    }
     926
     927    psFree(output);
     928
     929    return true;
     930}
     931static bool addfilesetMode(pxConfig *config)
     932{
     933
     934    // required values
     935    PXOPT_LOOKUP_S64(dist_id, config->args, "-dist_id", true, false);
     936    PXOPT_LOOKUP_S64(prod_id, config->args, "-prod_id", true, false);
     937
     938    PXOPT_LOOKUP_S16(fault, config->args, "-fault", false, false);
     939
     940    // unless fault code is set require name
     941    PXOPT_LOOKUP_STR(name, config->args, "-name", fault == 0, false);
     942
     943    if (!rcDSFilesetInsert(config->dbh,
     944            0,          // fs_id
     945            dist_id,
     946            prod_id,
     947            name,
     948            "full",
     949            fault)) {
     950        psError(PS_ERR_UNKNOWN, false, "database error");
     951        return false;
     952    }
     953
     954    return true;
     955}
     956static bool revertfilesetMode(pxConfig *config)
     957{
     958    psMetadata *where = psMetadataAlloc();
     959    PXOPT_COPY_S64(config->args, where, "-fs_id", "fs_id", "==");
     960    PXOPT_COPY_S64(config->args, where, "-dist_id", "rcDSFileset.dist_id", "==");
     961    PXOPT_COPY_S64(config->args, where, "-prod_id", "prod_id", "==");
     962    PXOPT_COPY_STR(config->args, where, "-stage", "stage", "==");;
     963    PXOPT_COPY_S64(config->args, where, "-stage_id", "stage_id", "==");
     964    PXOPT_COPY_STR(config->args, where, "-state", "state", "==");
     965    PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
     966    PXOPT_COPY_S16(config->args, where, "-fault", "rcDSFileset.fault", "==");
     967
     968    // It might be useful to be able to query by the parameters of the underlying runs
     969
     970    if (!psListLength(where->list) && !psMetadataLookupBool(NULL, config->args, "-all")) {
     971        psFree(where);
     972        psError(PXTOOLS_ERR_DATA, false, "search parameters are required");
     973        return false;
     974    }
     975
     976    psString query = pxDataGet("disttool_revertfileset.sql");
     977    if (!query) {
     978        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     979        psFree(where);
     980        return false;
     981    }
     982
     983    if (psListLength(where->list)) {
     984        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     985        psStringAppend(&query, " AND %s", whereClause);
     986        psFree(whereClause);
     987    }
     988
     989    if (!p_psDBRunQuery(config->dbh, query)) {
     990        psError(PS_ERR_UNKNOWN, false, "database error");
     991        psFree(query);
     992        if (!psDBRollback(config->dbh)) {
     993            psError(PS_ERR_UNKNOWN, false, "database error");
     994        }
     995        return false;
     996    }
     997    psFree(query);
     998
     999    int numUpdated = psDBAffectedRows(config->dbh);
     1000
     1001    psLogMsg("disttool", PS_LOG_INFO, "deleted %d rcDSFilesets", numUpdated);
     1002
     1003    return true;
     1004}
     1005
     1006static bool pendingdestMode(pxConfig *config)
     1007{
     1008    PS_ASSERT_PTR_NON_NULL(config, false);
     1009
     1010    psMetadata *where = psMetadataAlloc();
     1011    PXOPT_COPY_S64(config->args, where, "-dest_id", "dist_id", "==");
     1012//     PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
     1013
     1014    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     1015    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     1016
     1017    // look for "inputs" that need to processed
     1018    psString query = pxDataGet("disttool_pendingdest.sql");
     1019    if (!query) {
     1020        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     1021        return false;
     1022    }
     1023
     1024    psString whereString = NULL;
     1025    if (psListLength(where->list)) {
     1026        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1027        // where string gets added by hook, not at the end of the query
     1028        psStringAppend(&whereString, "\n AND %s", whereClause);
     1029        psFree(whereClause);
     1030    }
     1031    psFree(where);
     1032
     1033    // treat limit == 0 as "no limit"
     1034    if (limit) {
     1035        psString limitString = psDBGenerateLimitSQL(limit);
     1036        psStringAppend(&query, " %s", limitString);
     1037        psFree(limitString);
     1038    }
     1039
     1040    if (!p_psDBRunQueryF(config->dbh, query, whereString ? whereString : "")) {
     1041        psError(PS_ERR_UNKNOWN, false, "database error");
     1042        psFree(whereString);
     1043        psFree(query);
     1044        return false;
     1045    }
     1046    psFree(query);
     1047
     1048    psArray *output = p_psDBFetchResult(config->dbh);
     1049    if (!output) {
     1050        psErrorCode err = psErrorCodeLast();
     1051        switch (err) {
     1052            case PS_ERR_DB_CLIENT:
     1053                psError(PXTOOLS_ERR_SYS, false, "database error");
     1054            case PS_ERR_DB_SERVER:
     1055                psError(PXTOOLS_ERR_PROG, false, "database error");
     1056            default:
     1057                psError(PXTOOLS_ERR_PROG, false, "unknown error");
     1058        }
     1059
     1060        return false;
     1061    }
     1062    if (!psArrayLength(output)) {
     1063        psTrace("disttool", PS_LOG_INFO, "no rows found");
     1064        psFree(output);
     1065        return true;
     1066    }
     1067
     1068    if (psArrayLength(output)) {
     1069        // negative simple so the default is true
     1070        if (!ippdbPrintMetadatas(stdout, output, "pendingfileset", !simple)) {
     1071            psError(PS_ERR_UNKNOWN, false, "failed to print array");
     1072            psFree(output);
     1073            return false;
     1074        }
     1075    }
     1076
     1077    psFree(output);
     1078
     1079    return true;
     1080}
     1081
     1082static bool queuercrunMode(pxConfig *config)
     1083{
     1084    PS_ASSERT_PTR_NON_NULL(config, false);
     1085    psMetadata *where = psMetadataAlloc();
     1086
     1087    PXOPT_COPY_S64(config->args, where, "-dist_id",  "dist_id", "==");
     1088    PXOPT_COPY_S64(config->args, where, "-dest_id",  "dest_id", "==");
     1089    PXOPT_COPY_S64(config->args, where, "-prod_id",  "prod_id", "==");
     1090    PXOPT_COPY_S64(config->args, where, "-target_id","target_id", "==");
     1091    PXOPT_COPY_S64(config->args, where, "-fs_id",    "fs_id", "==");
     1092    PXOPT_COPY_STR(config->args, where, "-stage",    "stage", "==");;
     1093    PXOPT_COPY_S64(config->args, where, "-stage_id", "stage_id", "==");
     1094    PXOPT_COPY_STR(config->args, where, "-label",    "label", "==");
     1095
     1096    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     1097
     1098    psString query = pxDataGet("disttool_queuercrun.sql");
     1099    if (!query) {
     1100        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     1101        return false;
     1102    }
     1103
     1104    if (psListLength(where->list)) {
     1105        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1106        psStringAppend(&query, " AND %s", whereClause);
     1107        psFree(whereClause);
     1108    }
     1109    psFree(where);
     1110
     1111    // treat limit == 0 as "no limit"
     1112    if (limit) {
     1113        psString limitString = psDBGenerateLimitSQL(limit);
     1114        psStringAppend(&query, " %s", limitString);
     1115        psFree(limitString);
     1116    }
     1117
     1118    if (!p_psDBRunQuery(config->dbh, query)) {
     1119        psError(PS_ERR_UNKNOWN, false, "database error");
     1120        psFree(query);
     1121        return false;
     1122    }
     1123    psFree(query);
     1124
     1125    long numUpdated = psDBAffectedRows(config->dbh);
     1126
     1127    psLogMsg("disttool", PS_LOG_INFO, "Inserted %ld rcRuns", numUpdated);
     1128
     1129    return true;
     1130}
     1131
     1132
     1133static bool updatercrunMode(pxConfig *config)
     1134{
     1135    PS_ASSERT_PTR_NON_NULL(config, false);
     1136
     1137    psMetadata *where = psMetadataAlloc();
     1138
     1139    PXOPT_LOOKUP_S64(rc_id, config->args, "-rc_id", false, false);
     1140    PXOPT_LOOKUP_STR(fs_name, config->args, "-fs_name", false, false);
     1141    PXOPT_LOOKUP_STR(status_fs_name, config->args, "-status_fs_name", false, false);
     1142    PXOPT_LOOKUP_S64(dest_id, config->args, "-dest_id", false, false);
     1143
     1144    // We either need rc_id or (dest_id and fs_name) to identifiy the rcRun
     1145    if ((!rc_id) && !(dest_id && fs_name)) {
     1146        psError(PXTOOLS_ERR_DATA, true, "either -rc_id or (-fs_name and -dest_id) are required");
     1147        return false;
     1148    }
     1149
     1150    // now that we have done the argument checking
     1151    PXOPT_COPY_S64(config->args, where, "-rc_id", "rc_id", "==");
     1152    PXOPT_COPY_STR(config->args, where, "-fs_name", "rcDSFileset.name", "==");
     1153    PXOPT_COPY_S64(config->args, where, "-dest_id", "rcRun.dest_id", "==");
     1154
     1155    if (!psListLength(where->list)) {
     1156        // this can't happen because we checked above
     1157        psFree(where);
     1158        psError(PXTOOLS_ERR_DATA, false, "search parameters are required");
     1159        return false;
     1160    }
     1161
     1162
     1163    PXOPT_LOOKUP_STR(last_fileset, config->args, "-set_last_fileset", false, false);
     1164    PXOPT_LOOKUP_STR(state, config->args, "-set_state", false, false);
     1165    PXOPT_LOOKUP_S16(fault, config->args, "-fault", false, false);
     1166
     1167    if (!state && (fault < 0)) {
     1168        psError(PXTOOLS_ERR_DATA, false, "parameters (-fault or -set_state) are required");
     1169        psFree(where);
     1170        return false;
     1171    }
     1172
     1173    psString query = pxDataGet("disttool_updatercrun.sql");
     1174    if (!query) {
     1175        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     1176        return false;
     1177    }
     1178
     1179    psString setString = psStringCopy("\n");
     1180    psString separator = "";
     1181    if (state) {
     1182        psStringAppend(&setString, " rcRun.state = '%s'", state);
     1183        separator = ",";
     1184    }
     1185
     1186    // default for fault is -1, so set it if it's zero or higher. This allows clearing fault
     1187    // without forcing revert first
     1188    if (fault >= 0) {
     1189        psStringAppend(&setString, "%s rcRun.fault = %d", separator, fault);
     1190    }
     1191
     1192    if (status_fs_name) {
     1193        psStringAppend(&setString, ", rcRun.status_fs_name = '%s'", status_fs_name);
     1194    }
     1195
     1196    if (last_fileset) {
     1197        psStringAppend(&setString, ", rcDestination.last_fileset = '%s'", last_fileset);
     1198    }
     1199
     1200    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1201    psStringAppend(&query, " AND %s", whereClause);
     1202    psFree(whereClause);
     1203    psFree(where);
     1204
     1205    if (!p_psDBRunQueryF(config->dbh, query, setString)) {
     1206        psError(PS_ERR_UNKNOWN, false, "database error");
     1207        psFree(setString);
     1208        psFree(query);
     1209        return false;
     1210    }
     1211    psFree(setString);
     1212    psFree(query);
     1213
     1214    long numUpdated = psDBAffectedRows(config->dbh);
     1215
     1216    psLogMsg("disttool", PS_LOG_INFO, "Updated %ld rows", numUpdated);
     1217
     1218    return true;
     1219}
     1220
     1221static bool revertrcrunMode(pxConfig *config)
     1222{
     1223    PS_ASSERT_PTR_NON_NULL(config, false);
     1224    psMetadata *where = psMetadataAlloc();
     1225    PXOPT_COPY_S64(config->args, where, "-rc_id", "rc_id", "==");
     1226    PXOPT_COPY_S64(config->args, where, "-fs_id", "fs_id", "==");
     1227    PXOPT_COPY_S64(config->args, where, "-dest_id", "dest_id", "==");
     1228    PXOPT_COPY_S64(config->args, where, "-fault", "fault", "==");
     1229
     1230    if (!psListLength(where->list) && !psMetadataLookupBool(NULL, config->args, "-all")) {
     1231        psFree(where);
     1232        psError(PXTOOLS_ERR_DATA, false, "search parameters are required");
     1233        return false;
     1234    }
     1235
     1236    psString query = pxDataGet("disttool_revertrcrun.sql");
     1237    if (!query) {
     1238        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
     1239        if (!psDBRollback(config->dbh)) {
     1240            psError(PS_ERR_UNKNOWN, false, "database error");
     1241        }
     1242        return false;
     1243    }
     1244
     1245    if (psListLength(where->list)) {
     1246        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1247        psStringAppend(&query, " AND %s", whereClause);
     1248        psFree(whereClause);
     1249    }
     1250
     1251    if (!p_psDBRunQuery(config->dbh, query)) {
     1252        psError(PS_ERR_UNKNOWN, false, "database error");
     1253        psFree(query);
     1254        if (!psDBRollback(config->dbh)) {
     1255            psError(PS_ERR_UNKNOWN, false, "database error");
     1256        }
     1257        return false;
     1258    }
     1259    psFree(query);
     1260
     1261    long numUpdated = psDBAffectedRows(config->dbh);
     1262
     1263    psLogMsg("disttool", PS_LOG_INFO, "Updated %ld rcRuns", numUpdated);
     1264
     1265    return true;
     1266}
     1267
     1268static bool definetargetMode(pxConfig *config)
     1269{
     1270    PS_ASSERT_PTR_NON_NULL(config, false);
     1271
     1272    // required
     1273    PXOPT_LOOKUP_STR(obs_mode, config->args, "-obs_mode", true, false);
     1274    PXOPT_LOOKUP_STR(stage, config->args, "-stage", true, false);
     1275
     1276    // optional
     1277    PXOPT_LOOKUP_BOOL(clean, config->args, "-clean", false);
     1278    PXOPT_LOOKUP_STR(state, config->args, "-set_state", false, false);
     1279    PXOPT_LOOKUP_STR(comment, config->args, "-comment", false, false);
     1280
     1281    distTargetRow *row = distTargetRowAlloc(
     1282            0,          // target_id
     1283            obs_mode,
     1284            stage,
     1285            clean,
     1286            state ? state : "enabled",
     1287            comment
     1288            );
     1289           
     1290    if (!row) {
     1291        psError(PS_ERR_UNKNOWN, false, "failed to allocate distTarget object");
     1292        return false;
     1293    }
     1294   if (!distTargetInsertObject(config->dbh, row)) {
     1295        psError(PS_ERR_UNKNOWN, false, "database error");
     1296        psFree(row);
     1297        return false;
     1298    }
     1299
     1300    // get the assigned target_id
     1301    row->target_id = psDBLastInsertID(config->dbh);
     1302
     1303    if (!distTargetPrintObject(stdout, row, true)) {
     1304            psError(PS_ERR_UNKNOWN, false, "failed to print object");
     1305            psFree(row);
     1306            return false;
     1307    }
     1308
     1309    psFree(row);
     1310
     1311    return true;
     1312}
     1313static bool updatetargetMode(pxConfig *config)
     1314{
     1315    PS_ASSERT_PTR_NON_NULL(config, false);
     1316
     1317    psMetadata *where = psMetadataAlloc();
     1318    PXOPT_COPY_S64(config->args, where, "-target_id", "target_id", "==");
     1319    PXOPT_COPY_STR(config->args, where, "-obs_mode", "obs_mode", "==");
     1320    PXOPT_COPY_STR(config->args, where, "-stage", "stage", "==");
     1321
     1322    PXOPT_LOOKUP_STR(state, config->args, "-set_state", true, false);
     1323
     1324    psString query = psStringCopy("UPDATE distTarget SET state = '%s'");
     1325
     1326    if (psListLength(where->list)) {
     1327        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1328        psStringAppend(&query, " WHERE %s", whereClause);
     1329        psFree(whereClause);
     1330    } else {
     1331        psError(PS_ERR_UNKNOWN, true, "search parameters are required");
     1332        psFree(where);
     1333        psFree(query);
     1334        return false;
     1335    }
     1336    psFree(where);
     1337
     1338    if (!p_psDBRunQueryF(config->dbh, query, state)) {
     1339        psError(PS_ERR_UNKNOWN, false, "database error");
     1340        psFree(query);
     1341        return false;
     1342    }
     1343    psFree(query);
     1344
     1345    return true;
     1346}
     1347
     1348static bool listtargetMode(pxConfig *config)
     1349{
     1350    PS_ASSERT_PTR_NON_NULL(config, false);
     1351
     1352    psMetadata *where = psMetadataAlloc();
     1353    PXOPT_COPY_S64(config->args, where, "-target_id", "target_id", "==");
     1354    PXOPT_COPY_STR(config->args, where, "-obs_mode", "obs_mode", "==");
     1355    PXOPT_COPY_STR(config->args, where, "-stage", "stage", "==");
     1356    PXOPT_COPY_STR(config->args, where, "-state", "state", "==");
     1357
     1358    PXOPT_LOOKUP_BOOL(clean, config->args, "-clean", false);
     1359    PXOPT_LOOKUP_BOOL(full, config->args, "-full", false);
     1360
     1361    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     1362    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     1363
     1364    if (clean && full) {
     1365        psError(PS_ERR_UNKNOWN, false, "can't select both -clean and -full");
     1366        return false;
     1367    }
     1368
     1369    psString query = psStringCopy("SELECT * FROM distTarget");
     1370
     1371    if (psListLength(where->list)) {
     1372        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1373        psStringAppend(&query, " WHERE %s", whereClause);
     1374        psFree(whereClause);
     1375        if (clean) {
     1376            psStringAppend(&query, " (AND clean)");
     1377        } else if (full) {
     1378            psStringAppend(&query, " (AND !clean)");
     1379        }
     1380    } else if (clean) {
     1381        psStringAppend(&query, " WHERE clean");
     1382    } else if (full) {
     1383        psStringAppend(&query, " WHERE !clean");
     1384    }
     1385    psFree(where);
     1386
     1387    // treat limit == 0 as "no limit"
     1388    if (limit) {
     1389        psString limitString = psDBGenerateLimitSQL(limit);
     1390        psStringAppend(&query, " %s", limitString);
     1391        psFree(limitString);
     1392    }
     1393
     1394    if (!p_psDBRunQuery(config->dbh, query)) {
     1395        psError(PS_ERR_UNKNOWN, false, "database error");
     1396        psFree(query);
     1397        if (!psDBRollback(config->dbh)) {
     1398            psError(PS_ERR_UNKNOWN, false, "database error");
     1399        }
     1400        return false;
     1401    }
     1402    psFree(query);
     1403
     1404    psArray *output = p_psDBFetchResult(config->dbh);
     1405    if (!output) {
     1406        psError(PS_ERR_UNKNOWN, false, "database error");
     1407        return false;
     1408    }
     1409    if (!psArrayLength(output)) {
     1410        psTrace("disttool", PS_LOG_INFO, "no rows found");
     1411        psFree(output);
     1412        return true;
     1413    }
     1414
     1415    if (!ippdbPrintMetadatas(stdout, output, "distTarget", !simple)) {
     1416        psError(PS_ERR_UNKNOWN, false, "failed to print array");
     1417        psFree(output);
     1418        return false;
     1419    }
     1420
     1421    psFree(output);
     1422
     1423    return true;
     1424}
     1425
     1426static bool definedsproductMode(pxConfig *config)
     1427{
     1428    PS_ASSERT_PTR_NON_NULL(config, false);
     1429
     1430    // required
     1431    PXOPT_LOOKUP_STR(name, config->args,   "-name", true, false);
     1432    PXOPT_LOOKUP_STR(dbname, config->args, "-ds_dbname", true, false);
     1433    PXOPT_LOOKUP_STR(dbhost, config->args, "-ds_dbhost", true, false);
     1434
     1435    // XXX: should we insure that these names do not contatin any whitespace?
     1436
     1437    rcDSProductRow *row = rcDSProductRowAlloc(
     1438            0,          // prod_id
     1439            name,
     1440            dbname,
     1441            dbhost
     1442            );
     1443           
     1444    if (!row) {
     1445        psError(PS_ERR_UNKNOWN, false, "failed to allocate rcDSProduct object");
     1446        return false;
     1447    }
     1448   if (!rcDSProductInsertObject(config->dbh, row)) {
     1449        psError(PS_ERR_UNKNOWN, false, "database error");
     1450        psFree(row);
     1451        return false;
     1452    }
     1453
     1454    // get the assigned target_id
     1455    row->prod_id = psDBLastInsertID(config->dbh);
     1456
     1457    if (!rcDSProductPrintObject(stdout, row, true)) {
     1458        psError(PS_ERR_UNKNOWN, false, "failed to print object");
     1459        psFree(row);
     1460        return false;
     1461    }
     1462
     1463    psFree(row);
     1464
     1465    return true;
     1466}
     1467static bool updatedsproductMode(pxConfig *config)
     1468{
     1469    PS_ASSERT_PTR_NON_NULL(config, false);
     1470
     1471    psMetadata *where = psMetadataAlloc();
     1472    PXOPT_COPY_S64(config->args, where, "-prod_id", "prod_id", "==");
     1473
     1474    PXOPT_LOOKUP_STR(dbname, config->args, "-ds_dbname", false, false);
     1475    PXOPT_LOOKUP_STR(dbhost, config->args, "-ds_dbhost", false, false);
     1476
     1477    if (!(dbname || dbhost)) {
     1478        psError(PS_ERR_UNKNOWN, true, "one or more of dbname or dbhost is required");
     1479        psFree(where);
     1480        return false;
     1481    }
     1482    psString query = psStringCopy("UPDATE rcDSProduct SET");
     1483    psString sep = "";
     1484    if (dbname) {
     1485        psStringAppend(&query, " dbname = '%s'", dbname);
     1486        sep = ",";
     1487    }
     1488    if (dbhost) {
     1489        psStringAppend(&query, " %s dbhost = '%s'", sep, dbhost);
     1490    }
     1491
     1492    if (psListLength(where->list)) {
     1493        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1494        psStringAppend(&query, " WHERE %s", whereClause);
     1495        psFree(whereClause);
     1496    } else {
     1497        psError(PS_ERR_UNKNOWN, true, "search parameters are required");
     1498        psFree(where);
     1499        psFree(query);
     1500        return false;
     1501    }
     1502    psFree(where);
     1503
     1504    if (!p_psDBRunQuery(config->dbh, query)) {
     1505        psError(PS_ERR_UNKNOWN, false, "database error");
     1506        psFree(query);
     1507        return false;
     1508    }
     1509    psFree(query);
     1510
     1511    return true;
     1512}
     1513
     1514static bool definedestinationMode(pxConfig *config)
     1515{
     1516    PS_ASSERT_PTR_NON_NULL(config, false);
     1517
     1518    // required
     1519    PXOPT_LOOKUP_S64(prod_id, config->args,      "-prod_id", true, false);
     1520    PXOPT_LOOKUP_STR(name, config->args,         "-name", true, false);
     1521
     1522    // optional
     1523    PXOPT_LOOKUP_STR(status_uri, config->args,   "-status_uri", false, false);
     1524    PXOPT_LOOKUP_STR(comment, config->args,      "-comment", false, false);
     1525    PXOPT_LOOKUP_STR(last_fileset, config->args, "-last_fileset", false, false);
     1526    PXOPT_LOOKUP_STR(state, config->args,        "-set_state", false, false);
     1527
     1528    // XXX: should we insure that these names do not contatin any whitespace?
     1529
     1530    rcDestinationRow *row = rcDestinationRowAlloc(
     1531            0,          // dest_id
     1532            prod_id,
     1533            name,
     1534            status_uri,
     1535            comment,
     1536            last_fileset,
     1537            state ? state : "enabled"
     1538            );
     1539           
     1540    if (!row) {
     1541        psError(PS_ERR_UNKNOWN, false, "failed to allocate rcDestination object");
     1542        return false;
     1543    }
     1544   if (!rcDestinationInsertObject(config->dbh, row)) {
     1545        psError(PS_ERR_UNKNOWN, false, "database error");
     1546        psFree(row);
     1547        return false;
     1548    }
     1549
     1550    // get the assigned target_id
     1551    row->dest_id = psDBLastInsertID(config->dbh);
     1552
     1553    if (!rcDestinationPrintObject(stdout, row, true)) {
     1554        psError(PS_ERR_UNKNOWN, false, "failed to print object");
     1555        psFree(row);
     1556        return false;
     1557    }
     1558
     1559    psFree(row);
     1560
     1561    return true;
     1562}
     1563
     1564static bool updatedestinationMode(pxConfig *config)
     1565{
     1566    PS_ASSERT_PTR_NON_NULL(config, false);
     1567
     1568    psMetadata *where = psMetadataAlloc();
     1569    PXOPT_COPY_S64(config->args, where, "-dest_id", "dest_id", "==");
     1570    PXOPT_COPY_S64(config->args, where, "-prod_id", "prod_id", "==");
     1571
     1572    PXOPT_LOOKUP_STR(state, config->args, "-set_state", false, false);
     1573#ifdef ALLOW_UPDATE_LAST_FILESET
     1574    PXOPT_LOOKUP_STR(last_fileset, config->args, "-set_last_fileset", false, false);
     1575    if (!(state || last_fileset)) {
     1576        psError(PS_ERR_UNKNOWN, true, "one or more of -set_state or -set_last_fileset is required");
     1577# else
     1578    if (!state) {
     1579#endif
     1580        psFree(where);
     1581        return false;
     1582    }
     1583    psString query = psStringCopy("UPDATE rcDestination SET");
     1584    psString sep = "";
     1585    if (state) {
     1586        psStringAppend(&query, " state = '%s'", state);
     1587        sep = ",";
     1588    }
     1589#ifdef ALLOW_UPDATE_LAST_FILESET
     1590    // last_fileset normally gets set by updatercrunMode
     1591    // Allowing it to be set here might cause problems
     1592    // especially since we are allowing selection by prod_id
     1593    if (last_fileset) {
     1594        psStringAppend(&query, " %s last_fileset = '%s'", sep, last_fileset);
     1595    }
     1596#endif
     1597
     1598    if (psListLength(where->list)) {
     1599        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1600        psStringAppend(&query, " WHERE %s", whereClause);
     1601        psFree(whereClause);
     1602    } else {
     1603        psError(PS_ERR_UNKNOWN, true, "search parameters are required");
     1604        psFree(where);
     1605        psFree(query);
     1606        return false;
     1607    }
     1608    psFree(where);
     1609
     1610    if (!p_psDBRunQuery(config->dbh, query)) {
     1611        psError(PS_ERR_UNKNOWN, false, "database error");
     1612        psFree(query);
     1613        return false;
     1614    }
     1615    psFree(query);
     1616
     1617    return true;
     1618}
     1619
     1620static bool defineinterestMode(pxConfig *config)
     1621{
     1622    PS_ASSERT_PTR_NON_NULL(config, false);
     1623
     1624    // required
     1625    PXOPT_LOOKUP_S64(dest_id, config->args,      "-dest_id", true, false);
     1626    PXOPT_LOOKUP_S64(target_id, config->args,    "-target_id", true, false);
     1627
     1628    // optional
     1629    PXOPT_LOOKUP_STR(state, config->args,        "-set_state", false, false);
     1630
     1631    // XXX: should we insure that these names do not contatin any whitespace?
     1632
     1633    rcInterestRow *row = rcInterestRowAlloc(
     1634            0,          // int_id
     1635            dest_id,
     1636            target_id,
     1637            state ? state : "enabled"
     1638            );
     1639           
     1640    if (!row) {
     1641        psError(PS_ERR_UNKNOWN, false, "failed to allocate rcInterest object");
     1642        return false;
     1643    }
     1644   if (!rcInterestInsertObject(config->dbh, row)) {
     1645        psError(PS_ERR_UNKNOWN, false, "database error");
     1646        psFree(row);
     1647        return false;
     1648    }
     1649
     1650    // get the assigned target_id
     1651    row->int_id = psDBLastInsertID(config->dbh);
     1652
     1653    if (!rcInterestPrintObject(stdout, row, true)) {
     1654        psError(PS_ERR_UNKNOWN, false, "failed to print object");
     1655        psFree(row);
     1656        return false;
     1657    }
     1658
     1659    psFree(row);
     1660
     1661    return true;
     1662}
     1663
     1664static bool updateinterestMode(pxConfig *config)
     1665{
     1666    PS_ASSERT_PTR_NON_NULL(config, false);
     1667
     1668    psMetadata *where = psMetadataAlloc();
     1669    PXOPT_COPY_S64(config->args, where, "-int_id",    "int_id", "==");
     1670    PXOPT_COPY_S64(config->args, where, "-dest_id",   "dest_id", "==");
     1671    PXOPT_COPY_S64(config->args, where, "-target_id", "target_id", "==");
     1672
     1673    PXOPT_LOOKUP_STR(state, config->args, "-set_state", false, false);
     1674    if (!state) {
     1675        psError(PS_ERR_UNKNOWN, true, "-set_state is required");
     1676        psFree(where);
     1677        return false;
     1678    }
     1679    psString query = NULL;
     1680    psStringAppend(&query, "UPDATE rcInterest SET state = '%s'", state);
     1681
     1682    if (psListLength(where->list)) {
     1683        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1684        psStringAppend(&query, " WHERE %s", whereClause);
     1685        psFree(whereClause);
     1686    } else {
     1687        psError(PS_ERR_UNKNOWN, true, "search parameters are required");
     1688        psFree(where);
     1689        psFree(query);
     1690        return false;
     1691    }
     1692    psFree(where);
     1693
     1694    if (!p_psDBRunQuery(config->dbh, query)) {
     1695        psError(PS_ERR_UNKNOWN, false, "database error");
     1696        psFree(query);
     1697        return false;
     1698    }
     1699    psFree(query);
     1700
     1701    return true;
     1702}
     1703
Note: See TracChangeset for help on using the changeset viewer.