IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 21, 2007, 4:25:34 PM (19 years ago)
Author:
jhoblitt
Message:

VERSION 1.1.27

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ippdb/src/ippdb.c

    r14451 r14598  
    2020/*
    2121 *
    22  * This file was generated by glueforge 1.03
     22 * This file was generated by glueforge 1.01
    2323 *
    2424 * Do NOT directly edit this file.
     
    7070#define DETRUNSUMMARY_TABLE_NAME "detRunSummary"
    7171#define DETREGISTEREDIMFILE_TABLE_NAME "detRegisteredImfile"
     72#define MAGICRUN_TABLE_NAME "magicRun"
     73#define MAGICINPUTSKYFILE_TABLE_NAME "magicInputSkyfile"
     74#define MAGICTREE_TABLE_NAME "magicTree"
     75#define MAGICNODERESULT_TABLE_NAME "magicNodeResult"
     76#define MAGICMASK_TABLE_NAME "magicMask"
    7277#define MAX_STRING_LENGTH 1024
    7378
     
    14201425static void pzPendingImfileRowFree(pzPendingImfileRow *object);
    14211426
    1422 pzPendingImfileRow *pzPendingImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, psS64 exp_id)
     1427pzPendingImfileRow *pzPendingImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id)
    14231428{
    14241429    pzPendingImfileRow *_object;
     
    14321437    _object->class = psStringCopy(class);
    14331438    _object->class_id = psStringCopy(class_id);
    1434     _object->exp_id = exp_id;
    14351439
    14361440    return _object;
     
    14741478        return false;
    14751479    }
    1476     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Unique Key", 64)) {
    1477         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    1478         psFree(md);
    1479         return false;
    1480     }
    14811480
    14821481    bool status = psDBCreateTable(dbh, PZPENDINGIMFILE_TABLE_NAME, md);
     
    14921491}
    14931492
    1494 bool pzPendingImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, psS64 exp_id)
     1493bool pzPendingImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id)
    14951494{
    14961495    psMetadata *md = psMetadataAlloc();
     
    15171516    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
    15181517        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    1519         psFree(md);
    1520         return false;
    1521     }
    1522     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
    1523         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    15241518        psFree(md);
    15251519        return false;
     
    15481542bool pzPendingImfileInsertObject(psDB *dbh, pzPendingImfileRow *object)
    15491543{
    1550     return pzPendingImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id, object->exp_id);
     1544    return pzPendingImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id);
    15511545}
    15521546
     
    16461640        return false;
    16471641    }
    1648     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
    1649         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    1650         psFree(md);
    1651         return false;
    1652     }
    16531642
    16541643
     
    16851674        return false;
    16861675    }
    1687     psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
    1688     if (!status) {
    1689         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
    1690         return false;
    1691     }
    1692 
    1693     return pzPendingImfileRowAlloc(exp_name, camera, telescope, class, class_id, exp_id);
     1676
     1677    return pzPendingImfileRowAlloc(exp_name, camera, telescope, class, class_id);
    16941678}
    16951679psArray *pzPendingImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    21212105static void pzDoneImfileRowFree(pzDoneImfileRow *object);
    21222106
    2123 pzDoneImfileRow *pzDoneImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, psS64 exp_id, const char *uri)
     2107pzDoneImfileRow *pzDoneImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, const char *uri)
    21242108{
    21252109    pzDoneImfileRow *_object;
     
    21332117    _object->class = psStringCopy(class);
    21342118    _object->class_id = psStringCopy(class_id);
    2135     _object->exp_id = exp_id;
    21362119    _object->uri = psStringCopy(uri);
    21372120
     
    21772160        return false;
    21782161    }
    2179     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Unique Key", 64)) {
    2180         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    2181         psFree(md);
    2182         return false;
    2183     }
    21842162    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
    21852163        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     
    22002178}
    22012179
    2202 bool pzDoneImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, psS64 exp_id, const char *uri)
     2180bool pzDoneImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, const char *uri)
    22032181{
    22042182    psMetadata *md = psMetadataAlloc();
     
    22252203    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
    22262204        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    2227         psFree(md);
    2228         return false;
    2229     }
    2230     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
    2231         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    22322205        psFree(md);
    22332206        return false;
     
    22612234bool pzDoneImfileInsertObject(psDB *dbh, pzDoneImfileRow *object)
    22622235{
    2263     return pzDoneImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id, object->exp_id, object->uri);
     2236    return pzDoneImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id, object->uri);
    22642237}
    22652238
     
    23592332        return false;
    23602333    }
    2361     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
    2362         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    2363         psFree(md);
    2364         return false;
    2365     }
    23662334    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
    23672335        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     
    24032371        return false;
    24042372    }
    2405     psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
    2406     if (!status) {
    2407         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
    2408         return false;
    2409     }
    24102373    char* uri = psMetadataLookupPtr(&status, md, "uri");
    24112374    if (!status) {
     
    24142377    }
    24152378
    2416     return pzDoneImfileRowAlloc(exp_name, camera, telescope, class, class_id, exp_id, uri);
     2379    return pzDoneImfileRowAlloc(exp_name, camera, telescope, class, class_id, uri);
    24172380}
    24182381psArray *pzDoneImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    93079270static void warpSkyfileRowFree(warpSkyfileRow *object);
    93089271
    9309 warpSkyfileRow *warpSkyfileRowAlloc(psS64 warp_id, const char *skycell_id, const char *tess_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psS16 fault)
     9272warpSkyfileRow *warpSkyfileRowAlloc(psS64 warp_id, const char *skycell_id, const char *tess_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF64 pixel_fill, psS16 fault)
    93109273{
    93119274    warpSkyfileRow  *_object;
     
    93219284    _object->bg = bg;
    93229285    _object->bg_stdev = bg_stdev;
     9286    _object->pixel_fill = pixel_fill;
    93239287    _object->fault = fault;
    93249288
     
    93729336        return false;
    93739337    }
     9338    if (!psMetadataAdd(md, PS_LIST_TAIL, "pixel_fill", PS_DATA_F64, "Key", 0.0)) {
     9339        psError(PS_ERR_UNKNOWN, false, "failed to add item pixel_fill");
     9340        psFree(md);
     9341        return false;
     9342    }
    93749343    if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, "Key", 0)) {
    93759344        psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
     
    93909359}
    93919360
    9392 bool warpSkyfileInsert(psDB * dbh, psS64 warp_id, const char *skycell_id, const char *tess_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psS16 fault)
     9361bool warpSkyfileInsert(psDB * dbh, psS64 warp_id, const char *skycell_id, const char *tess_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF64 pixel_fill, psS16 fault)
    93939362{
    93949363    psMetadata *md = psMetadataAlloc();
     
    94259394    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_stdev", PS_DATA_F64, NULL, bg_stdev)) {
    94269395        psError(PS_ERR_UNKNOWN, false, "failed to add item bg_stdev");
     9396        psFree(md);
     9397        return false;
     9398    }
     9399    if (!psMetadataAdd(md, PS_LIST_TAIL, "pixel_fill", PS_DATA_F64, NULL, pixel_fill)) {
     9400        psError(PS_ERR_UNKNOWN, false, "failed to add item pixel_fill");
    94279401        psFree(md);
    94289402        return false;
     
    94569430bool warpSkyfileInsertObject(psDB *dbh, warpSkyfileRow *object)
    94579431{
    9458     return warpSkyfileInsert(dbh, object->warp_id, object->skycell_id, object->tess_id, object->uri, object->path_base, object->bg, object->bg_stdev, object->fault);
     9432    return warpSkyfileInsert(dbh, object->warp_id, object->skycell_id, object->tess_id, object->uri, object->path_base, object->bg, object->bg_stdev, object->pixel_fill, object->fault);
    94599433}
    94609434
     
    95649538        return false;
    95659539    }
     9540    if (!psMetadataAdd(md, PS_LIST_TAIL, "pixel_fill", PS_DATA_F64, NULL, object->pixel_fill)) {
     9541        psError(PS_ERR_UNKNOWN, false, "failed to add item pixel_fill");
     9542        psFree(md);
     9543        return false;
     9544    }
    95669545    if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, object->fault)) {
    95679546        psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
     
    96139592        return false;
    96149593    }
     9594    psF64 pixel_fill = psMetadataLookupF64(&status, md, "pixel_fill");
     9595    if (!status) {
     9596        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item pixel_fill");
     9597        return false;
     9598    }
    96159599    psS16 fault = psMetadataLookupS16(&status, md, "fault");
    96169600    if (!status) {
     
    96199603    }
    96209604
    9621     return warpSkyfileRowAlloc(warp_id, skycell_id, tess_id, uri, path_base, bg, bg_stdev, fault);
     9605    return warpSkyfileRowAlloc(warp_id, skycell_id, tess_id, uri, path_base, bg, bg_stdev, pixel_fill, fault);
    96229606}
    96239607psArray *warpSkyfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    1890218886    return true;
    1890318887}
     18888static void magicRunRowFree(magicRunRow *object);
     18889
     18890magicRunRow *magicRunRowAlloc(psS64 magic_id, const char *state, const char *workdir, const char *workdir_state, const char *label, const char *dvodb, psTime* registered)
     18891{
     18892    magicRunRow     *_object;
     18893
     18894    _object = psAlloc(sizeof(magicRunRow));
     18895    psMemSetDeallocator(_object, (psFreeFunc)magicRunRowFree);
     18896
     18897    _object->magic_id = magic_id;
     18898    _object->state = psStringCopy(state);
     18899    _object->workdir = psStringCopy(workdir);
     18900    _object->workdir_state = psStringCopy(workdir_state);
     18901    _object->label = psStringCopy(label);
     18902    _object->dvodb = psStringCopy(dvodb);
     18903    _object->registered = psTimeCopy(registered);
     18904
     18905    return _object;
     18906}
     18907
     18908static void magicRunRowFree(magicRunRow *object)
     18909{
     18910    psFree(object->state);
     18911    psFree(object->workdir);
     18912    psFree(object->workdir_state);
     18913    psFree(object->label);
     18914    psFree(object->dvodb);
     18915    psFree(object->registered);
     18916}
     18917
     18918bool magicRunCreateTable(psDB *dbh)
     18919{
     18920    psMetadata *md = psMetadataAlloc();
     18921    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, "Primary Key AUTO_INCREMENT", 0)) {
     18922        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     18923        psFree(md);
     18924        return false;
     18925    }
     18926    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, "Key", "64")) {
     18927        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     18928        psFree(md);
     18929        return false;
     18930    }
     18931    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, "255")) {
     18932        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
     18933        psFree(md);
     18934        return false;
     18935    }
     18936    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, "Key", "255")) {
     18937        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
     18938        psFree(md);
     18939        return false;
     18940    }
     18941    if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, "key", "64")) {
     18942        psError(PS_ERR_UNKNOWN, false, "failed to add item label");
     18943        psFree(md);
     18944        return false;
     18945    }
     18946    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, "255")) {
     18947        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
     18948        psFree(md);
     18949        return false;
     18950    }
     18951    if (!psMetadataAdd(md, PS_LIST_TAIL, "registered", PS_DATA_TIME, NULL, NULL)) {
     18952        psError(PS_ERR_UNKNOWN, false, "failed to add item registered");
     18953        psFree(md);
     18954        return false;
     18955    }
     18956
     18957    bool status = psDBCreateTable(dbh, MAGICRUN_TABLE_NAME, md);
     18958
     18959    psFree(md);
     18960
     18961    return status;
     18962}
     18963
     18964bool magicRunDropTable(psDB *dbh)
     18965{
     18966    return psDBDropTable(dbh, MAGICRUN_TABLE_NAME);
     18967}
     18968
     18969bool magicRunInsert(psDB * dbh, psS64 magic_id, const char *state, const char *workdir, const char *workdir_state, const char *label, const char *dvodb, psTime* registered)
     18970{
     18971    psMetadata *md = psMetadataAlloc();
     18972    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, magic_id)) {
     18973        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     18974        psFree(md);
     18975        return false;
     18976    }
     18977    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, state)) {
     18978        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     18979        psFree(md);
     18980        return false;
     18981    }
     18982    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, workdir)) {
     18983        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
     18984        psFree(md);
     18985        return false;
     18986    }
     18987    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, NULL, workdir_state)) {
     18988        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
     18989        psFree(md);
     18990        return false;
     18991    }
     18992    if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, NULL, label)) {
     18993        psError(PS_ERR_UNKNOWN, false, "failed to add item label");
     18994        psFree(md);
     18995        return false;
     18996    }
     18997    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, dvodb)) {
     18998        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
     18999        psFree(md);
     19000        return false;
     19001    }
     19002    if (!psMetadataAdd(md, PS_LIST_TAIL, "registered", PS_DATA_TIME, NULL, registered)) {
     19003        psError(PS_ERR_UNKNOWN, false, "failed to add item registered");
     19004        psFree(md);
     19005        return false;
     19006    }
     19007
     19008    bool status = psDBInsertOneRow(dbh, MAGICRUN_TABLE_NAME, md);
     19009    psFree(md);
     19010
     19011    return status;
     19012}
     19013
     19014long long magicRunDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
     19015{
     19016    long long       deleted = 0;
     19017
     19018    long long count = psDBDeleteRows(dbh, MAGICRUN_TABLE_NAME, where, limit);
     19019    if (count < 0) {
     19020        psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicRun");
     19021        return count;
     19022
     19023        deleted += count;
     19024    }
     19025
     19026    return deleted;
     19027}
     19028bool magicRunInsertObject(psDB *dbh, magicRunRow *object)
     19029{
     19030    return magicRunInsert(dbh, object->magic_id, object->state, object->workdir, object->workdir_state, object->label, object->dvodb, object->registered);
     19031}
     19032
     19033bool magicRunInsertObjects(psDB *dbh, psArray *objects)
     19034{
     19035    for (long i = 0; i < psArrayLength(objects); i++) {
     19036        if (!magicRunInsertObject(dbh, objects->data[i])) {
     19037            return false;
     19038        }
     19039    }
     19040
     19041    return true;
     19042}
     19043
     19044bool magicRunInsertFits(psDB *dbh, const psFits *fits)
     19045{
     19046    psArray         *rowSet;
     19047
     19048    // move to (the first?) extension named  MAGICRUN_TABLE_NAME
     19049    if (!psFitsMoveExtName(fits, MAGICRUN_TABLE_NAME)) {
     19050        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", MAGICRUN_TABLE_NAME);
     19051        return false;
     19052    }
     19053
     19054    // check HDU type
     19055    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
     19056        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
     19057        return false;
     19058    }
     19059
     19060    // read fits table
     19061    rowSet = psFitsReadTable(fits);
     19062    if (!rowSet) {
     19063        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
     19064        psFree(rowSet);
     19065        return false;
     19066    }
     19067
     19068    if (!psDBInsertRows(dbh, MAGICRUN_TABLE_NAME, rowSet)) {
     19069        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
     19070        psFree(rowSet);
     19071        return false;
     19072    }
     19073
     19074    psFree(rowSet);
     19075
     19076    return true;
     19077}
     19078
     19079bool magicRunSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
     19080{
     19081    psArray         *rowSet;
     19082
     19083    rowSet = psDBSelectRows(dbh, MAGICRUN_TABLE_NAME, where, limit);
     19084    if (!rowSet) {
     19085        return false;
     19086    }
     19087
     19088    // output to fits
     19089    if (!psFitsWriteTable(fits, NULL, rowSet, MAGICRUN_TABLE_NAME)) {
     19090        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
     19091        psFree(rowSet);
     19092        return false;
     19093    }
     19094
     19095    psFree(rowSet);
     19096
     19097    return true;
     19098}
     19099
     19100psMetadata *magicRunMetadataFromObject(const magicRunRow *object)
     19101{
     19102    psMetadata *md = psMetadataAlloc();
     19103    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, object->magic_id)) {
     19104        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     19105        psFree(md);
     19106        return false;
     19107    }
     19108    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
     19109        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     19110        psFree(md);
     19111        return false;
     19112    }
     19113    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, object->workdir)) {
     19114        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
     19115        psFree(md);
     19116        return false;
     19117    }
     19118    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, NULL, object->workdir_state)) {
     19119        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
     19120        psFree(md);
     19121        return false;
     19122    }
     19123    if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, NULL, object->label)) {
     19124        psError(PS_ERR_UNKNOWN, false, "failed to add item label");
     19125        psFree(md);
     19126        return false;
     19127    }
     19128    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, object->dvodb)) {
     19129        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
     19130        psFree(md);
     19131        return false;
     19132    }
     19133    if (!psMetadataAdd(md, PS_LIST_TAIL, "registered", PS_DATA_TIME, NULL, object->registered)) {
     19134        psError(PS_ERR_UNKNOWN, false, "failed to add item registered");
     19135        psFree(md);
     19136        return false;
     19137    }
     19138
     19139
     19140    return md;
     19141}
     19142
     19143magicRunRow *magicRunObjectFromMetadata(psMetadata *md)
     19144{
     19145
     19146bool status = false;
     19147    psS64 magic_id = psMetadataLookupS64(&status, md, "magic_id");
     19148    if (!status) {
     19149        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic_id");
     19150        return false;
     19151    }
     19152    char* state = psMetadataLookupPtr(&status, md, "state");
     19153    if (!status) {
     19154        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
     19155        return false;
     19156    }
     19157    char* workdir = psMetadataLookupPtr(&status, md, "workdir");
     19158    if (!status) {
     19159        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item workdir");
     19160        return false;
     19161    }
     19162    char* workdir_state = psMetadataLookupPtr(&status, md, "workdir_state");
     19163    if (!status) {
     19164        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item workdir_state");
     19165        return false;
     19166    }
     19167    char* label = psMetadataLookupPtr(&status, md, "label");
     19168    if (!status) {
     19169        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item label");
     19170        return false;
     19171    }
     19172    char* dvodb = psMetadataLookupPtr(&status, md, "dvodb");
     19173    if (!status) {
     19174        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dvodb");
     19175        return false;
     19176    }
     19177    psTime* registered = psMetadataLookupPtr(&status, md, "registered");
     19178    if (!status) {
     19179        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item registered");
     19180        return false;
     19181    }
     19182
     19183    return magicRunRowAlloc(magic_id, state, workdir, workdir_state, label, dvodb, registered);
     19184}
     19185psArray *magicRunSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     19186{
     19187    psArray         *rowSet;
     19188    psArray         *returnSet;
     19189    psU64           i;
     19190
     19191    rowSet = psDBSelectRows(dbh, MAGICRUN_TABLE_NAME, where, limit);
     19192    if (!rowSet) {
     19193        return NULL;
     19194    }
     19195
     19196    // convert psMetadata rows to row objects
     19197
     19198    returnSet = psArrayAllocEmpty(rowSet->n);
     19199
     19200    for (i = 0; i < rowSet->n; i++) {
     19201        magicRunRow *object = magicRunObjectFromMetadata(rowSet->data[i]);
     19202        psArrayAdd(returnSet, 0, object);
     19203        psFree(object);
     19204    }
     19205
     19206    psFree(rowSet);
     19207
     19208    return returnSet;
     19209}
     19210bool magicRunDeleteObject(psDB *dbh, const magicRunRow *object)
     19211{
     19212    psMetadata *where = magicRunMetadataFromObject(object);
     19213    long long count = psDBDeleteRows(dbh, MAGICRUN_TABLE_NAME, where, 0);
     19214    psFree(where);
     19215    if (count < 0) {
     19216        psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicRun");
     19217        return false;
     19218    }
     19219    if (count > 1) {
     19220        // XXX should this be a psAbort() instead?  It is possible that
     19221        // having an object match multiple rows was by design.
     19222        psError(PS_ERR_UNKNOWN, true, "magicRunRow object matched more then one row.  Check your database schema");
     19223        return false;
     19224    }
     19225
     19226    return true;
     19227}
     19228long long magicRunDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
     19229{
     19230    long long       deleted = 0;
     19231
     19232    for (long long i = 0; i < objects->n; i++) {
     19233        magicRunRow *object = objects->data[i];
     19234        psMetadata *where = magicRunMetadataFromObject(object);
     19235        long long count = psDBDeleteRows(dbh, MAGICRUN_TABLE_NAME, where, limit);
     19236        psFree(where);
     19237        if (count < 0) {
     19238            psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicRun");
     19239            return count;
     19240        }
     19241
     19242        deleted += count;
     19243    }
     19244
     19245    return deleted;
     19246}
     19247bool magicRunPrintObjects(FILE *stream, psArray *objects, bool mdcf)
     19248{
     19249    PS_ASSERT_PTR_NON_NULL(objects, false);
     19250
     19251    psMetadata *output = psMetadataAlloc();
     19252    for (long i = 0; i < psArrayLength(objects); i++) {
     19253        psMetadata *md = magicRunMetadataFromObject(objects->data[i]);
     19254        if (!psMetadataAddMetadata(
     19255            output,
     19256            PS_LIST_TAIL,
     19257            MAGICRUN_TABLE_NAME,
     19258            PS_META_DUPLICATE_OK,
     19259            NULL,
     19260            md
     19261        )) {
     19262            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
     19263            psFree(md);
     19264            psFree(output);
     19265            return false;
     19266        }
     19267        psFree(md);
     19268    }
     19269
     19270    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
     19271        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     19272        psFree(output);
     19273    }
     19274    psFree(output);
     19275
     19276    return true;
     19277}
     19278bool magicRunPrintObject(FILE *stream, magicRunRow *object, bool mdcf)
     19279{
     19280    PS_ASSERT_PTR_NON_NULL(object, false);
     19281
     19282    psMetadata *md = magicRunMetadataFromObject(object);
     19283
     19284    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
     19285        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     19286        psFree(md);
     19287    }
     19288
     19289    psFree(md);
     19290
     19291    return true;
     19292}
     19293static void magicInputSkyfileRowFree(magicInputSkyfileRow *object);
     19294
     19295magicInputSkyfileRow *magicInputSkyfileRowAlloc(psS64 magic_id, psS64 diff_id, psS32 node)
     19296{
     19297    magicInputSkyfileRow *_object;
     19298
     19299    _object = psAlloc(sizeof(magicInputSkyfileRow));
     19300    psMemSetDeallocator(_object, (psFreeFunc)magicInputSkyfileRowFree);
     19301
     19302    _object->magic_id = magic_id;
     19303    _object->diff_id = diff_id;
     19304    _object->node = node;
     19305
     19306    return _object;
     19307}
     19308
     19309static void magicInputSkyfileRowFree(magicInputSkyfileRow *object)
     19310{
     19311}
     19312
     19313bool magicInputSkyfileCreateTable(psDB *dbh)
     19314{
     19315    psMetadata *md = psMetadataAlloc();
     19316    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, "Primary Key fkey(magic_id) ref magicRun(magic_id)", 0)) {
     19317        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     19318        psFree(md);
     19319        return false;
     19320    }
     19321    if (!psMetadataAdd(md, PS_LIST_TAIL, "diff_id", PS_DATA_S64, "Key fkey(diff_id) ref diffRun(diff_id)", 0)) {
     19322        psError(PS_ERR_UNKNOWN, false, "failed to add item diff_id");
     19323        psFree(md);
     19324        return false;
     19325    }
     19326    if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_S32, "AUTO_INCREMENT INDEX(magic_id, node)", 0)) {
     19327        psError(PS_ERR_UNKNOWN, false, "failed to add item node");
     19328        psFree(md);
     19329        return false;
     19330    }
     19331
     19332    bool status = psDBCreateTable(dbh, MAGICINPUTSKYFILE_TABLE_NAME, md);
     19333
     19334    psFree(md);
     19335
     19336    return status;
     19337}
     19338
     19339bool magicInputSkyfileDropTable(psDB *dbh)
     19340{
     19341    return psDBDropTable(dbh, MAGICINPUTSKYFILE_TABLE_NAME);
     19342}
     19343
     19344bool magicInputSkyfileInsert(psDB * dbh, psS64 magic_id, psS64 diff_id, psS32 node)
     19345{
     19346    psMetadata *md = psMetadataAlloc();
     19347    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, magic_id)) {
     19348        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     19349        psFree(md);
     19350        return false;
     19351    }
     19352    if (!psMetadataAdd(md, PS_LIST_TAIL, "diff_id", PS_DATA_S64, NULL, diff_id)) {
     19353        psError(PS_ERR_UNKNOWN, false, "failed to add item diff_id");
     19354        psFree(md);
     19355        return false;
     19356    }
     19357    if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_S32, NULL, node)) {
     19358        psError(PS_ERR_UNKNOWN, false, "failed to add item node");
     19359        psFree(md);
     19360        return false;
     19361    }
     19362
     19363    bool status = psDBInsertOneRow(dbh, MAGICINPUTSKYFILE_TABLE_NAME, md);
     19364    psFree(md);
     19365
     19366    return status;
     19367}
     19368
     19369long long magicInputSkyfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
     19370{
     19371    long long       deleted = 0;
     19372
     19373    long long count = psDBDeleteRows(dbh, MAGICINPUTSKYFILE_TABLE_NAME, where, limit);
     19374    if (count < 0) {
     19375        psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicInputSkyfile");
     19376        return count;
     19377
     19378        deleted += count;
     19379    }
     19380
     19381    return deleted;
     19382}
     19383bool magicInputSkyfileInsertObject(psDB *dbh, magicInputSkyfileRow *object)
     19384{
     19385    return magicInputSkyfileInsert(dbh, object->magic_id, object->diff_id, object->node);
     19386}
     19387
     19388bool magicInputSkyfileInsertObjects(psDB *dbh, psArray *objects)
     19389{
     19390    for (long i = 0; i < psArrayLength(objects); i++) {
     19391        if (!magicInputSkyfileInsertObject(dbh, objects->data[i])) {
     19392            return false;
     19393        }
     19394    }
     19395
     19396    return true;
     19397}
     19398
     19399bool magicInputSkyfileInsertFits(psDB *dbh, const psFits *fits)
     19400{
     19401    psArray         *rowSet;
     19402
     19403    // move to (the first?) extension named  MAGICINPUTSKYFILE_TABLE_NAME
     19404    if (!psFitsMoveExtName(fits, MAGICINPUTSKYFILE_TABLE_NAME)) {
     19405        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", MAGICINPUTSKYFILE_TABLE_NAME);
     19406        return false;
     19407    }
     19408
     19409    // check HDU type
     19410    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
     19411        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
     19412        return false;
     19413    }
     19414
     19415    // read fits table
     19416    rowSet = psFitsReadTable(fits);
     19417    if (!rowSet) {
     19418        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
     19419        psFree(rowSet);
     19420        return false;
     19421    }
     19422
     19423    if (!psDBInsertRows(dbh, MAGICINPUTSKYFILE_TABLE_NAME, rowSet)) {
     19424        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
     19425        psFree(rowSet);
     19426        return false;
     19427    }
     19428
     19429    psFree(rowSet);
     19430
     19431    return true;
     19432}
     19433
     19434bool magicInputSkyfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
     19435{
     19436    psArray         *rowSet;
     19437
     19438    rowSet = psDBSelectRows(dbh, MAGICINPUTSKYFILE_TABLE_NAME, where, limit);
     19439    if (!rowSet) {
     19440        return false;
     19441    }
     19442
     19443    // output to fits
     19444    if (!psFitsWriteTable(fits, NULL, rowSet, MAGICINPUTSKYFILE_TABLE_NAME)) {
     19445        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
     19446        psFree(rowSet);
     19447        return false;
     19448    }
     19449
     19450    psFree(rowSet);
     19451
     19452    return true;
     19453}
     19454
     19455psMetadata *magicInputSkyfileMetadataFromObject(const magicInputSkyfileRow *object)
     19456{
     19457    psMetadata *md = psMetadataAlloc();
     19458    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, object->magic_id)) {
     19459        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     19460        psFree(md);
     19461        return false;
     19462    }
     19463    if (!psMetadataAdd(md, PS_LIST_TAIL, "diff_id", PS_DATA_S64, NULL, object->diff_id)) {
     19464        psError(PS_ERR_UNKNOWN, false, "failed to add item diff_id");
     19465        psFree(md);
     19466        return false;
     19467    }
     19468    if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_S32, NULL, object->node)) {
     19469        psError(PS_ERR_UNKNOWN, false, "failed to add item node");
     19470        psFree(md);
     19471        return false;
     19472    }
     19473
     19474
     19475    return md;
     19476}
     19477
     19478magicInputSkyfileRow *magicInputSkyfileObjectFromMetadata(psMetadata *md)
     19479{
     19480
     19481bool status = false;
     19482    psS64 magic_id = psMetadataLookupS64(&status, md, "magic_id");
     19483    if (!status) {
     19484        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic_id");
     19485        return false;
     19486    }
     19487    psS64 diff_id = psMetadataLookupS64(&status, md, "diff_id");
     19488    if (!status) {
     19489        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item diff_id");
     19490        return false;
     19491    }
     19492    psS32 node = psMetadataLookupS32(&status, md, "node");
     19493    if (!status) {
     19494        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item node");
     19495        return false;
     19496    }
     19497
     19498    return magicInputSkyfileRowAlloc(magic_id, diff_id, node);
     19499}
     19500psArray *magicInputSkyfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     19501{
     19502    psArray         *rowSet;
     19503    psArray         *returnSet;
     19504    psU64           i;
     19505
     19506    rowSet = psDBSelectRows(dbh, MAGICINPUTSKYFILE_TABLE_NAME, where, limit);
     19507    if (!rowSet) {
     19508        return NULL;
     19509    }
     19510
     19511    // convert psMetadata rows to row objects
     19512
     19513    returnSet = psArrayAllocEmpty(rowSet->n);
     19514
     19515    for (i = 0; i < rowSet->n; i++) {
     19516        magicInputSkyfileRow *object = magicInputSkyfileObjectFromMetadata(rowSet->data[i]);
     19517        psArrayAdd(returnSet, 0, object);
     19518        psFree(object);
     19519    }
     19520
     19521    psFree(rowSet);
     19522
     19523    return returnSet;
     19524}
     19525bool magicInputSkyfileDeleteObject(psDB *dbh, const magicInputSkyfileRow *object)
     19526{
     19527    psMetadata *where = magicInputSkyfileMetadataFromObject(object);
     19528    long long count = psDBDeleteRows(dbh, MAGICINPUTSKYFILE_TABLE_NAME, where, 0);
     19529    psFree(where);
     19530    if (count < 0) {
     19531        psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicInputSkyfile");
     19532        return false;
     19533    }
     19534    if (count > 1) {
     19535        // XXX should this be a psAbort() instead?  It is possible that
     19536        // having an object match multiple rows was by design.
     19537        psError(PS_ERR_UNKNOWN, true, "magicInputSkyfileRow object matched more then one row.  Check your database schema");
     19538        return false;
     19539    }
     19540
     19541    return true;
     19542}
     19543long long magicInputSkyfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
     19544{
     19545    long long       deleted = 0;
     19546
     19547    for (long long i = 0; i < objects->n; i++) {
     19548        magicInputSkyfileRow *object = objects->data[i];
     19549        psMetadata *where = magicInputSkyfileMetadataFromObject(object);
     19550        long long count = psDBDeleteRows(dbh, MAGICINPUTSKYFILE_TABLE_NAME, where, limit);
     19551        psFree(where);
     19552        if (count < 0) {
     19553            psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicInputSkyfile");
     19554            return count;
     19555        }
     19556
     19557        deleted += count;
     19558    }
     19559
     19560    return deleted;
     19561}
     19562bool magicInputSkyfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
     19563{
     19564    PS_ASSERT_PTR_NON_NULL(objects, false);
     19565
     19566    psMetadata *output = psMetadataAlloc();
     19567    for (long i = 0; i < psArrayLength(objects); i++) {
     19568        psMetadata *md = magicInputSkyfileMetadataFromObject(objects->data[i]);
     19569        if (!psMetadataAddMetadata(
     19570            output,
     19571            PS_LIST_TAIL,
     19572            MAGICINPUTSKYFILE_TABLE_NAME,
     19573            PS_META_DUPLICATE_OK,
     19574            NULL,
     19575            md
     19576        )) {
     19577            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
     19578            psFree(md);
     19579            psFree(output);
     19580            return false;
     19581        }
     19582        psFree(md);
     19583    }
     19584
     19585    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
     19586        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     19587        psFree(output);
     19588    }
     19589    psFree(output);
     19590
     19591    return true;
     19592}
     19593bool magicInputSkyfilePrintObject(FILE *stream, magicInputSkyfileRow *object, bool mdcf)
     19594{
     19595    PS_ASSERT_PTR_NON_NULL(object, false);
     19596
     19597    psMetadata *md = magicInputSkyfileMetadataFromObject(object);
     19598
     19599    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
     19600        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     19601        psFree(md);
     19602    }
     19603
     19604    psFree(md);
     19605
     19606    return true;
     19607}
     19608static void magicTreeRowFree(magicTreeRow *object);
     19609
     19610magicTreeRow *magicTreeRowAlloc(psS64 magic_id, const char *node, const char *dep)
     19611{
     19612    magicTreeRow    *_object;
     19613
     19614    _object = psAlloc(sizeof(magicTreeRow));
     19615    psMemSetDeallocator(_object, (psFreeFunc)magicTreeRowFree);
     19616
     19617    _object->magic_id = magic_id;
     19618    _object->node = psStringCopy(node);
     19619    _object->dep = psStringCopy(dep);
     19620
     19621    return _object;
     19622}
     19623
     19624static void magicTreeRowFree(magicTreeRow *object)
     19625{
     19626    psFree(object->node);
     19627    psFree(object->dep);
     19628}
     19629
     19630bool magicTreeCreateTable(psDB *dbh)
     19631{
     19632    psMetadata *md = psMetadataAlloc();
     19633    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, "Primary Key fkey(magic_id) ref magicRun(magic_id)", 0)) {
     19634        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     19635        psFree(md);
     19636        return false;
     19637    }
     19638    if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, "Primary Key fkey(magic_id, node) ref magicInputSkyfile(magic_id, node)", "64")) {
     19639        psError(PS_ERR_UNKNOWN, false, "failed to add item node");
     19640        psFree(md);
     19641        return false;
     19642    }
     19643    if (!psMetadataAdd(md, PS_LIST_TAIL, "dep", PS_DATA_STRING, "fkey(magic_id, dep) ref magicInputSkyfile(magic_id, node)", "64")) {
     19644        psError(PS_ERR_UNKNOWN, false, "failed to add item dep");
     19645        psFree(md);
     19646        return false;
     19647    }
     19648
     19649    bool status = psDBCreateTable(dbh, MAGICTREE_TABLE_NAME, md);
     19650
     19651    psFree(md);
     19652
     19653    return status;
     19654}
     19655
     19656bool magicTreeDropTable(psDB *dbh)
     19657{
     19658    return psDBDropTable(dbh, MAGICTREE_TABLE_NAME);
     19659}
     19660
     19661bool magicTreeInsert(psDB * dbh, psS64 magic_id, const char *node, const char *dep)
     19662{
     19663    psMetadata *md = psMetadataAlloc();
     19664    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, magic_id)) {
     19665        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     19666        psFree(md);
     19667        return false;
     19668    }
     19669    if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, NULL, node)) {
     19670        psError(PS_ERR_UNKNOWN, false, "failed to add item node");
     19671        psFree(md);
     19672        return false;
     19673    }
     19674    if (!psMetadataAdd(md, PS_LIST_TAIL, "dep", PS_DATA_STRING, NULL, dep)) {
     19675        psError(PS_ERR_UNKNOWN, false, "failed to add item dep");
     19676        psFree(md);
     19677        return false;
     19678    }
     19679
     19680    bool status = psDBInsertOneRow(dbh, MAGICTREE_TABLE_NAME, md);
     19681    psFree(md);
     19682
     19683    return status;
     19684}
     19685
     19686long long magicTreeDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
     19687{
     19688    long long       deleted = 0;
     19689
     19690    long long count = psDBDeleteRows(dbh, MAGICTREE_TABLE_NAME, where, limit);
     19691    if (count < 0) {
     19692        psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicTree");
     19693        return count;
     19694
     19695        deleted += count;
     19696    }
     19697
     19698    return deleted;
     19699}
     19700bool magicTreeInsertObject(psDB *dbh, magicTreeRow *object)
     19701{
     19702    return magicTreeInsert(dbh, object->magic_id, object->node, object->dep);
     19703}
     19704
     19705bool magicTreeInsertObjects(psDB *dbh, psArray *objects)
     19706{
     19707    for (long i = 0; i < psArrayLength(objects); i++) {
     19708        if (!magicTreeInsertObject(dbh, objects->data[i])) {
     19709            return false;
     19710        }
     19711    }
     19712
     19713    return true;
     19714}
     19715
     19716bool magicTreeInsertFits(psDB *dbh, const psFits *fits)
     19717{
     19718    psArray         *rowSet;
     19719
     19720    // move to (the first?) extension named  MAGICTREE_TABLE_NAME
     19721    if (!psFitsMoveExtName(fits, MAGICTREE_TABLE_NAME)) {
     19722        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", MAGICTREE_TABLE_NAME);
     19723        return false;
     19724    }
     19725
     19726    // check HDU type
     19727    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
     19728        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
     19729        return false;
     19730    }
     19731
     19732    // read fits table
     19733    rowSet = psFitsReadTable(fits);
     19734    if (!rowSet) {
     19735        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
     19736        psFree(rowSet);
     19737        return false;
     19738    }
     19739
     19740    if (!psDBInsertRows(dbh, MAGICTREE_TABLE_NAME, rowSet)) {
     19741        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
     19742        psFree(rowSet);
     19743        return false;
     19744    }
     19745
     19746    psFree(rowSet);
     19747
     19748    return true;
     19749}
     19750
     19751bool magicTreeSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
     19752{
     19753    psArray         *rowSet;
     19754
     19755    rowSet = psDBSelectRows(dbh, MAGICTREE_TABLE_NAME, where, limit);
     19756    if (!rowSet) {
     19757        return false;
     19758    }
     19759
     19760    // output to fits
     19761    if (!psFitsWriteTable(fits, NULL, rowSet, MAGICTREE_TABLE_NAME)) {
     19762        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
     19763        psFree(rowSet);
     19764        return false;
     19765    }
     19766
     19767    psFree(rowSet);
     19768
     19769    return true;
     19770}
     19771
     19772psMetadata *magicTreeMetadataFromObject(const magicTreeRow *object)
     19773{
     19774    psMetadata *md = psMetadataAlloc();
     19775    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, object->magic_id)) {
     19776        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     19777        psFree(md);
     19778        return false;
     19779    }
     19780    if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, NULL, object->node)) {
     19781        psError(PS_ERR_UNKNOWN, false, "failed to add item node");
     19782        psFree(md);
     19783        return false;
     19784    }
     19785    if (!psMetadataAdd(md, PS_LIST_TAIL, "dep", PS_DATA_STRING, NULL, object->dep)) {
     19786        psError(PS_ERR_UNKNOWN, false, "failed to add item dep");
     19787        psFree(md);
     19788        return false;
     19789    }
     19790
     19791
     19792    return md;
     19793}
     19794
     19795magicTreeRow *magicTreeObjectFromMetadata(psMetadata *md)
     19796{
     19797
     19798bool status = false;
     19799    psS64 magic_id = psMetadataLookupS64(&status, md, "magic_id");
     19800    if (!status) {
     19801        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic_id");
     19802        return false;
     19803    }
     19804    char* node = psMetadataLookupPtr(&status, md, "node");
     19805    if (!status) {
     19806        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item node");
     19807        return false;
     19808    }
     19809    char* dep = psMetadataLookupPtr(&status, md, "dep");
     19810    if (!status) {
     19811        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dep");
     19812        return false;
     19813    }
     19814
     19815    return magicTreeRowAlloc(magic_id, node, dep);
     19816}
     19817psArray *magicTreeSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     19818{
     19819    psArray         *rowSet;
     19820    psArray         *returnSet;
     19821    psU64           i;
     19822
     19823    rowSet = psDBSelectRows(dbh, MAGICTREE_TABLE_NAME, where, limit);
     19824    if (!rowSet) {
     19825        return NULL;
     19826    }
     19827
     19828    // convert psMetadata rows to row objects
     19829
     19830    returnSet = psArrayAllocEmpty(rowSet->n);
     19831
     19832    for (i = 0; i < rowSet->n; i++) {
     19833        magicTreeRow *object = magicTreeObjectFromMetadata(rowSet->data[i]);
     19834        psArrayAdd(returnSet, 0, object);
     19835        psFree(object);
     19836    }
     19837
     19838    psFree(rowSet);
     19839
     19840    return returnSet;
     19841}
     19842bool magicTreeDeleteObject(psDB *dbh, const magicTreeRow *object)
     19843{
     19844    psMetadata *where = magicTreeMetadataFromObject(object);
     19845    long long count = psDBDeleteRows(dbh, MAGICTREE_TABLE_NAME, where, 0);
     19846    psFree(where);
     19847    if (count < 0) {
     19848        psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicTree");
     19849        return false;
     19850    }
     19851    if (count > 1) {
     19852        // XXX should this be a psAbort() instead?  It is possible that
     19853        // having an object match multiple rows was by design.
     19854        psError(PS_ERR_UNKNOWN, true, "magicTreeRow object matched more then one row.  Check your database schema");
     19855        return false;
     19856    }
     19857
     19858    return true;
     19859}
     19860long long magicTreeDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
     19861{
     19862    long long       deleted = 0;
     19863
     19864    for (long long i = 0; i < objects->n; i++) {
     19865        magicTreeRow *object = objects->data[i];
     19866        psMetadata *where = magicTreeMetadataFromObject(object);
     19867        long long count = psDBDeleteRows(dbh, MAGICTREE_TABLE_NAME, where, limit);
     19868        psFree(where);
     19869        if (count < 0) {
     19870            psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicTree");
     19871            return count;
     19872        }
     19873
     19874        deleted += count;
     19875    }
     19876
     19877    return deleted;
     19878}
     19879bool magicTreePrintObjects(FILE *stream, psArray *objects, bool mdcf)
     19880{
     19881    PS_ASSERT_PTR_NON_NULL(objects, false);
     19882
     19883    psMetadata *output = psMetadataAlloc();
     19884    for (long i = 0; i < psArrayLength(objects); i++) {
     19885        psMetadata *md = magicTreeMetadataFromObject(objects->data[i]);
     19886        if (!psMetadataAddMetadata(
     19887            output,
     19888            PS_LIST_TAIL,
     19889            MAGICTREE_TABLE_NAME,
     19890            PS_META_DUPLICATE_OK,
     19891            NULL,
     19892            md
     19893        )) {
     19894            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
     19895            psFree(md);
     19896            psFree(output);
     19897            return false;
     19898        }
     19899        psFree(md);
     19900    }
     19901
     19902    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
     19903        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     19904        psFree(output);
     19905    }
     19906    psFree(output);
     19907
     19908    return true;
     19909}
     19910bool magicTreePrintObject(FILE *stream, magicTreeRow *object, bool mdcf)
     19911{
     19912    PS_ASSERT_PTR_NON_NULL(object, false);
     19913
     19914    psMetadata *md = magicTreeMetadataFromObject(object);
     19915
     19916    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
     19917        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     19918        psFree(md);
     19919    }
     19920
     19921    psFree(md);
     19922
     19923    return true;
     19924}
     19925static void magicNodeResultRowFree(magicNodeResultRow *object);
     19926
     19927magicNodeResultRow *magicNodeResultRowAlloc(psS64 magic_id, const char *node, const char *uri)
     19928{
     19929    magicNodeResultRow *_object;
     19930
     19931    _object = psAlloc(sizeof(magicNodeResultRow));
     19932    psMemSetDeallocator(_object, (psFreeFunc)magicNodeResultRowFree);
     19933
     19934    _object->magic_id = magic_id;
     19935    _object->node = psStringCopy(node);
     19936    _object->uri = psStringCopy(uri);
     19937
     19938    return _object;
     19939}
     19940
     19941static void magicNodeResultRowFree(magicNodeResultRow *object)
     19942{
     19943    psFree(object->node);
     19944    psFree(object->uri);
     19945}
     19946
     19947bool magicNodeResultCreateTable(psDB *dbh)
     19948{
     19949    psMetadata *md = psMetadataAlloc();
     19950    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, "Primary Key fkey(magic_id) ref magicRun(magic_id)", 0)) {
     19951        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     19952        psFree(md);
     19953        return false;
     19954    }
     19955    if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, "Primary Key fkey(magic_id, node) ref magicInputSkyfile(magic_id, node)", "64")) {
     19956        psError(PS_ERR_UNKNOWN, false, "failed to add item node");
     19957        psFree(md);
     19958        return false;
     19959    }
     19960    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
     19961        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     19962        psFree(md);
     19963        return false;
     19964    }
     19965
     19966    bool status = psDBCreateTable(dbh, MAGICNODERESULT_TABLE_NAME, md);
     19967
     19968    psFree(md);
     19969
     19970    return status;
     19971}
     19972
     19973bool magicNodeResultDropTable(psDB *dbh)
     19974{
     19975    return psDBDropTable(dbh, MAGICNODERESULT_TABLE_NAME);
     19976}
     19977
     19978bool magicNodeResultInsert(psDB * dbh, psS64 magic_id, const char *node, const char *uri)
     19979{
     19980    psMetadata *md = psMetadataAlloc();
     19981    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, magic_id)) {
     19982        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     19983        psFree(md);
     19984        return false;
     19985    }
     19986    if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, NULL, node)) {
     19987        psError(PS_ERR_UNKNOWN, false, "failed to add item node");
     19988        psFree(md);
     19989        return false;
     19990    }
     19991    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
     19992        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     19993        psFree(md);
     19994        return false;
     19995    }
     19996
     19997    bool status = psDBInsertOneRow(dbh, MAGICNODERESULT_TABLE_NAME, md);
     19998    psFree(md);
     19999
     20000    return status;
     20001}
     20002
     20003long long magicNodeResultDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
     20004{
     20005    long long       deleted = 0;
     20006
     20007    long long count = psDBDeleteRows(dbh, MAGICNODERESULT_TABLE_NAME, where, limit);
     20008    if (count < 0) {
     20009        psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicNodeResult");
     20010        return count;
     20011
     20012        deleted += count;
     20013    }
     20014
     20015    return deleted;
     20016}
     20017bool magicNodeResultInsertObject(psDB *dbh, magicNodeResultRow *object)
     20018{
     20019    return magicNodeResultInsert(dbh, object->magic_id, object->node, object->uri);
     20020}
     20021
     20022bool magicNodeResultInsertObjects(psDB *dbh, psArray *objects)
     20023{
     20024    for (long i = 0; i < psArrayLength(objects); i++) {
     20025        if (!magicNodeResultInsertObject(dbh, objects->data[i])) {
     20026            return false;
     20027        }
     20028    }
     20029
     20030    return true;
     20031}
     20032
     20033bool magicNodeResultInsertFits(psDB *dbh, const psFits *fits)
     20034{
     20035    psArray         *rowSet;
     20036
     20037    // move to (the first?) extension named  MAGICNODERESULT_TABLE_NAME
     20038    if (!psFitsMoveExtName(fits, MAGICNODERESULT_TABLE_NAME)) {
     20039        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", MAGICNODERESULT_TABLE_NAME);
     20040        return false;
     20041    }
     20042
     20043    // check HDU type
     20044    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
     20045        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
     20046        return false;
     20047    }
     20048
     20049    // read fits table
     20050    rowSet = psFitsReadTable(fits);
     20051    if (!rowSet) {
     20052        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
     20053        psFree(rowSet);
     20054        return false;
     20055    }
     20056
     20057    if (!psDBInsertRows(dbh, MAGICNODERESULT_TABLE_NAME, rowSet)) {
     20058        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
     20059        psFree(rowSet);
     20060        return false;
     20061    }
     20062
     20063    psFree(rowSet);
     20064
     20065    return true;
     20066}
     20067
     20068bool magicNodeResultSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
     20069{
     20070    psArray         *rowSet;
     20071
     20072    rowSet = psDBSelectRows(dbh, MAGICNODERESULT_TABLE_NAME, where, limit);
     20073    if (!rowSet) {
     20074        return false;
     20075    }
     20076
     20077    // output to fits
     20078    if (!psFitsWriteTable(fits, NULL, rowSet, MAGICNODERESULT_TABLE_NAME)) {
     20079        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
     20080        psFree(rowSet);
     20081        return false;
     20082    }
     20083
     20084    psFree(rowSet);
     20085
     20086    return true;
     20087}
     20088
     20089psMetadata *magicNodeResultMetadataFromObject(const magicNodeResultRow *object)
     20090{
     20091    psMetadata *md = psMetadataAlloc();
     20092    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, object->magic_id)) {
     20093        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     20094        psFree(md);
     20095        return false;
     20096    }
     20097    if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, NULL, object->node)) {
     20098        psError(PS_ERR_UNKNOWN, false, "failed to add item node");
     20099        psFree(md);
     20100        return false;
     20101    }
     20102    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
     20103        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     20104        psFree(md);
     20105        return false;
     20106    }
     20107
     20108
     20109    return md;
     20110}
     20111
     20112magicNodeResultRow *magicNodeResultObjectFromMetadata(psMetadata *md)
     20113{
     20114
     20115bool status = false;
     20116    psS64 magic_id = psMetadataLookupS64(&status, md, "magic_id");
     20117    if (!status) {
     20118        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic_id");
     20119        return false;
     20120    }
     20121    char* node = psMetadataLookupPtr(&status, md, "node");
     20122    if (!status) {
     20123        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item node");
     20124        return false;
     20125    }
     20126    char* uri = psMetadataLookupPtr(&status, md, "uri");
     20127    if (!status) {
     20128        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
     20129        return false;
     20130    }
     20131
     20132    return magicNodeResultRowAlloc(magic_id, node, uri);
     20133}
     20134psArray *magicNodeResultSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     20135{
     20136    psArray         *rowSet;
     20137    psArray         *returnSet;
     20138    psU64           i;
     20139
     20140    rowSet = psDBSelectRows(dbh, MAGICNODERESULT_TABLE_NAME, where, limit);
     20141    if (!rowSet) {
     20142        return NULL;
     20143    }
     20144
     20145    // convert psMetadata rows to row objects
     20146
     20147    returnSet = psArrayAllocEmpty(rowSet->n);
     20148
     20149    for (i = 0; i < rowSet->n; i++) {
     20150        magicNodeResultRow *object = magicNodeResultObjectFromMetadata(rowSet->data[i]);
     20151        psArrayAdd(returnSet, 0, object);
     20152        psFree(object);
     20153    }
     20154
     20155    psFree(rowSet);
     20156
     20157    return returnSet;
     20158}
     20159bool magicNodeResultDeleteObject(psDB *dbh, const magicNodeResultRow *object)
     20160{
     20161    psMetadata *where = magicNodeResultMetadataFromObject(object);
     20162    long long count = psDBDeleteRows(dbh, MAGICNODERESULT_TABLE_NAME, where, 0);
     20163    psFree(where);
     20164    if (count < 0) {
     20165        psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicNodeResult");
     20166        return false;
     20167    }
     20168    if (count > 1) {
     20169        // XXX should this be a psAbort() instead?  It is possible that
     20170        // having an object match multiple rows was by design.
     20171        psError(PS_ERR_UNKNOWN, true, "magicNodeResultRow object matched more then one row.  Check your database schema");
     20172        return false;
     20173    }
     20174
     20175    return true;
     20176}
     20177long long magicNodeResultDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
     20178{
     20179    long long       deleted = 0;
     20180
     20181    for (long long i = 0; i < objects->n; i++) {
     20182        magicNodeResultRow *object = objects->data[i];
     20183        psMetadata *where = magicNodeResultMetadataFromObject(object);
     20184        long long count = psDBDeleteRows(dbh, MAGICNODERESULT_TABLE_NAME, where, limit);
     20185        psFree(where);
     20186        if (count < 0) {
     20187            psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicNodeResult");
     20188            return count;
     20189        }
     20190
     20191        deleted += count;
     20192    }
     20193
     20194    return deleted;
     20195}
     20196bool magicNodeResultPrintObjects(FILE *stream, psArray *objects, bool mdcf)
     20197{
     20198    PS_ASSERT_PTR_NON_NULL(objects, false);
     20199
     20200    psMetadata *output = psMetadataAlloc();
     20201    for (long i = 0; i < psArrayLength(objects); i++) {
     20202        psMetadata *md = magicNodeResultMetadataFromObject(objects->data[i]);
     20203        if (!psMetadataAddMetadata(
     20204            output,
     20205            PS_LIST_TAIL,
     20206            MAGICNODERESULT_TABLE_NAME,
     20207            PS_META_DUPLICATE_OK,
     20208            NULL,
     20209            md
     20210        )) {
     20211            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
     20212            psFree(md);
     20213            psFree(output);
     20214            return false;
     20215        }
     20216        psFree(md);
     20217    }
     20218
     20219    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
     20220        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     20221        psFree(output);
     20222    }
     20223    psFree(output);
     20224
     20225    return true;
     20226}
     20227bool magicNodeResultPrintObject(FILE *stream, magicNodeResultRow *object, bool mdcf)
     20228{
     20229    PS_ASSERT_PTR_NON_NULL(object, false);
     20230
     20231    psMetadata *md = magicNodeResultMetadataFromObject(object);
     20232
     20233    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
     20234        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     20235        psFree(md);
     20236    }
     20237
     20238    psFree(md);
     20239
     20240    return true;
     20241}
     20242static void magicMaskRowFree(magicMaskRow *object);
     20243
     20244magicMaskRow *magicMaskRowAlloc(psS64 magic_id, const char *uri)
     20245{
     20246    magicMaskRow    *_object;
     20247
     20248    _object = psAlloc(sizeof(magicMaskRow));
     20249    psMemSetDeallocator(_object, (psFreeFunc)magicMaskRowFree);
     20250
     20251    _object->magic_id = magic_id;
     20252    _object->uri = psStringCopy(uri);
     20253
     20254    return _object;
     20255}
     20256
     20257static void magicMaskRowFree(magicMaskRow *object)
     20258{
     20259    psFree(object->uri);
     20260}
     20261
     20262bool magicMaskCreateTable(psDB *dbh)
     20263{
     20264    psMetadata *md = psMetadataAlloc();
     20265    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, "Primary Key fkey(magic_id) ref magicRun(magic_id)", 0)) {
     20266        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     20267        psFree(md);
     20268        return false;
     20269    }
     20270    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
     20271        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     20272        psFree(md);
     20273        return false;
     20274    }
     20275
     20276    bool status = psDBCreateTable(dbh, MAGICMASK_TABLE_NAME, md);
     20277
     20278    psFree(md);
     20279
     20280    return status;
     20281}
     20282
     20283bool magicMaskDropTable(psDB *dbh)
     20284{
     20285    return psDBDropTable(dbh, MAGICMASK_TABLE_NAME);
     20286}
     20287
     20288bool magicMaskInsert(psDB * dbh, psS64 magic_id, const char *uri)
     20289{
     20290    psMetadata *md = psMetadataAlloc();
     20291    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, magic_id)) {
     20292        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     20293        psFree(md);
     20294        return false;
     20295    }
     20296    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
     20297        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     20298        psFree(md);
     20299        return false;
     20300    }
     20301
     20302    bool status = psDBInsertOneRow(dbh, MAGICMASK_TABLE_NAME, md);
     20303    psFree(md);
     20304
     20305    return status;
     20306}
     20307
     20308long long magicMaskDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
     20309{
     20310    long long       deleted = 0;
     20311
     20312    long long count = psDBDeleteRows(dbh, MAGICMASK_TABLE_NAME, where, limit);
     20313    if (count < 0) {
     20314        psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicMask");
     20315        return count;
     20316
     20317        deleted += count;
     20318    }
     20319
     20320    return deleted;
     20321}
     20322bool magicMaskInsertObject(psDB *dbh, magicMaskRow *object)
     20323{
     20324    return magicMaskInsert(dbh, object->magic_id, object->uri);
     20325}
     20326
     20327bool magicMaskInsertObjects(psDB *dbh, psArray *objects)
     20328{
     20329    for (long i = 0; i < psArrayLength(objects); i++) {
     20330        if (!magicMaskInsertObject(dbh, objects->data[i])) {
     20331            return false;
     20332        }
     20333    }
     20334
     20335    return true;
     20336}
     20337
     20338bool magicMaskInsertFits(psDB *dbh, const psFits *fits)
     20339{
     20340    psArray         *rowSet;
     20341
     20342    // move to (the first?) extension named  MAGICMASK_TABLE_NAME
     20343    if (!psFitsMoveExtName(fits, MAGICMASK_TABLE_NAME)) {
     20344        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", MAGICMASK_TABLE_NAME);
     20345        return false;
     20346    }
     20347
     20348    // check HDU type
     20349    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
     20350        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
     20351        return false;
     20352    }
     20353
     20354    // read fits table
     20355    rowSet = psFitsReadTable(fits);
     20356    if (!rowSet) {
     20357        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
     20358        psFree(rowSet);
     20359        return false;
     20360    }
     20361
     20362    if (!psDBInsertRows(dbh, MAGICMASK_TABLE_NAME, rowSet)) {
     20363        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
     20364        psFree(rowSet);
     20365        return false;
     20366    }
     20367
     20368    psFree(rowSet);
     20369
     20370    return true;
     20371}
     20372
     20373bool magicMaskSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
     20374{
     20375    psArray         *rowSet;
     20376
     20377    rowSet = psDBSelectRows(dbh, MAGICMASK_TABLE_NAME, where, limit);
     20378    if (!rowSet) {
     20379        return false;
     20380    }
     20381
     20382    // output to fits
     20383    if (!psFitsWriteTable(fits, NULL, rowSet, MAGICMASK_TABLE_NAME)) {
     20384        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
     20385        psFree(rowSet);
     20386        return false;
     20387    }
     20388
     20389    psFree(rowSet);
     20390
     20391    return true;
     20392}
     20393
     20394psMetadata *magicMaskMetadataFromObject(const magicMaskRow *object)
     20395{
     20396    psMetadata *md = psMetadataAlloc();
     20397    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, object->magic_id)) {
     20398        psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
     20399        psFree(md);
     20400        return false;
     20401    }
     20402    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
     20403        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     20404        psFree(md);
     20405        return false;
     20406    }
     20407
     20408
     20409    return md;
     20410}
     20411
     20412magicMaskRow *magicMaskObjectFromMetadata(psMetadata *md)
     20413{
     20414
     20415bool status = false;
     20416    psS64 magic_id = psMetadataLookupS64(&status, md, "magic_id");
     20417    if (!status) {
     20418        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic_id");
     20419        return false;
     20420    }
     20421    char* uri = psMetadataLookupPtr(&status, md, "uri");
     20422    if (!status) {
     20423        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
     20424        return false;
     20425    }
     20426
     20427    return magicMaskRowAlloc(magic_id, uri);
     20428}
     20429psArray *magicMaskSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     20430{
     20431    psArray         *rowSet;
     20432    psArray         *returnSet;
     20433    psU64           i;
     20434
     20435    rowSet = psDBSelectRows(dbh, MAGICMASK_TABLE_NAME, where, limit);
     20436    if (!rowSet) {
     20437        return NULL;
     20438    }
     20439
     20440    // convert psMetadata rows to row objects
     20441
     20442    returnSet = psArrayAllocEmpty(rowSet->n);
     20443
     20444    for (i = 0; i < rowSet->n; i++) {
     20445        magicMaskRow *object = magicMaskObjectFromMetadata(rowSet->data[i]);
     20446        psArrayAdd(returnSet, 0, object);
     20447        psFree(object);
     20448    }
     20449
     20450    psFree(rowSet);
     20451
     20452    return returnSet;
     20453}
     20454bool magicMaskDeleteObject(psDB *dbh, const magicMaskRow *object)
     20455{
     20456    psMetadata *where = magicMaskMetadataFromObject(object);
     20457    long long count = psDBDeleteRows(dbh, MAGICMASK_TABLE_NAME, where, 0);
     20458    psFree(where);
     20459    if (count < 0) {
     20460        psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicMask");
     20461        return false;
     20462    }
     20463    if (count > 1) {
     20464        // XXX should this be a psAbort() instead?  It is possible that
     20465        // having an object match multiple rows was by design.
     20466        psError(PS_ERR_UNKNOWN, true, "magicMaskRow object matched more then one row.  Check your database schema");
     20467        return false;
     20468    }
     20469
     20470    return true;
     20471}
     20472long long magicMaskDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
     20473{
     20474    long long       deleted = 0;
     20475
     20476    for (long long i = 0; i < objects->n; i++) {
     20477        magicMaskRow *object = objects->data[i];
     20478        psMetadata *where = magicMaskMetadataFromObject(object);
     20479        long long count = psDBDeleteRows(dbh, MAGICMASK_TABLE_NAME, where, limit);
     20480        psFree(where);
     20481        if (count < 0) {
     20482            psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicMask");
     20483            return count;
     20484        }
     20485
     20486        deleted += count;
     20487    }
     20488
     20489    return deleted;
     20490}
     20491bool magicMaskPrintObjects(FILE *stream, psArray *objects, bool mdcf)
     20492{
     20493    PS_ASSERT_PTR_NON_NULL(objects, false);
     20494
     20495    psMetadata *output = psMetadataAlloc();
     20496    for (long i = 0; i < psArrayLength(objects); i++) {
     20497        psMetadata *md = magicMaskMetadataFromObject(objects->data[i]);
     20498        if (!psMetadataAddMetadata(
     20499            output,
     20500            PS_LIST_TAIL,
     20501            MAGICMASK_TABLE_NAME,
     20502            PS_META_DUPLICATE_OK,
     20503            NULL,
     20504            md
     20505        )) {
     20506            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
     20507            psFree(md);
     20508            psFree(output);
     20509            return false;
     20510        }
     20511        psFree(md);
     20512    }
     20513
     20514    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
     20515        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     20516        psFree(output);
     20517    }
     20518    psFree(output);
     20519
     20520    return true;
     20521}
     20522bool magicMaskPrintObject(FILE *stream, magicMaskRow *object, bool mdcf)
     20523{
     20524    PS_ASSERT_PTR_NON_NULL(object, false);
     20525
     20526    psMetadata *md = magicMaskMetadataFromObject(object);
     20527
     20528    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
     20529        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     20530        psFree(md);
     20531    }
     20532
     20533    psFree(md);
     20534
     20535    return true;
     20536}
Note: See TracChangeset for help on using the changeset viewer.