IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 30, 2007, 4:42:05 PM (19 years ago)
Author:
jhoblitt
Message:

update

File:
1 edited

Legend:

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

    r15344 r15420  
    2020/*
    2121 *
    22  * This file was generated by glueforge 1.01
     22 * This file was generated by glueforge 1.03
    2323 *
    2424 * Do NOT directly edit this file.
     
    3131#include "ippdb.h"
    3232
    33 #define PZDATASTORE_TABLE_NAME "pzDataStore"
    3433#define SUMMITEXP_TABLE_NAME "summitExp"
    3534#define SUMMITIMFILE_TABLE_NAME "summitImfile"
     
    4443#define GUIDEPENDINGEXP_TABLE_NAME "guidePendingExp"
    4544#define CHIPRUN_TABLE_NAME "chipRun"
     45#define CHIPINPUTIMFILE_TABLE_NAME "chipInputImfile"
    4646#define CHIPPROCESSEDIMFILE_TABLE_NAME "chipProcessedImfile"
    4747#define CHIPMASK_TABLE_NAME "chipMask"
     
    7070#define DETRESIDEXP_TABLE_NAME "detResidExp"
    7171#define DETRUNSUMMARY_TABLE_NAME "detRunSummary"
    72 #define DETREGISTEREDIMFILE_TABLE_NAME "detRegisteredImfile"
    73 #define DETCORRECTEDEXP_TABLE_NAME "detCorrectedExp"
    74 #define DETCORRECTEDIMFILE_TABLE_NAME "detCorrectedImfile"
    75 #define MAGICRUN_TABLE_NAME "magicRun"
    76 #define MAGICINPUTSKYFILE_TABLE_NAME "magicInputSkyfile"
    77 #define MAGICTREE_TABLE_NAME "magicTree"
    78 #define MAGICNODERESULT_TABLE_NAME "magicNodeResult"
    79 #define MAGICMASK_TABLE_NAME "magicMask"
    80 #define MAGICSKYFILEMASK_TABLE_NAME "magicSkyfileMask"
    8172#define MAX_STRING_LENGTH 1024
    8273
     
    255246}
    256247
    257 static void pzDataStoreRowFree(pzDataStoreRow *object);
    258 
    259 pzDataStoreRow *pzDataStoreRowAlloc(const char *camera, const char *telescope, const char *uri)
    260 {
    261     pzDataStoreRow  *_object;
    262 
    263     _object = psAlloc(sizeof(pzDataStoreRow));
    264     psMemSetDeallocator(_object, (psFreeFunc)pzDataStoreRowFree);
    265 
    266     _object->camera = psStringCopy(camera);
    267     _object->telescope = psStringCopy(telescope);
    268     _object->uri = psStringCopy(uri);
    269 
    270     return _object;
    271 }
    272 
    273 static void pzDataStoreRowFree(pzDataStoreRow *object)
    274 {
    275     psFree(object->camera);
    276     psFree(object->telescope);
    277     psFree(object->uri);
    278 }
    279 
    280 bool pzDataStoreCreateTable(psDB *dbh)
    281 {
    282     psMetadata *md = psMetadataAlloc();
    283     if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, "Primary Key", "64")) {
    284         psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
    285         psFree(md);
    286         return false;
    287     }
    288     if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, "Primary Key", "64")) {
    289         psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
    290         psFree(md);
    291         return false;
    292     }
    293     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
    294         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    295         psFree(md);
    296         return false;
    297     }
    298 
    299     bool status = psDBCreateTable(dbh, PZDATASTORE_TABLE_NAME, md);
    300 
    301     psFree(md);
    302 
    303     return status;
    304 }
    305 
    306 bool pzDataStoreDropTable(psDB *dbh)
    307 {
    308     return psDBDropTable(dbh, PZDATASTORE_TABLE_NAME);
    309 }
    310 
    311 bool pzDataStoreInsert(psDB * dbh, const char *camera, const char *telescope, const char *uri)
    312 {
    313     psMetadata *md = psMetadataAlloc();
    314     if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, NULL, camera)) {
    315         psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
    316         psFree(md);
    317         return false;
    318     }
    319     if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, NULL, telescope)) {
    320         psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
    321         psFree(md);
    322         return false;
    323     }
    324     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
    325         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    326         psFree(md);
    327         return false;
    328     }
    329 
    330     bool status = psDBInsertOneRow(dbh, PZDATASTORE_TABLE_NAME, md);
    331     psFree(md);
    332 
    333     return status;
    334 }
    335 
    336 long long pzDataStoreDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    337 {
    338     long long       deleted = 0;
    339 
    340     long long count = psDBDeleteRows(dbh, PZDATASTORE_TABLE_NAME, where, limit);
    341     if (count < 0) {
    342         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDataStore");
    343         return count;
    344 
    345         deleted += count;
    346     }
    347 
    348     return deleted;
    349 }
    350 bool pzDataStoreInsertObject(psDB *dbh, pzDataStoreRow *object)
    351 {
    352     return pzDataStoreInsert(dbh, object->camera, object->telescope, object->uri);
    353 }
    354 
    355 bool pzDataStoreInsertObjects(psDB *dbh, psArray *objects)
    356 {
    357     for (long i = 0; i < psArrayLength(objects); i++) {
    358         if (!pzDataStoreInsertObject(dbh, objects->data[i])) {
    359             return false;
    360         }
    361     }
    362 
    363     return true;
    364 }
    365 
    366 bool pzDataStoreInsertFits(psDB *dbh, const psFits *fits)
    367 {
    368     psArray         *rowSet;
    369 
    370     // move to (the first?) extension named  PZDATASTORE_TABLE_NAME
    371     if (!psFitsMoveExtName(fits, PZDATASTORE_TABLE_NAME)) {
    372         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PZDATASTORE_TABLE_NAME);
    373         return false;
    374     }
    375 
    376     // check HDU type
    377     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    378         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    379         return false;
    380     }
    381 
    382     // read fits table
    383     rowSet = psFitsReadTable(fits);
    384     if (!rowSet) {
    385         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    386         psFree(rowSet);
    387         return false;
    388     }
    389 
    390     if (!psDBInsertRows(dbh, PZDATASTORE_TABLE_NAME, rowSet)) {
    391         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    392         psFree(rowSet);
    393         return false;
    394     }
    395 
    396     psFree(rowSet);
    397 
    398     return true;
    399 }
    400 
    401 bool pzDataStoreSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    402 {
    403     psArray         *rowSet;
    404 
    405     rowSet = psDBSelectRows(dbh, PZDATASTORE_TABLE_NAME, where, limit);
    406     if (!rowSet) {
    407         return false;
    408     }
    409 
    410     // output to fits
    411     if (!psFitsWriteTable(fits, NULL, rowSet, PZDATASTORE_TABLE_NAME)) {
    412         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    413         psFree(rowSet);
    414         return false;
    415     }
    416 
    417     psFree(rowSet);
    418 
    419     return true;
    420 }
    421 
    422 psMetadata *pzDataStoreMetadataFromObject(const pzDataStoreRow *object)
    423 {
    424     psMetadata *md = psMetadataAlloc();
    425     if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, NULL, object->camera)) {
    426         psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
    427         psFree(md);
    428         return false;
    429     }
    430     if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, NULL, object->telescope)) {
    431         psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
    432         psFree(md);
    433         return false;
    434     }
    435     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
    436         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    437         psFree(md);
    438         return false;
    439     }
    440 
    441 
    442     return md;
    443 }
    444 
    445 pzDataStoreRow *pzDataStoreObjectFromMetadata(psMetadata *md)
    446 {
    447 
    448 bool status = false;
    449     char* camera = psMetadataLookupPtr(&status, md, "camera");
    450     if (!status) {
    451         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item camera");
    452         return false;
    453     }
    454     char* telescope = psMetadataLookupPtr(&status, md, "telescope");
    455     if (!status) {
    456         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item telescope");
    457         return false;
    458     }
    459     char* uri = psMetadataLookupPtr(&status, md, "uri");
    460     if (!status) {
    461         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
    462         return false;
    463     }
    464 
    465     return pzDataStoreRowAlloc(camera, telescope, uri);
    466 }
    467 psArray *pzDataStoreSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    468 {
    469     psArray         *rowSet;
    470     psArray         *returnSet;
    471     psU64           i;
    472 
    473     rowSet = psDBSelectRows(dbh, PZDATASTORE_TABLE_NAME, where, limit);
    474     if (!rowSet) {
    475         return NULL;
    476     }
    477 
    478     // convert psMetadata rows to row objects
    479 
    480     returnSet = psArrayAllocEmpty(rowSet->n);
    481 
    482     for (i = 0; i < rowSet->n; i++) {
    483         pzDataStoreRow *object = pzDataStoreObjectFromMetadata(rowSet->data[i]);
    484         psArrayAdd(returnSet, 0, object);
    485         psFree(object);
    486     }
    487 
    488     psFree(rowSet);
    489 
    490     return returnSet;
    491 }
    492 bool pzDataStoreDeleteObject(psDB *dbh, const pzDataStoreRow *object)
    493 {
    494     psMetadata *where = pzDataStoreMetadataFromObject(object);
    495     long long count = psDBDeleteRows(dbh, PZDATASTORE_TABLE_NAME, where, 0);
    496     psFree(where);
    497     if (count < 0) {
    498         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDataStore");
    499         return false;
    500     }
    501     if (count > 1) {
    502         // XXX should this be a psAbort() instead?  It is possible that
    503         // having an object match multiple rows was by design.
    504         psError(PS_ERR_UNKNOWN, true, "pzDataStoreRow object matched more then one row.  Check your database schema");
    505         return false;
    506     }
    507 
    508     return true;
    509 }
    510 long long pzDataStoreDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    511 {
    512     long long       deleted = 0;
    513 
    514     for (long long i = 0; i < objects->n; i++) {
    515         pzDataStoreRow *object = objects->data[i];
    516         psMetadata *where = pzDataStoreMetadataFromObject(object);
    517         long long count = psDBDeleteRows(dbh, PZDATASTORE_TABLE_NAME, where, limit);
    518         psFree(where);
    519         if (count < 0) {
    520             psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDataStore");
    521             return count;
    522         }
    523 
    524         deleted += count;
    525     }
    526 
    527     return deleted;
    528 }
    529 bool pzDataStorePrintObjects(FILE *stream, psArray *objects, bool mdcf)
    530 {
    531     PS_ASSERT_PTR_NON_NULL(objects, false);
    532 
    533     psMetadata *output = psMetadataAlloc();
    534     for (long i = 0; i < psArrayLength(objects); i++) {
    535         psMetadata *md = pzDataStoreMetadataFromObject(objects->data[i]);
    536         if (!psMetadataAddMetadata(
    537             output,
    538             PS_LIST_TAIL,
    539             PZDATASTORE_TABLE_NAME,
    540             PS_META_DUPLICATE_OK,
    541             NULL,
    542             md
    543         )) {
    544             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    545             psFree(md);
    546             psFree(output);
    547             return false;
    548         }
    549         psFree(md);
    550     }
    551 
    552     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    553         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    554         psFree(output);
    555     }
    556     psFree(output);
    557 
    558     return true;
    559 }
    560 bool pzDataStorePrintObject(FILE *stream, pzDataStoreRow *object, bool mdcf)
    561 {
    562     PS_ASSERT_PTR_NON_NULL(object, false);
    563 
    564     psMetadata *md = pzDataStoreMetadataFromObject(object);
    565 
    566     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    567         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    568         psFree(md);
    569     }
    570 
    571     psFree(md);
    572 
    573     return true;
    574 }
    575248static void summitExpRowFree(summitExpRow *object);
    576249
     
    17471420static void pzPendingImfileRowFree(pzPendingImfileRow *object);
    17481421
    1749 pzPendingImfileRow *pzPendingImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id)
     1422pzPendingImfileRow *pzPendingImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, psS64 exp_id)
    17501423{
    17511424    pzPendingImfileRow *_object;
     
    17591432    _object->class = psStringCopy(class);
    17601433    _object->class_id = psStringCopy(class_id);
     1434    _object->exp_id = exp_id;
    17611435
    17621436    return _object;
     
    18001474        return false;
    18011475    }
     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    }
    18021481
    18031482    bool status = psDBCreateTable(dbh, PZPENDINGIMFILE_TABLE_NAME, md);
     
    18131492}
    18141493
    1815 bool pzPendingImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id)
     1494bool pzPendingImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, psS64 exp_id)
    18161495{
    18171496    psMetadata *md = psMetadataAlloc();
     
    18381517    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
    18391518        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");
    18401524        psFree(md);
    18411525        return false;
     
    18641548bool pzPendingImfileInsertObject(psDB *dbh, pzPendingImfileRow *object)
    18651549{
    1866     return pzPendingImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id);
     1550    return pzPendingImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id, object->exp_id);
    18671551}
    18681552
     
    19621646        return false;
    19631647    }
     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    }
    19641653
    19651654
     
    19961685        return false;
    19971686    }
    1998 
    1999     return pzPendingImfileRowAlloc(exp_name, camera, telescope, class, class_id);
     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);
    20001694}
    20011695psArray *pzPendingImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    24272121static void pzDoneImfileRowFree(pzDoneImfileRow *object);
    24282122
    2429 pzDoneImfileRow *pzDoneImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, const char *uri)
     2123pzDoneImfileRow *pzDoneImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, psS64 exp_id, const char *uri)
    24302124{
    24312125    pzDoneImfileRow *_object;
     
    24392133    _object->class = psStringCopy(class);
    24402134    _object->class_id = psStringCopy(class_id);
     2135    _object->exp_id = exp_id;
    24412136    _object->uri = psStringCopy(uri);
    24422137
     
    24822177        return false;
    24832178    }
     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    }
    24842184    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
    24852185        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     
    25002200}
    25012201
    2502 bool pzDoneImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, const char *uri)
     2202bool 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)
    25032203{
    25042204    psMetadata *md = psMetadataAlloc();
     
    25252225    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
    25262226        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");
    25272232        psFree(md);
    25282233        return false;
     
    25562261bool pzDoneImfileInsertObject(psDB *dbh, pzDoneImfileRow *object)
    25572262{
    2558     return pzDoneImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id, object->uri);
     2263    return pzDoneImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id, object->exp_id, object->uri);
    25592264}
    25602265
     
    26542359        return false;
    26552360    }
     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    }
    26562366    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
    26572367        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     
    26932403        return false;
    26942404    }
     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    }
    26952410    char* uri = psMetadataLookupPtr(&status, md, "uri");
    26962411    if (!status) {
     
    26992414    }
    27002415
    2701     return pzDoneImfileRowAlloc(exp_name, camera, telescope, class, class_id, uri);
     2416    return pzDoneImfileRowAlloc(exp_name, camera, telescope, class, class_id, exp_id, uri);
    27022417}
    27032418psArray *pzDoneImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    28112526static void newExpRowFree(newExpRow *object);
    28122527
    2813 newExpRow *newExpRowAlloc(psS64 exp_id, const char *tmp_exp_name, const char *tmp_camera, const char *tmp_telescope, const char *state, const char *workdir, const char *workdir_state, const char *reduction)
     2528newExpRow *newExpRowAlloc(psS64 exp_id, const char *tmp_exp_name, const char *tmp_camera, const char *tmp_telescope, const char *state, psS32 imfiles, const char *workdir, const char *workdir_state)
    28142529{
    28152530    newExpRow       *_object;
     
    28232538    _object->tmp_telescope = psStringCopy(tmp_telescope);
    28242539    _object->state = psStringCopy(state);
     2540    _object->imfiles = imfiles;
    28252541    _object->workdir = psStringCopy(workdir);
    28262542    _object->workdir_state = psStringCopy(workdir_state);
    2827     _object->reduction = psStringCopy(reduction);
    28282543
    28292544    return _object;
     
    28382553    psFree(object->workdir);
    28392554    psFree(object->workdir_state);
    2840     psFree(object->reduction);
    28412555}
    28422556
     
    28692583        return false;
    28702584    }
     2585    if (!psMetadataAdd(md, PS_LIST_TAIL, "imfiles", PS_DATA_S32, NULL, 0)) {
     2586        psError(PS_ERR_UNKNOWN, false, "failed to add item imfiles");
     2587        psFree(md);
     2588        return false;
     2589    }
    28712590    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, "destination for output files", "255")) {
    28722591        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
     
    28792598        return false;
    28802599    }
    2881     if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, "Reduction class", "64")) {
    2882         psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
    2883         psFree(md);
    2884         return false;
    2885     }
    28862600
    28872601    bool status = psDBCreateTable(dbh, NEWEXP_TABLE_NAME, md);
     
    28972611}
    28982612
    2899 bool newExpInsert(psDB * dbh, psS64 exp_id, const char *tmp_exp_name, const char *tmp_camera, const char *tmp_telescope, const char *state, const char *workdir, const char *workdir_state, const char *reduction)
     2613bool newExpInsert(psDB * dbh, psS64 exp_id, const char *tmp_exp_name, const char *tmp_camera, const char *tmp_telescope, const char *state, psS32 imfiles, const char *workdir, const char *workdir_state)
    29002614{
    29012615    psMetadata *md = psMetadataAlloc();
     
    29252639        return false;
    29262640    }
     2641    if (!psMetadataAdd(md, PS_LIST_TAIL, "imfiles", PS_DATA_S32, NULL, imfiles)) {
     2642        psError(PS_ERR_UNKNOWN, false, "failed to add item imfiles");
     2643        psFree(md);
     2644        return false;
     2645    }
    29272646    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, workdir)) {
    29282647        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
     
    29322651    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, NULL, workdir_state)) {
    29332652        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
    2934         psFree(md);
    2935         return false;
    2936     }
    2937     if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, reduction)) {
    2938         psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
    29392653        psFree(md);
    29402654        return false;
     
    29632677bool newExpInsertObject(psDB *dbh, newExpRow *object)
    29642678{
    2965     return newExpInsert(dbh, object->exp_id, object->tmp_exp_name, object->tmp_camera, object->tmp_telescope, object->state, object->workdir, object->workdir_state, object->reduction);
     2679    return newExpInsert(dbh, object->exp_id, object->tmp_exp_name, object->tmp_camera, object->tmp_telescope, object->state, object->imfiles, object->workdir, object->workdir_state);
    29662680}
    29672681
     
    30612775        return false;
    30622776    }
     2777    if (!psMetadataAdd(md, PS_LIST_TAIL, "imfiles", PS_DATA_S32, NULL, object->imfiles)) {
     2778        psError(PS_ERR_UNKNOWN, false, "failed to add item imfiles");
     2779        psFree(md);
     2780        return false;
     2781    }
    30632782    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, object->workdir)) {
    30642783        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
     
    30712790        return false;
    30722791    }
    3073     if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, object->reduction)) {
    3074         psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
    3075         psFree(md);
    3076         return false;
    3077     }
    30782792
    30792793
     
    31102824        return false;
    31112825    }
     2826    psS32 imfiles = psMetadataLookupS32(&status, md, "imfiles");
     2827    if (!status) {
     2828        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item imfiles");
     2829        return false;
     2830    }
    31122831    char* workdir = psMetadataLookupPtr(&status, md, "workdir");
    31132832    if (!status) {
     
    31202839        return false;
    31212840    }
    3122     char* reduction = psMetadataLookupPtr(&status, md, "reduction");
    3123     if (!status) {
    3124         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item reduction");
    3125         return false;
    3126     }
    3127 
    3128     return newExpRowAlloc(exp_id, tmp_exp_name, tmp_camera, tmp_telescope, state, workdir, workdir_state, reduction);
     2841
     2842    return newExpRowAlloc(exp_id, tmp_exp_name, tmp_camera, tmp_telescope, state, imfiles, workdir, workdir_state);
    31292843}
    31302844psArray *newExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    35553269static void rawExpRowFree(rawExpRow *object);
    35563270
    3557 rawExpRow *rawExpRowAlloc(psS64 exp_id, const char *exp_name, const char *camera, const char *telescope, psTime* dateobs, const char *exp_tag, const char *exp_type, const char *filelevel, const char *workdir, const char *reduction, const char *filter, psF32 airmass, psF64 ra, psF64 decl, psF32 exp_time, psF32 sat_pixel_frac, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 alt, psF64 az, psF32 ccd_temp, psF64 posang, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *object, psF32 solang, psS16 fault)
     3271rawExpRow *rawExpRowAlloc(psS64 exp_id, const char *exp_name, const char *camera, const char *telescope, psTime* dateobs, const char *exp_tag, const char *exp_type, psS32 imfiles, const char *filelevel, const char *workdir, const char *filter, psF32 airmass, psF64 ra, psF64 decl, psF32 exp_time, psF32 sat_pixel_frac, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 alt, psF64 az, psF32 ccd_temp, psF64 posang, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *object, psF32 solang, psS16 fault)
    35583272{
    35593273    rawExpRow       *_object;
     
    35693283    _object->exp_tag = psStringCopy(exp_tag);
    35703284    _object->exp_type = psStringCopy(exp_type);
     3285    _object->imfiles = imfiles;
    35713286    _object->filelevel = psStringCopy(filelevel);
    35723287    _object->workdir = psStringCopy(workdir);
    3573     _object->reduction = psStringCopy(reduction);
    35743288    _object->filter = psStringCopy(filter);
    35753289    _object->airmass = airmass;
     
    36073321    psFree(object->filelevel);
    36083322    psFree(object->workdir);
    3609     psFree(object->reduction);
    36103323    psFree(object->filter);
    36113324    psFree(object->object);
     
    36503363        return false;
    36513364    }
     3365    if (!psMetadataAdd(md, PS_LIST_TAIL, "imfiles", PS_DATA_S32, NULL, 0)) {
     3366        psError(PS_ERR_UNKNOWN, false, "failed to add item imfiles");
     3367        psFree(md);
     3368        return false;
     3369    }
    36523370    if (!psMetadataAdd(md, PS_LIST_TAIL, "filelevel", PS_DATA_STRING, NULL, "64")) {
    36533371        psError(PS_ERR_UNKNOWN, false, "failed to add item filelevel");
     
    36603378        return false;
    36613379    }
    3662     if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, "Reduction class", "64")) {
    3663         psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
    3664         psFree(md);
    3665         return false;
    3666     }
    36673380    if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, "64")) {
    36683381        psError(PS_ERR_UNKNOWN, false, "failed to add item filter");
     
    37833496}
    37843497
    3785 bool rawExpInsert(psDB * dbh, psS64 exp_id, const char *exp_name, const char *camera, const char *telescope, psTime* dateobs, const char *exp_tag, const char *exp_type, const char *filelevel, const char *workdir, const char *reduction, const char *filter, psF32 airmass, psF64 ra, psF64 decl, psF32 exp_time, psF32 sat_pixel_frac, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 alt, psF64 az, psF32 ccd_temp, psF64 posang, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *object, psF32 solang, psS16 fault)
     3498bool rawExpInsert(psDB * dbh, psS64 exp_id, const char *exp_name, const char *camera, const char *telescope, psTime* dateobs, const char *exp_tag, const char *exp_type, psS32 imfiles, const char *filelevel, const char *workdir, const char *filter, psF32 airmass, psF64 ra, psF64 decl, psF32 exp_time, psF32 sat_pixel_frac, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 alt, psF64 az, psF32 ccd_temp, psF64 posang, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *object, psF32 solang, psS16 fault)
    37863499{
    37873500    psMetadata *md = psMetadataAlloc();
     
    38213534        return false;
    38223535    }
     3536    if (!psMetadataAdd(md, PS_LIST_TAIL, "imfiles", PS_DATA_S32, NULL, imfiles)) {
     3537        psError(PS_ERR_UNKNOWN, false, "failed to add item imfiles");
     3538        psFree(md);
     3539        return false;
     3540    }
    38233541    if (!psMetadataAdd(md, PS_LIST_TAIL, "filelevel", PS_DATA_STRING, NULL, filelevel)) {
    38243542        psError(PS_ERR_UNKNOWN, false, "failed to add item filelevel");
     
    38283546    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, workdir)) {
    38293547        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
    3830         psFree(md);
    3831         return false;
    3832     }
    3833     if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, reduction)) {
    3834         psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
    38353548        psFree(md);
    38363549        return false;
     
    39643677bool rawExpInsertObject(psDB *dbh, rawExpRow *object)
    39653678{
    3966     return rawExpInsert(dbh, object->exp_id, object->exp_name, object->camera, object->telescope, object->dateobs, object->exp_tag, object->exp_type, object->filelevel, object->workdir, object->reduction, object->filter, object->airmass, object->ra, object->decl, object->exp_time, object->sat_pixel_frac, object->bg, object->bg_stdev, object->bg_mean_stdev, object->alt, object->az, object->ccd_temp, object->posang, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->object, object->solang, object->fault);
     3679    return rawExpInsert(dbh, object->exp_id, object->exp_name, object->camera, object->telescope, object->dateobs, object->exp_tag, object->exp_type, object->imfiles, object->filelevel, object->workdir, object->filter, object->airmass, object->ra, object->decl, object->exp_time, object->sat_pixel_frac, object->bg, object->bg_stdev, object->bg_mean_stdev, object->alt, object->az, object->ccd_temp, object->posang, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->object, object->solang, object->fault);
    39673680}
    39683681
     
    40723785        return false;
    40733786    }
     3787    if (!psMetadataAdd(md, PS_LIST_TAIL, "imfiles", PS_DATA_S32, NULL, object->imfiles)) {
     3788        psError(PS_ERR_UNKNOWN, false, "failed to add item imfiles");
     3789        psFree(md);
     3790        return false;
     3791    }
    40743792    if (!psMetadataAdd(md, PS_LIST_TAIL, "filelevel", PS_DATA_STRING, NULL, object->filelevel)) {
    40753793        psError(PS_ERR_UNKNOWN, false, "failed to add item filelevel");
     
    40823800        return false;
    40833801    }
    4084     if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, object->reduction)) {
    4085         psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
    4086         psFree(md);
    4087         return false;
    4088     }
    40893802    if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, object->filter)) {
    40903803        psError(PS_ERR_UNKNOWN, false, "failed to add item filter");
     
    42363949        return false;
    42373950    }
     3951    psS32 imfiles = psMetadataLookupS32(&status, md, "imfiles");
     3952    if (!status) {
     3953        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item imfiles");
     3954        return false;
     3955    }
    42383956    char* filelevel = psMetadataLookupPtr(&status, md, "filelevel");
    42393957    if (!status) {
     
    42463964        return false;
    42473965    }
    4248     char* reduction = psMetadataLookupPtr(&status, md, "reduction");
    4249     if (!status) {
    4250         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item reduction");
    4251         return false;
    4252     }
    42533966    char* filter = psMetadataLookupPtr(&status, md, "filter");
    42543967    if (!status) {
     
    43574070    }
    43584071
    4359     return rawExpRowAlloc(exp_id, exp_name, camera, telescope, dateobs, exp_tag, exp_type, filelevel, workdir, reduction, filter, airmass, ra, decl, exp_time, sat_pixel_frac, bg, bg_stdev, bg_mean_stdev, alt, az, ccd_temp, posang, user_1, user_2, user_3, user_4, user_5, object, solang, fault);
     4072    return rawExpRowAlloc(exp_id, exp_name, camera, telescope, dateobs, exp_tag, exp_type, imfiles, filelevel, workdir, filter, airmass, ra, decl, exp_time, sat_pixel_frac, bg, bg_stdev, bg_mean_stdev, alt, az, ccd_temp, posang, user_1, user_2, user_3, user_4, user_5, object, solang, fault);
    43604073}
    43614074psArray *rawExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    56785391static void chipRunRowFree(chipRunRow *object);
    56795392
    5680 chipRunRow *chipRunRowAlloc(psS64 chip_id, psS64 exp_id, const char *state, const char *workdir, const char *workdir_state, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
     5393chipRunRow *chipRunRowAlloc(psS64 chip_id, const char *state, const char *workdir, const char *workdir_state, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
    56815394{
    56825395    chipRunRow      *_object;
     
    56865399
    56875400    _object->chip_id = chip_id;
    5688     _object->exp_id = exp_id;
    56895401    _object->state = psStringCopy(state);
    56905402    _object->workdir = psStringCopy(workdir);
     
    57175429        return false;
    57185430    }
    5719     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Key INDEX(chip_id, exp_id) fkey (exp_id) ref rawExp(exp_id)", 64)) {
    5720         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    5721         psFree(md);
    5722         return false;
    5723     }
    5724     if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, "Key", "64")) {
     5431    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, "key", "64")) {
    57255432        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
    57265433        psFree(md);
     
    57325439        return false;
    57335440    }
    5734     if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, "Key", "64")) {
     5441    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, "key", "64")) {
    57355442        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
    57365443        psFree(md);
    57375444        return false;
    57385445    }
    5739     if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, "Key", "64")) {
     5446    if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, "key", "64")) {
    57405447        psError(PS_ERR_UNKNOWN, false, "failed to add item label");
    57415448        psFree(md);
     
    57475454        return false;
    57485455    }
    5749     if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, "Key", "64")) {
     5456    if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, "key", "64")) {
    57505457        psError(PS_ERR_UNKNOWN, false, "failed to add item expgroup");
    57515458        psFree(md);
     
    57705477}
    57715478
    5772 bool chipRunInsert(psDB * dbh, psS64 chip_id, psS64 exp_id, const char *state, const char *workdir, const char *workdir_state, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
     5479bool chipRunInsert(psDB * dbh, psS64 chip_id, const char *state, const char *workdir, const char *workdir_state, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
    57735480{
    57745481    psMetadata *md = psMetadataAlloc();
    57755482    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, NULL, chip_id)) {
    57765483        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
    5777         psFree(md);
    5778         return false;
    5779     }
    5780     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
    5781         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    57825484        psFree(md);
    57835485        return false;
     
    58415543bool chipRunInsertObject(psDB *dbh, chipRunRow *object)
    58425544{
    5843     return chipRunInsert(dbh, object->chip_id, object->exp_id, object->state, object->workdir, object->workdir_state, object->label, object->reduction, object->expgroup, object->dvodb);
     5545    return chipRunInsert(dbh, object->chip_id, object->state, object->workdir, object->workdir_state, object->label, object->reduction, object->expgroup, object->dvodb);
    58445546}
    58455547
     
    59195621        return false;
    59205622    }
    5921     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
    5922         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    5923         psFree(md);
    5924         return false;
    5925     }
    59265623    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
    59275624        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     
    59735670        return false;
    59745671    }
    5975     psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
    5976     if (!status) {
    5977         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
    5978         return false;
    5979     }
    59805672    char* state = psMetadataLookupPtr(&status, md, "state");
    59815673    if (!status) {
     
    60145706    }
    60155707
    6016     return chipRunRowAlloc(chip_id, exp_id, state, workdir, workdir_state, label, reduction, expgroup, dvodb);
     5708    return chipRunRowAlloc(chip_id, state, workdir, workdir_state, label, reduction, expgroup, dvodb);
    60175709}
    60185710psArray *chipRunSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    61145806
    61155807    psMetadata *md = chipRunMetadataFromObject(object);
     5808
     5809    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
     5810        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     5811        psFree(md);
     5812    }
     5813
     5814    psFree(md);
     5815
     5816    return true;
     5817}
     5818static void chipInputImfileRowFree(chipInputImfileRow *object);
     5819
     5820chipInputImfileRow *chipInputImfileRowAlloc(psS64 chip_id, psS64 exp_id, const char *class_id)
     5821{
     5822    chipInputImfileRow *_object;
     5823
     5824    _object = psAlloc(sizeof(chipInputImfileRow));
     5825    psMemSetDeallocator(_object, (psFreeFunc)chipInputImfileRowFree);
     5826
     5827    _object->chip_id = chip_id;
     5828    _object->exp_id = exp_id;
     5829    _object->class_id = psStringCopy(class_id);
     5830
     5831    return _object;
     5832}
     5833
     5834static void chipInputImfileRowFree(chipInputImfileRow *object)
     5835{
     5836    psFree(object->class_id);
     5837}
     5838
     5839bool chipInputImfileCreateTable(psDB *dbh)
     5840{
     5841    psMetadata *md = psMetadataAlloc();
     5842    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Primary Key fkey (chip_id) ref chipRun(chip_id)", 0)) {
     5843        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
     5844        psFree(md);
     5845        return false;
     5846    }
     5847    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key fkey (exp_id, class_id) ref rawImfile (exp_id, class_id)", 64)) {
     5848        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
     5849        psFree(md);
     5850        return false;
     5851    }
     5852    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
     5853        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
     5854        psFree(md);
     5855        return false;
     5856    }
     5857
     5858    bool status = psDBCreateTable(dbh, CHIPINPUTIMFILE_TABLE_NAME, md);
     5859
     5860    psFree(md);
     5861
     5862    return status;
     5863}
     5864
     5865bool chipInputImfileDropTable(psDB *dbh)
     5866{
     5867    return psDBDropTable(dbh, CHIPINPUTIMFILE_TABLE_NAME);
     5868}
     5869
     5870bool chipInputImfileInsert(psDB * dbh, psS64 chip_id, psS64 exp_id, const char *class_id)
     5871{
     5872    psMetadata *md = psMetadataAlloc();
     5873    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, NULL, chip_id)) {
     5874        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
     5875        psFree(md);
     5876        return false;
     5877    }
     5878    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
     5879        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
     5880        psFree(md);
     5881        return false;
     5882    }
     5883    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
     5884        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
     5885        psFree(md);
     5886        return false;
     5887    }
     5888
     5889    bool status = psDBInsertOneRow(dbh, CHIPINPUTIMFILE_TABLE_NAME, md);
     5890    psFree(md);
     5891
     5892    return status;
     5893}
     5894
     5895long long chipInputImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
     5896{
     5897    long long       deleted = 0;
     5898
     5899    long long count = psDBDeleteRows(dbh, CHIPINPUTIMFILE_TABLE_NAME, where, limit);
     5900    if (count < 0) {
     5901        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipInputImfile");
     5902        return count;
     5903
     5904        deleted += count;
     5905    }
     5906
     5907    return deleted;
     5908}
     5909bool chipInputImfileInsertObject(psDB *dbh, chipInputImfileRow *object)
     5910{
     5911    return chipInputImfileInsert(dbh, object->chip_id, object->exp_id, object->class_id);
     5912}
     5913
     5914bool chipInputImfileInsertObjects(psDB *dbh, psArray *objects)
     5915{
     5916    for (long i = 0; i < psArrayLength(objects); i++) {
     5917        if (!chipInputImfileInsertObject(dbh, objects->data[i])) {
     5918            return false;
     5919        }
     5920    }
     5921
     5922    return true;
     5923}
     5924
     5925bool chipInputImfileInsertFits(psDB *dbh, const psFits *fits)
     5926{
     5927    psArray         *rowSet;
     5928
     5929    // move to (the first?) extension named  CHIPINPUTIMFILE_TABLE_NAME
     5930    if (!psFitsMoveExtName(fits, CHIPINPUTIMFILE_TABLE_NAME)) {
     5931        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", CHIPINPUTIMFILE_TABLE_NAME);
     5932        return false;
     5933    }
     5934
     5935    // check HDU type
     5936    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
     5937        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
     5938        return false;
     5939    }
     5940
     5941    // read fits table
     5942    rowSet = psFitsReadTable(fits);
     5943    if (!rowSet) {
     5944        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
     5945        psFree(rowSet);
     5946        return false;
     5947    }
     5948
     5949    if (!psDBInsertRows(dbh, CHIPINPUTIMFILE_TABLE_NAME, rowSet)) {
     5950        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
     5951        psFree(rowSet);
     5952        return false;
     5953    }
     5954
     5955    psFree(rowSet);
     5956
     5957    return true;
     5958}
     5959
     5960bool chipInputImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
     5961{
     5962    psArray         *rowSet;
     5963
     5964    rowSet = psDBSelectRows(dbh, CHIPINPUTIMFILE_TABLE_NAME, where, limit);
     5965    if (!rowSet) {
     5966        return false;
     5967    }
     5968
     5969    // output to fits
     5970    if (!psFitsWriteTable(fits, NULL, rowSet, CHIPINPUTIMFILE_TABLE_NAME)) {
     5971        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
     5972        psFree(rowSet);
     5973        return false;
     5974    }
     5975
     5976    psFree(rowSet);
     5977
     5978    return true;
     5979}
     5980
     5981psMetadata *chipInputImfileMetadataFromObject(const chipInputImfileRow *object)
     5982{
     5983    psMetadata *md = psMetadataAlloc();
     5984    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, NULL, object->chip_id)) {
     5985        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
     5986        psFree(md);
     5987        return false;
     5988    }
     5989    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
     5990        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
     5991        psFree(md);
     5992        return false;
     5993    }
     5994    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) {
     5995        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
     5996        psFree(md);
     5997        return false;
     5998    }
     5999
     6000
     6001    return md;
     6002}
     6003
     6004chipInputImfileRow *chipInputImfileObjectFromMetadata(psMetadata *md)
     6005{
     6006
     6007bool status = false;
     6008    psS64 chip_id = psMetadataLookupS64(&status, md, "chip_id");
     6009    if (!status) {
     6010        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item chip_id");
     6011        return false;
     6012    }
     6013    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
     6014    if (!status) {
     6015        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
     6016        return false;
     6017    }
     6018    char* class_id = psMetadataLookupPtr(&status, md, "class_id");
     6019    if (!status) {
     6020        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id");
     6021        return false;
     6022    }
     6023
     6024    return chipInputImfileRowAlloc(chip_id, exp_id, class_id);
     6025}
     6026psArray *chipInputImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     6027{
     6028    psArray         *rowSet;
     6029    psArray         *returnSet;
     6030    psU64           i;
     6031
     6032    rowSet = psDBSelectRows(dbh, CHIPINPUTIMFILE_TABLE_NAME, where, limit);
     6033    if (!rowSet) {
     6034        return NULL;
     6035    }
     6036
     6037    // convert psMetadata rows to row objects
     6038
     6039    returnSet = psArrayAllocEmpty(rowSet->n);
     6040
     6041    for (i = 0; i < rowSet->n; i++) {
     6042        chipInputImfileRow *object = chipInputImfileObjectFromMetadata(rowSet->data[i]);
     6043        psArrayAdd(returnSet, 0, object);
     6044        psFree(object);
     6045    }
     6046
     6047    psFree(rowSet);
     6048
     6049    return returnSet;
     6050}
     6051bool chipInputImfileDeleteObject(psDB *dbh, const chipInputImfileRow *object)
     6052{
     6053    psMetadata *where = chipInputImfileMetadataFromObject(object);
     6054    long long count = psDBDeleteRows(dbh, CHIPINPUTIMFILE_TABLE_NAME, where, 0);
     6055    psFree(where);
     6056    if (count < 0) {
     6057        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipInputImfile");
     6058        return false;
     6059    }
     6060    if (count > 1) {
     6061        // XXX should this be a psAbort() instead?  It is possible that
     6062        // having an object match multiple rows was by design.
     6063        psError(PS_ERR_UNKNOWN, true, "chipInputImfileRow object matched more then one row.  Check your database schema");
     6064        return false;
     6065    }
     6066
     6067    return true;
     6068}
     6069long long chipInputImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
     6070{
     6071    long long       deleted = 0;
     6072
     6073    for (long long i = 0; i < objects->n; i++) {
     6074        chipInputImfileRow *object = objects->data[i];
     6075        psMetadata *where = chipInputImfileMetadataFromObject(object);
     6076        long long count = psDBDeleteRows(dbh, CHIPINPUTIMFILE_TABLE_NAME, where, limit);
     6077        psFree(where);
     6078        if (count < 0) {
     6079            psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipInputImfile");
     6080            return count;
     6081        }
     6082
     6083        deleted += count;
     6084    }
     6085
     6086    return deleted;
     6087}
     6088bool chipInputImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
     6089{
     6090    PS_ASSERT_PTR_NON_NULL(objects, false);
     6091
     6092    psMetadata *output = psMetadataAlloc();
     6093    for (long i = 0; i < psArrayLength(objects); i++) {
     6094        psMetadata *md = chipInputImfileMetadataFromObject(objects->data[i]);
     6095        if (!psMetadataAddMetadata(
     6096            output,
     6097            PS_LIST_TAIL,
     6098            CHIPINPUTIMFILE_TABLE_NAME,
     6099            PS_META_DUPLICATE_OK,
     6100            NULL,
     6101            md
     6102        )) {
     6103            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
     6104            psFree(md);
     6105            psFree(output);
     6106            return false;
     6107        }
     6108        psFree(md);
     6109    }
     6110
     6111    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
     6112        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     6113        psFree(output);
     6114    }
     6115    psFree(output);
     6116
     6117    return true;
     6118}
     6119bool chipInputImfilePrintObject(FILE *stream, chipInputImfileRow *object, bool mdcf)
     6120{
     6121    PS_ASSERT_PTR_NON_NULL(object, false);
     6122
     6123    psMetadata *md = chipInputImfileMetadataFromObject(object);
    61166124
    61176125    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
     
    61716179{
    61726180    psMetadata *md = psMetadataAlloc();
    6173     if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Primary Key fkey (chip_id, exp_id) ref chipRun(chip_id, exp_id)", 0)) {
     6181    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Primary Key fkey (chip_id, exp_id, class_id) ref chipInputImfile(chip_id, exp_id, class_id)", 0)) {
    61746182        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
    61756183        psFree(md);
    61766184        return false;
    61776185    }
    6178     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key fkey (exp_id, class_id) ref rawImfile(exp_id, class_id)", 64)) {
     6186    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key", 64)) {
    61796187        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    61806188        psFree(md);
     
    62516259        return false;
    62526260    }
    6253     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, "# replace this with fwhm_major", 0.0)) {
     6261    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, NULL, 0.0)) {
    62546262        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm");
    62556263        psFree(md);
    62566264        return false;
    62576265    }
    6258     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, "# replace this with fwhm_minor", 0.0)) {
     6266    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, NULL, 0.0)) {
    62596267        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_range");
    62606268        psFree(md);
     
    71987206        return false;
    71997207    }
    7200     if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Key INDEX(cam_id, chip_id) fkey(chip_id) ref chipRun(chip_id)", 0)) {
     7208    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Primary Key fkey(chip_id) ref chipRun(chip_id)", 0)) {
    72017209        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
    72027210        psFree(md);
     
    95929600static void warpSkyfileRowFree(warpSkyfileRow *object);
    95939601
    9594 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, psF64 pixel_fill, psS16 fault)
     9602warpSkyfileRow *warpSkyfileRowAlloc(psS64 warp_id, const char *skycell_id, const char *tess_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev)
    95959603{
    95969604    warpSkyfileRow  *_object;
     
    96069614    _object->bg = bg;
    96079615    _object->bg_stdev = bg_stdev;
    9608     _object->pixel_fill = pixel_fill;
    9609     _object->fault = fault;
    96109616
    96119617    return _object;
     
    96589664        return false;
    96599665    }
    9660     if (!psMetadataAdd(md, PS_LIST_TAIL, "pixel_fill", PS_DATA_F64, "Key", 0.0)) {
    9661         psError(PS_ERR_UNKNOWN, false, "failed to add item pixel_fill");
    9662         psFree(md);
    9663         return false;
    9664     }
    9665     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, "Key", 0)) {
    9666         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    9667         psFree(md);
    9668         return false;
    9669     }
    96709666
    96719667    bool status = psDBCreateTable(dbh, WARPSKYFILE_TABLE_NAME, md);
     
    96819677}
    96829678
    9683 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, psF64 pixel_fill, psS16 fault)
     9679bool 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)
    96849680{
    96859681    psMetadata *md = psMetadataAlloc();
     
    97169712    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_stdev", PS_DATA_F64, NULL, bg_stdev)) {
    97179713        psError(PS_ERR_UNKNOWN, false, "failed to add item bg_stdev");
    9718         psFree(md);
    9719         return false;
    9720     }
    9721     if (!psMetadataAdd(md, PS_LIST_TAIL, "pixel_fill", PS_DATA_F64, NULL, pixel_fill)) {
    9722         psError(PS_ERR_UNKNOWN, false, "failed to add item pixel_fill");
    9723         psFree(md);
    9724         return false;
    9725     }
    9726     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, fault)) {
    9727         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    97289714        psFree(md);
    97299715        return false;
     
    97529738bool warpSkyfileInsertObject(psDB *dbh, warpSkyfileRow *object)
    97539739{
    9754     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);
     9740    return warpSkyfileInsert(dbh, object->warp_id, object->skycell_id, object->tess_id, object->uri, object->path_base, object->bg, object->bg_stdev);
    97559741}
    97569742
     
    98609846        return false;
    98619847    }
    9862     if (!psMetadataAdd(md, PS_LIST_TAIL, "pixel_fill", PS_DATA_F64, NULL, object->pixel_fill)) {
    9863         psError(PS_ERR_UNKNOWN, false, "failed to add item pixel_fill");
    9864         psFree(md);
    9865         return false;
    9866     }
    9867     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, object->fault)) {
    9868         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    9869         psFree(md);
    9870         return false;
    9871     }
    98729848
    98739849
     
    99149890        return false;
    99159891    }
    9916     psF64 pixel_fill = psMetadataLookupF64(&status, md, "pixel_fill");
    9917     if (!status) {
    9918         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item pixel_fill");
    9919         return false;
    9920     }
    9921     psS16 fault = psMetadataLookupS16(&status, md, "fault");
    9922     if (!status) {
    9923         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fault");
    9924         return false;
    9925     }
    9926 
    9927     return warpSkyfileRowAlloc(warp_id, skycell_id, tess_id, uri, path_base, bg, bg_stdev, pixel_fill, fault);
     9892
     9893    return warpSkyfileRowAlloc(warp_id, skycell_id, tess_id, uri, path_base, bg, bg_stdev);
    99289894}
    99299895psArray *warpSkyfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    1044210408static void diffInputSkyfileRowFree(diffInputSkyfileRow *object);
    1044310409
    10444 diffInputSkyfileRow *diffInputSkyfileRowAlloc(psS64 diff_id, bool template, psS64 stack_id, psS64 warp_id, const char *skycell_id, const char *tess_id, const char *kind)
     10410diffInputSkyfileRow *diffInputSkyfileRowAlloc(psS64 diff_id, psS64 warp_id, const char *skycell_id, const char *tess_id, const char *kind, bool template)
    1044510411{
    1044610412    diffInputSkyfileRow *_object;
     
    1045010416
    1045110417    _object->diff_id = diff_id;
    10452     _object->template = template;
    10453     _object->stack_id = stack_id;
    1045410418    _object->warp_id = warp_id;
    1045510419    _object->skycell_id = psStringCopy(skycell_id);
    1045610420    _object->tess_id = psStringCopy(tess_id);
    1045710421    _object->kind = psStringCopy(kind);
     10422    _object->template = template;
    1045810423
    1045910424    return _object;
     
    1047510440        return false;
    1047610441    }
    10477     if (!psMetadataAdd(md, PS_LIST_TAIL, "template", PS_DATA_BOOL, "Primary Key", 0)) {
    10478         psError(PS_ERR_UNKNOWN, false, "failed to add item template");
    10479         psFree(md);
    10480         return false;
    10481     }
    10482     if (!psMetadataAdd(md, PS_LIST_TAIL, "stack_id", PS_DATA_S64, "fkey(stack_id) ref stackSumSkyfile(stack_id)", 0)) {
    10483         psError(PS_ERR_UNKNOWN, false, "failed to add item stack_id");
    10484         psFree(md);
    10485         return false;
    10486     }
    10487     if (!psMetadataAdd(md, PS_LIST_TAIL, "warp_id", PS_DATA_S64, "fkey(warp_id, skycell_id, tess_id) ref warpSkyfile(warp_id, skycell_id, tess_id)", 0)) {
     10442    if (!psMetadataAdd(md, PS_LIST_TAIL, "warp_id", PS_DATA_S64, "Primary Key fkey(warp_id, skycell_id, tess_id) ref warpSkyfile(warp_id, skycell_id, tess_id)", 0)) {
    1048810443        psError(PS_ERR_UNKNOWN, false, "failed to add item warp_id");
    1048910444        psFree(md);
    1049010445        return false;
    1049110446    }
    10492     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, "Key", "64")) {
     10447    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, "Primary Key", "64")) {
    1049310448        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    1049410449        psFree(md);
    1049510450        return false;
    1049610451    }
    10497     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, "Key", "64")) {
     10452    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, "Primary Key", "64")) {
    1049810453        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    1049910454        psFree(md);
     
    1050510460        return false;
    1050610461    }
     10462    if (!psMetadataAdd(md, PS_LIST_TAIL, "template", PS_DATA_BOOL, NULL, 0)) {
     10463        psError(PS_ERR_UNKNOWN, false, "failed to add item template");
     10464        psFree(md);
     10465        return false;
     10466    }
    1050710467
    1050810468    bool status = psDBCreateTable(dbh, DIFFINPUTSKYFILE_TABLE_NAME, md);
     
    1051810478}
    1051910479
    10520 bool diffInputSkyfileInsert(psDB * dbh, psS64 diff_id, bool template, psS64 stack_id, psS64 warp_id, const char *skycell_id, const char *tess_id, const char *kind)
     10480bool diffInputSkyfileInsert(psDB * dbh, psS64 diff_id, psS64 warp_id, const char *skycell_id, const char *tess_id, const char *kind, bool template)
    1052110481{
    1052210482    psMetadata *md = psMetadataAlloc();
     
    1052610486        return false;
    1052710487    }
     10488    if (!psMetadataAdd(md, PS_LIST_TAIL, "warp_id", PS_DATA_S64, NULL, warp_id)) {
     10489        psError(PS_ERR_UNKNOWN, false, "failed to add item warp_id");
     10490        psFree(md);
     10491        return false;
     10492    }
     10493    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) {
     10494        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
     10495        psFree(md);
     10496        return false;
     10497    }
     10498    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) {
     10499        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
     10500        psFree(md);
     10501        return false;
     10502    }
     10503    if (!psMetadataAdd(md, PS_LIST_TAIL, "kind", PS_DATA_STRING, NULL, kind)) {
     10504        psError(PS_ERR_UNKNOWN, false, "failed to add item kind");
     10505        psFree(md);
     10506        return false;
     10507    }
    1052810508    if (!psMetadataAdd(md, PS_LIST_TAIL, "template", PS_DATA_BOOL, NULL, template)) {
    1052910509        psError(PS_ERR_UNKNOWN, false, "failed to add item template");
    10530         psFree(md);
    10531         return false;
    10532     }
    10533     if (!psMetadataAdd(md, PS_LIST_TAIL, "stack_id", PS_DATA_S64, NULL, stack_id)) {
    10534         psError(PS_ERR_UNKNOWN, false, "failed to add item stack_id");
    10535         psFree(md);
    10536         return false;
    10537     }
    10538     if (!psMetadataAdd(md, PS_LIST_TAIL, "warp_id", PS_DATA_S64, NULL, warp_id)) {
    10539         psError(PS_ERR_UNKNOWN, false, "failed to add item warp_id");
    10540         psFree(md);
    10541         return false;
    10542     }
    10543     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) {
    10544         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    10545         psFree(md);
    10546         return false;
    10547     }
    10548     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) {
    10549         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    10550         psFree(md);
    10551         return false;
    10552     }
    10553     if (!psMetadataAdd(md, PS_LIST_TAIL, "kind", PS_DATA_STRING, NULL, kind)) {
    10554         psError(PS_ERR_UNKNOWN, false, "failed to add item kind");
    1055510510        psFree(md);
    1055610511        return false;
     
    1057910534bool diffInputSkyfileInsertObject(psDB *dbh, diffInputSkyfileRow *object)
    1058010535{
    10581     return diffInputSkyfileInsert(dbh, object->diff_id, object->template, object->stack_id, object->warp_id, object->skycell_id, object->tess_id, object->kind);
     10536    return diffInputSkyfileInsert(dbh, object->diff_id, object->warp_id, object->skycell_id, object->tess_id, object->kind, object->template);
    1058210537}
    1058310538
     
    1065710612        return false;
    1065810613    }
     10614    if (!psMetadataAdd(md, PS_LIST_TAIL, "warp_id", PS_DATA_S64, NULL, object->warp_id)) {
     10615        psError(PS_ERR_UNKNOWN, false, "failed to add item warp_id");
     10616        psFree(md);
     10617        return false;
     10618    }
     10619    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) {
     10620        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
     10621        psFree(md);
     10622        return false;
     10623    }
     10624    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) {
     10625        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
     10626        psFree(md);
     10627        return false;
     10628    }
     10629    if (!psMetadataAdd(md, PS_LIST_TAIL, "kind", PS_DATA_STRING, NULL, object->kind)) {
     10630        psError(PS_ERR_UNKNOWN, false, "failed to add item kind");
     10631        psFree(md);
     10632        return false;
     10633    }
    1065910634    if (!psMetadataAdd(md, PS_LIST_TAIL, "template", PS_DATA_BOOL, NULL, object->template)) {
    1066010635        psError(PS_ERR_UNKNOWN, false, "failed to add item template");
     
    1066210637        return false;
    1066310638    }
    10664     if (!psMetadataAdd(md, PS_LIST_TAIL, "stack_id", PS_DATA_S64, NULL, object->stack_id)) {
    10665         psError(PS_ERR_UNKNOWN, false, "failed to add item stack_id");
    10666         psFree(md);
    10667         return false;
    10668     }
    10669     if (!psMetadataAdd(md, PS_LIST_TAIL, "warp_id", PS_DATA_S64, NULL, object->warp_id)) {
    10670         psError(PS_ERR_UNKNOWN, false, "failed to add item warp_id");
    10671         psFree(md);
    10672         return false;
    10673     }
    10674     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) {
    10675         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    10676         psFree(md);
    10677         return false;
    10678     }
    10679     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) {
    10680         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    10681         psFree(md);
    10682         return false;
    10683     }
    10684     if (!psMetadataAdd(md, PS_LIST_TAIL, "kind", PS_DATA_STRING, NULL, object->kind)) {
    10685         psError(PS_ERR_UNKNOWN, false, "failed to add item kind");
    10686         psFree(md);
    10687         return false;
    10688     }
    1068910639
    1069010640
     
    1070110651        return false;
    1070210652    }
     10653    psS64 warp_id = psMetadataLookupS64(&status, md, "warp_id");
     10654    if (!status) {
     10655        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item warp_id");
     10656        return false;
     10657    }
     10658    char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id");
     10659    if (!status) {
     10660        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id");
     10661        return false;
     10662    }
     10663    char* tess_id = psMetadataLookupPtr(&status, md, "tess_id");
     10664    if (!status) {
     10665        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id");
     10666        return false;
     10667    }
     10668    char* kind = psMetadataLookupPtr(&status, md, "kind");
     10669    if (!status) {
     10670        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item kind");
     10671        return false;
     10672    }
    1070310673    bool template = psMetadataLookupBool(&status, md, "template");
    1070410674    if (!status) {
     
    1070610676        return false;
    1070710677    }
    10708     psS64 stack_id = psMetadataLookupS64(&status, md, "stack_id");
    10709     if (!status) {
    10710         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item stack_id");
    10711         return false;
    10712     }
    10713     psS64 warp_id = psMetadataLookupS64(&status, md, "warp_id");
    10714     if (!status) {
    10715         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item warp_id");
    10716         return false;
    10717     }
    10718     char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id");
    10719     if (!status) {
    10720         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id");
    10721         return false;
    10722     }
    10723     char* tess_id = psMetadataLookupPtr(&status, md, "tess_id");
    10724     if (!status) {
    10725         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id");
    10726         return false;
    10727     }
    10728     char* kind = psMetadataLookupPtr(&status, md, "kind");
    10729     if (!status) {
    10730         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item kind");
    10731         return false;
    10732     }
    10733 
    10734     return diffInputSkyfileRowAlloc(diff_id, template, stack_id, warp_id, skycell_id, tess_id, kind);
     10678
     10679    return diffInputSkyfileRowAlloc(diff_id, warp_id, skycell_id, tess_id, kind, template);
    1073510680}
    1073610681psArray *diffInputSkyfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    1084410789static void diffSkyfileRowFree(diffSkyfileRow *object);
    1084510790
    10846 diffSkyfileRow *diffSkyfileRowAlloc(psS64 diff_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psS16 fault)
     10791diffSkyfileRow *diffSkyfileRowAlloc(psS64 diff_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev)
    1084710792{
    1084810793    diffSkyfileRow  *_object;
     
    1085610801    _object->bg = bg;
    1085710802    _object->bg_stdev = bg_stdev;
    10858     _object->fault = fault;
    1085910803
    1086010804    return _object;
     
    1089510839        return false;
    1089610840    }
    10897     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, "Key", 0)) {
    10898         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    10899         psFree(md);
    10900         return false;
    10901     }
    1090210841
    1090310842    bool status = psDBCreateTable(dbh, DIFFSKYFILE_TABLE_NAME, md);
     
    1091310852}
    1091410853
    10915 bool diffSkyfileInsert(psDB * dbh, psS64 diff_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psS16 fault)
     10854bool diffSkyfileInsert(psDB * dbh, psS64 diff_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev)
    1091610855{
    1091710856    psMetadata *md = psMetadataAlloc();
     
    1093810877    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_stdev", PS_DATA_F64, NULL, bg_stdev)) {
    1093910878        psError(PS_ERR_UNKNOWN, false, "failed to add item bg_stdev");
    10940         psFree(md);
    10941         return false;
    10942     }
    10943     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, fault)) {
    10944         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    1094510879        psFree(md);
    1094610880        return false;
     
    1096910903bool diffSkyfileInsertObject(psDB *dbh, diffSkyfileRow *object)
    1097010904{
    10971     return diffSkyfileInsert(dbh, object->diff_id, object->uri, object->path_base, object->bg, object->bg_stdev, object->fault);
     10905    return diffSkyfileInsert(dbh, object->diff_id, object->uri, object->path_base, object->bg, object->bg_stdev);
    1097210906}
    1097310907
     
    1106711001        return false;
    1106811002    }
    11069     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, object->fault)) {
    11070         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    11071         psFree(md);
    11072         return false;
    11073     }
    1107411003
    1107511004
     
    1110611035        return false;
    1110711036    }
    11108     psS16 fault = psMetadataLookupS16(&status, md, "fault");
    11109     if (!status) {
    11110         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fault");
    11111         return false;
    11112     }
    11113 
    11114     return diffSkyfileRowAlloc(diff_id, uri, path_base, bg, bg_stdev, fault);
     11037
     11038    return diffSkyfileRowAlloc(diff_id, uri, path_base, bg, bg_stdev);
    1111511039}
    1111611040psArray *diffSkyfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    1192311847static void stackSumSkyfileRowFree(stackSumSkyfileRow *object);
    1192411848
    11925 stackSumSkyfileRow *stackSumSkyfileRowAlloc(psS64 stack_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psS16 fault)
     11849stackSumSkyfileRow *stackSumSkyfileRowAlloc(psS64 stack_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev)
    1192611850{
    1192711851    stackSumSkyfileRow *_object;
     
    1193511859    _object->bg = bg;
    1193611860    _object->bg_stdev = bg_stdev;
    11937     _object->fault = fault;
    1193811861
    1193911862    return _object;
     
    1197411897        return false;
    1197511898    }
    11976     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, "Key", 0)) {
    11977         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    11978         psFree(md);
    11979         return false;
    11980     }
    1198111899
    1198211900    bool status = psDBCreateTable(dbh, STACKSUMSKYFILE_TABLE_NAME, md);
     
    1199211910}
    1199311911
    11994 bool stackSumSkyfileInsert(psDB * dbh, psS64 stack_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psS16 fault)
     11912bool stackSumSkyfileInsert(psDB * dbh, psS64 stack_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev)
    1199511913{
    1199611914    psMetadata *md = psMetadataAlloc();
     
    1201711935    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_stdev", PS_DATA_F64, NULL, bg_stdev)) {
    1201811936        psError(PS_ERR_UNKNOWN, false, "failed to add item bg_stdev");
    12019         psFree(md);
    12020         return false;
    12021     }
    12022     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, fault)) {
    12023         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    1202411937        psFree(md);
    1202511938        return false;
     
    1204811961bool stackSumSkyfileInsertObject(psDB *dbh, stackSumSkyfileRow *object)
    1204911962{
    12050     return stackSumSkyfileInsert(dbh, object->stack_id, object->uri, object->path_base, object->bg, object->bg_stdev, object->fault);
     11963    return stackSumSkyfileInsert(dbh, object->stack_id, object->uri, object->path_base, object->bg, object->bg_stdev);
    1205111964}
    1205211965
     
    1214612059        return false;
    1214712060    }
    12148     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, object->fault)) {
    12149         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    12150         psFree(md);
    12151         return false;
    12152     }
    1215312061
    1215412062
     
    1218512093        return false;
    1218612094    }
    12187     psS16 fault = psMetadataLookupS16(&status, md, "fault");
    12188     if (!status) {
    12189         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fault");
    12190         return false;
    12191     }
    12192 
    12193     return stackSumSkyfileRowAlloc(stack_id, uri, path_base, bg, bg_stdev, fault);
     12095
     12096    return stackSumSkyfileRowAlloc(stack_id, uri, path_base, bg, bg_stdev);
    1219412097}
    1219512098psArray *stackSumSkyfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    1237112274        return false;
    1237212275    }
    12373     if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Key INDEX(det_id, iteration)", 0)) {
     12276    if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Key", 0)) {
    1237412277        psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");
    1237512278        psFree(md);
     
    1320213105{
    1320313106    psMetadata *md = psMetadataAlloc();
    13204     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key fkey(det_id) ref detRun(det_id)", 0)) {
     13107    if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key", 0)) {
    1320513108        psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    1320613109        psFree(md);
    1320713110        return false;
    1320813111    }
    13209     if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key fkey(exp_id) ref rawExp(exp_id)", 0)) {
     13112    if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key", 0)) {
    1321013113        psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");
    1321113114        psFree(md);
    1321213115        return false;
    1321313116    }
    13214     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key INDEX(det_id, exp_id)", 64)) {
     13117    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key", 64)) {
    1321513118        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    1321613119        psFree(md);
    1321713120        return false;
    1321813121    }
    13219     if (!psMetadataAdd(md, PS_LIST_TAIL, "include", PS_DATA_BOOL, "INDEX(det_id, iteration)", 0)) {
     13122    if (!psMetadataAdd(md, PS_LIST_TAIL, "include", PS_DATA_BOOL, NULL, 0)) {
    1322013123        psError(PS_ERR_UNKNOWN, false, "failed to add item include");
    1322113124        psFree(md);
     
    1355613459{
    1355713460    psMetadata *md = psMetadataAlloc();
    13558     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key fkey(det_id, exp_id) ref detInputExp(det_id, exp_id)", 0)) {
     13461    if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key", 0)) {
    1355913462        psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    1356013463        psFree(md);
    1356113464        return false;
    1356213465    }
    13563     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key fkey(exp_id, class_id) ref rawImfile(exp_id, class_id)", 64)) {
     13466    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key", 64)) {
    1356413467        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    1356513468        psFree(md);
    1356613469        return false;
    1356713470    }
    13568     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key INDEX(det_id, class_id)", "64")) {
     13471    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
    1356913472        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    1357013473        psFree(md);
    1357113474        return false;
    1357213475    }
    13573     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, "INDEX(det_id, exp_id)", "255")) {
     13476    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
    1357413477        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    1357513478        psFree(md);
     
    1418614089{
    1418714090    psMetadata *md = psMetadataAlloc();
    14188     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key fkey(det_id, exp_id) ref detInputExp(det_id, exp_id)", 0)) {
     14091    if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key", 0)) {
    1418914092        psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    1419014093        psFree(md);
    1419114094        return false;
    1419214095    }
    14193     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key fkey(det_id, exp_id) ref detProcessedImfile(det_id, exp_id)", 64)) {
     14096    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key", 64)) {
    1419414097        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    1419514098        psFree(md);
     
    1477514678{
    1477614679    psMetadata *md = psMetadataAlloc();
    14777     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key fkey(det_id, iteration) ref detInputExp(det_id, iteration)", 0)) {
     14680    if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key", 0)) {
    1477814681        psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    1477914682        psFree(md);
    1478014683        return false;
    1478114684    }
    14782     if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key fkey(det_id, class_id) ref detProcessedImfile(det_id, class_id)", 0)) {
     14685    if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key", 0)) {
    1478314686        psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");
    1478414687        psFree(md);
     
    1531315216{
    1531415217    psMetadata *md = psMetadataAlloc();
    15315     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key fkey(det_id, iteration) ref detInputExp(det_id, iteration)", 0)) {
     15218    if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key", 0)) {
    1531615219        psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    1531715220        psFree(md);
    1531815221        return false;
    1531915222    }
    15320     if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key fkey(det_id, iteration, class_id) ref detStackedImfile(det_id, iteration, class_id)", 0)) {
     15223    if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key", 0)) {
    1532115224        psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");
    1532215225        psFree(md);
     
    1568215585{
    1568315586    psMetadata *md = psMetadataAlloc();
    15684     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key fkey(det_id) ref detInputExp(det_id)", 0)) {
     15587    if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key", 0)) {
    1568515588        psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    1568615589        psFree(md);
    1568715590        return false;
    1568815591    }
    15689     if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key fkey(det_id, iteration, class_id) ref detNormalizedStatImfile(det_id, iteration, class_id)", 0)) {
     15592    if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key", 0)) {
    1569015593        psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");
    1569115594        psFree(md);
    1569215595        return false;
    1569315596    }
    15694     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key INDEX(det_id, iteration)", "64")) {
     15597    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
    1569515598        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    1569615599        psFree(md);
     
    1622916132{
    1623016133    psMetadata *md = psMetadataAlloc();
    16231     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key fkey(det_id, iteration) ref detInputExp(det_id, iteration)", 0)) {
     16134    if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key", 0)) {
    1623216135        psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    1623316136        psFree(md);
    1623416137        return false;
    1623516138    }
    16236     if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key fkey(det_id, iteration) ref detNormalizedImfile(det_id, iteration)", 0)) {
     16139    if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key", 0)) {
    1623716140        psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");
    1623816141        psFree(md);
     
    1672316626static void detResidImfileRowFree(detResidImfileRow *object);
    1672416627
    16725 detResidImfileRow *detResidImfileRowAlloc(psS64 det_id, psS32 iteration, psS64 exp_id, const char *class_id, const char *uri, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bg_skewness, psF64 bg_kurtosis, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 fringe_resid_0, psF64 fringe_resid_1, psF64 fringe_resid_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
     16628detResidImfileRow *detResidImfileRowAlloc(psS64 det_id, psS32 iteration, psS64 exp_id, const char *class_id, const char *uri, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
    1672616629{
    1672716630    detResidImfileRow *_object;
     
    1673916642    _object->bg_stdev = bg_stdev;
    1674016643    _object->bg_mean_stdev = bg_mean_stdev;
    16741     _object->bg_skewness = bg_skewness;
    16742     _object->bg_kurtosis = bg_kurtosis;
    1674316644    _object->bin_stdev = bin_stdev;
    1674416645    _object->fringe_0 = fringe_0;
    1674516646    _object->fringe_1 = fringe_1;
    1674616647    _object->fringe_2 = fringe_2;
    16747     _object->fringe_resid_0 = fringe_resid_0;
    16748     _object->fringe_resid_1 = fringe_resid_1;
    16749     _object->fringe_resid_2 = fringe_resid_2;
    1675016648    _object->user_1 = user_1;
    1675116649    _object->user_2 = user_2;
     
    1677016668{
    1677116669    psMetadata *md = psMetadataAlloc();
    16772     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key fkey(det_id, iteration, exp_id) ref detInputExp(det_id, iteration, exp_id)", 0)) {
     16670    if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key", 0)) {
    1677316671        psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    1677416672        psFree(md);
    1677516673        return false;
    1677616674    }
    16777     if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key fkey(det_id, exp_id, class_id) ref detProcessedImfile(det_id, exp_id, class_id)", 0)) {
     16675    if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key", 0)) {
    1677816676        psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");
    1677916677        psFree(md);
    1678016678        return false;
    1678116679    }
    16782     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key fkey(det_id, iteration) ref detNormalizedExp(det_id, iteration)", 64)) {
     16680    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key", 64)) {
    1678316681        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    1678416682        psFree(md);
    1678516683        return false;
    1678616684    }
    16787     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key INDEX(det_id, iteration, exp_id)", "64")) {
     16685    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
    1678816686        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    1678916687        psFree(md);
     
    1681516713        return false;
    1681616714    }
    16817     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_skewness", PS_DATA_F64, NULL, 0.0)) {
    16818         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_skewness");
    16819         psFree(md);
    16820         return false;
    16821     }
    16822     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_kurtosis", PS_DATA_F64, NULL, 0.0)) {
    16823         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_kurtosis");
    16824         psFree(md);
    16825         return false;
    16826     }
    1682716715    if (!psMetadataAdd(md, PS_LIST_TAIL, "bin_stdev", PS_DATA_F64, NULL, 0.0)) {
    1682816716        psError(PS_ERR_UNKNOWN, false, "failed to add item bin_stdev");
     
    1684516733        return false;
    1684616734    }
    16847     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_0", PS_DATA_F64, NULL, 0.0)) {
    16848         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_0");
    16849         psFree(md);
    16850         return false;
    16851     }
    16852     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_1", PS_DATA_F64, NULL, 0.0)) {
    16853         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_1");
    16854         psFree(md);
    16855         return false;
    16856     }
    16857     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_2", PS_DATA_F64, NULL, 0.0)) {
    16858         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_2");
    16859         psFree(md);
    16860         return false;
    16861     }
    1686216735    if (!psMetadataAdd(md, PS_LIST_TAIL, "user_1", PS_DATA_F64, NULL, 0.0)) {
    1686316736        psError(PS_ERR_UNKNOWN, false, "failed to add item user_1");
     
    1690816781}
    1690916782
    16910 bool detResidImfileInsert(psDB * dbh, psS64 det_id, psS32 iteration, psS64 exp_id, const char *class_id, const char *uri, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bg_skewness, psF64 bg_kurtosis, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 fringe_resid_0, psF64 fringe_resid_1, psF64 fringe_resid_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
     16783bool detResidImfileInsert(psDB * dbh, psS64 det_id, psS32 iteration, psS64 exp_id, const char *class_id, const char *uri, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
    1691116784{
    1691216785    psMetadata *md = psMetadataAlloc();
     
    1695616829        return false;
    1695716830    }
    16958     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_skewness", PS_DATA_F64, NULL, bg_skewness)) {
    16959         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_skewness");
    16960         psFree(md);
    16961         return false;
    16962     }
    16963     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_kurtosis", PS_DATA_F64, NULL, bg_kurtosis)) {
    16964         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_kurtosis");
    16965         psFree(md);
    16966         return false;
    16967     }
    1696816831    if (!psMetadataAdd(md, PS_LIST_TAIL, "bin_stdev", PS_DATA_F64, NULL, bin_stdev)) {
    1696916832        psError(PS_ERR_UNKNOWN, false, "failed to add item bin_stdev");
     
    1698316846    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_2", PS_DATA_F64, NULL, fringe_2)) {
    1698416847        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_2");
    16985         psFree(md);
    16986         return false;
    16987     }
    16988     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_0", PS_DATA_F64, NULL, fringe_resid_0)) {
    16989         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_0");
    16990         psFree(md);
    16991         return false;
    16992     }
    16993     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_1", PS_DATA_F64, NULL, fringe_resid_1)) {
    16994         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_1");
    16995         psFree(md);
    16996         return false;
    16997     }
    16998     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_2", PS_DATA_F64, NULL, fringe_resid_2)) {
    16999         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_2");
    1700016848        psFree(md);
    1700116849        return false;
     
    1705916907bool detResidImfileInsertObject(psDB *dbh, detResidImfileRow *object)
    1706016908{
    17061     return detResidImfileInsert(dbh, object->det_id, object->iteration, object->exp_id, object->class_id, object->uri, object->recipe, object->bg, object->bg_stdev, object->bg_mean_stdev, object->bg_skewness, object->bg_kurtosis, object->bin_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->fringe_resid_0, object->fringe_resid_1, object->fringe_resid_2, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->path_base, object->fault);
     16909    return detResidImfileInsert(dbh, object->det_id, object->iteration, object->exp_id, object->class_id, object->uri, object->recipe, object->bg, object->bg_stdev, object->bg_mean_stdev, object->bin_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->path_base, object->fault);
    1706216910}
    1706316911
     
    1717717025        return false;
    1717817026    }
    17179     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_skewness", PS_DATA_F64, NULL, object->bg_skewness)) {
    17180         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_skewness");
    17181         psFree(md);
    17182         return false;
    17183     }
    17184     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_kurtosis", PS_DATA_F64, NULL, object->bg_kurtosis)) {
    17185         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_kurtosis");
    17186         psFree(md);
    17187         return false;
    17188     }
    1718917027    if (!psMetadataAdd(md, PS_LIST_TAIL, "bin_stdev", PS_DATA_F64, NULL, object->bin_stdev)) {
    1719017028        psError(PS_ERR_UNKNOWN, false, "failed to add item bin_stdev");
     
    1720717045        return false;
    1720817046    }
    17209     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_0", PS_DATA_F64, NULL, object->fringe_resid_0)) {
    17210         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_0");
    17211         psFree(md);
    17212         return false;
    17213     }
    17214     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_1", PS_DATA_F64, NULL, object->fringe_resid_1)) {
    17215         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_1");
    17216         psFree(md);
    17217         return false;
    17218     }
    17219     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_2", PS_DATA_F64, NULL, object->fringe_resid_2)) {
    17220         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_2");
    17221         psFree(md);
    17222         return false;
    17223     }
    1722417047    if (!psMetadataAdd(md, PS_LIST_TAIL, "user_1", PS_DATA_F64, NULL, object->user_1)) {
    1722517048        psError(PS_ERR_UNKNOWN, false, "failed to add item user_1");
     
    1731117134        return false;
    1731217135    }
    17313     psF64 bg_skewness = psMetadataLookupF64(&status, md, "bg_skewness");
    17314     if (!status) {
    17315         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bg_skewness");
    17316         return false;
    17317     }
    17318     psF64 bg_kurtosis = psMetadataLookupF64(&status, md, "bg_kurtosis");
    17319     if (!status) {
    17320         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bg_kurtosis");
    17321         return false;
    17322     }
    1732317136    psF64 bin_stdev = psMetadataLookupF64(&status, md, "bin_stdev");
    1732417137    if (!status) {
     
    1734117154        return false;
    1734217155    }
    17343     psF64 fringe_resid_0 = psMetadataLookupF64(&status, md, "fringe_resid_0");
    17344     if (!status) {
    17345         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fringe_resid_0");
    17346         return false;
    17347     }
    17348     psF64 fringe_resid_1 = psMetadataLookupF64(&status, md, "fringe_resid_1");
    17349     if (!status) {
    17350         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fringe_resid_1");
    17351         return false;
    17352     }
    17353     psF64 fringe_resid_2 = psMetadataLookupF64(&status, md, "fringe_resid_2");
    17354     if (!status) {
    17355         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fringe_resid_2");
    17356         return false;
    17357     }
    1735817156    psF64 user_1 = psMetadataLookupF64(&status, md, "user_1");
    1735917157    if (!status) {
     
    1739217190    }
    1739317191
    17394     return detResidImfileRowAlloc(det_id, iteration, exp_id, class_id, uri, recipe, bg, bg_stdev, bg_mean_stdev, bg_skewness, bg_kurtosis, bin_stdev, fringe_0, fringe_1, fringe_2, fringe_resid_0, fringe_resid_1, fringe_resid_2, user_1, user_2, user_3, user_4, user_5, path_base, fault);
     17192    return detResidImfileRowAlloc(det_id, iteration, exp_id, class_id, uri, recipe, bg, bg_stdev, bg_mean_stdev, bin_stdev, fringe_0, fringe_1, fringe_2, user_1, user_2, user_3, user_4, user_5, path_base, fault);
    1739517193}
    1739617194psArray *detResidImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    1750417302static void detResidExpRowFree(detResidExpRow *object);
    1750517303
    17506 detResidExpRow *detResidExpRowAlloc(psS64 det_id, psS32 iteration, psS64 exp_id, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bg_skewness, psF64 bg_kurtosis, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 fringe_resid_0, psF64 fringe_resid_1, psF64 fringe_resid_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, bool accept, psS16 fault)
     17304detResidExpRow *detResidExpRowAlloc(psS64 det_id, psS32 iteration, psS64 exp_id, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, bool accept, psS16 fault)
    1750717305{
    1750817306    detResidExpRow  *_object;
     
    1751817316    _object->bg_stdev = bg_stdev;
    1751917317    _object->bg_mean_stdev = bg_mean_stdev;
    17520     _object->bg_skewness = bg_skewness;
    17521     _object->bg_kurtosis = bg_kurtosis;
    1752217318    _object->bin_stdev = bin_stdev;
    1752317319    _object->fringe_0 = fringe_0;
    1752417320    _object->fringe_1 = fringe_1;
    1752517321    _object->fringe_2 = fringe_2;
    17526     _object->fringe_resid_0 = fringe_resid_0;
    17527     _object->fringe_resid_1 = fringe_resid_1;
    17528     _object->fringe_resid_2 = fringe_resid_2;
    1752917322    _object->user_1 = user_1;
    1753017323    _object->user_2 = user_2;
     
    1754817341{
    1754917342    psMetadata *md = psMetadataAlloc();
    17550     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key fkey(det_id, iteration, exp_id) ref detInputExp(det_id, iteration, exp_id)", 0)) {
     17343    if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key", 0)) {
    1755117344        psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    1755217345        psFree(md);
    1755317346        return false;
    1755417347    }
    17555     if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key fkey(det_id, iteration, exp_id) ref detResidImfile(det_id, iteration, exp_id)", 0)) {
     17348    if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key", 0)) {
    1755617349        psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");
    1755717350        psFree(md);
    1755817351        return false;
    1755917352    }
    17560     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key INDEX(det_id, iteration)", 64)) {
     17353    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key", 64)) {
    1756117354        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    1756217355        psFree(md);
     
    1758317376        return false;
    1758417377    }
    17585     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_skewness", PS_DATA_F64, NULL, 0.0)) {
    17586         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_skewness");
    17587         psFree(md);
    17588         return false;
    17589     }
    17590     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_kurtosis", PS_DATA_F64, NULL, 0.0)) {
    17591         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_kurtosis");
    17592         psFree(md);
    17593         return false;
    17594     }
    1759517378    if (!psMetadataAdd(md, PS_LIST_TAIL, "bin_stdev", PS_DATA_F64, NULL, 0.0)) {
    1759617379        psError(PS_ERR_UNKNOWN, false, "failed to add item bin_stdev");
     
    1761317396        return false;
    1761417397    }
    17615     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_0", PS_DATA_F64, NULL, 0.0)) {
    17616         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_0");
    17617         psFree(md);
    17618         return false;
    17619     }
    17620     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_1", PS_DATA_F64, NULL, 0.0)) {
    17621         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_1");
    17622         psFree(md);
    17623         return false;
    17624     }
    17625     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_2", PS_DATA_F64, NULL, 0.0)) {
    17626         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_2");
    17627         psFree(md);
    17628         return false;
    17629     }
    1763017398    if (!psMetadataAdd(md, PS_LIST_TAIL, "user_1", PS_DATA_F64, NULL, 0.0)) {
    1763117399        psError(PS_ERR_UNKNOWN, false, "failed to add item user_1");
     
    1768117449}
    1768217450
    17683 bool detResidExpInsert(psDB * dbh, psS64 det_id, psS32 iteration, psS64 exp_id, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bg_skewness, psF64 bg_kurtosis, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 fringe_resid_0, psF64 fringe_resid_1, psF64 fringe_resid_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, bool accept, psS16 fault)
     17451bool detResidExpInsert(psDB * dbh, psS64 det_id, psS32 iteration, psS64 exp_id, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, bool accept, psS16 fault)
    1768417452{
    1768517453    psMetadata *md = psMetadataAlloc();
     
    1771917487        return false;
    1772017488    }
    17721     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_skewness", PS_DATA_F64, NULL, bg_skewness)) {
    17722         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_skewness");
    17723         psFree(md);
    17724         return false;
    17725     }
    17726     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_kurtosis", PS_DATA_F64, NULL, bg_kurtosis)) {
    17727         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_kurtosis");
    17728         psFree(md);
    17729         return false;
    17730     }
    1773117489    if (!psMetadataAdd(md, PS_LIST_TAIL, "bin_stdev", PS_DATA_F64, NULL, bin_stdev)) {
    1773217490        psError(PS_ERR_UNKNOWN, false, "failed to add item bin_stdev");
     
    1774617504    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_2", PS_DATA_F64, NULL, fringe_2)) {
    1774717505        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_2");
    17748         psFree(md);
    17749         return false;
    17750     }
    17751     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_0", PS_DATA_F64, NULL, fringe_resid_0)) {
    17752         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_0");
    17753         psFree(md);
    17754         return false;
    17755     }
    17756     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_1", PS_DATA_F64, NULL, fringe_resid_1)) {
    17757         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_1");
    17758         psFree(md);
    17759         return false;
    17760     }
    17761     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_2", PS_DATA_F64, NULL, fringe_resid_2)) {
    17762         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_2");
    1776317506        psFree(md);
    1776417507        return false;
     
    1782717570bool detResidExpInsertObject(psDB *dbh, detResidExpRow *object)
    1782817571{
    17829     return detResidExpInsert(dbh, object->det_id, object->iteration, object->exp_id, object->recipe, object->bg, object->bg_stdev, object->bg_mean_stdev, object->bg_skewness, object->bg_kurtosis, object->bin_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->fringe_resid_0, object->fringe_resid_1, object->fringe_resid_2, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->path_base, object->accept, object->fault);
     17572    return detResidExpInsert(dbh, object->det_id, object->iteration, object->exp_id, object->recipe, object->bg, object->bg_stdev, object->bg_mean_stdev, object->bin_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->path_base, object->accept, object->fault);
    1783017573}
    1783117574
     
    1793517678        return false;
    1793617679    }
    17937     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_skewness", PS_DATA_F64, NULL, object->bg_skewness)) {
    17938         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_skewness");
    17939         psFree(md);
    17940         return false;
    17941     }
    17942     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_kurtosis", PS_DATA_F64, NULL, object->bg_kurtosis)) {
    17943         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_kurtosis");
    17944         psFree(md);
    17945         return false;
    17946     }
    1794717680    if (!psMetadataAdd(md, PS_LIST_TAIL, "bin_stdev", PS_DATA_F64, NULL, object->bin_stdev)) {
    1794817681        psError(PS_ERR_UNKNOWN, false, "failed to add item bin_stdev");
     
    1796517698        return false;
    1796617699    }
    17967     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_0", PS_DATA_F64, NULL, object->fringe_resid_0)) {
    17968         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_0");
    17969         psFree(md);
    17970         return false;
    17971     }
    17972     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_1", PS_DATA_F64, NULL, object->fringe_resid_1)) {
    17973         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_1");
    17974         psFree(md);
    17975         return false;
    17976     }
    17977     if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_resid_2", PS_DATA_F64, NULL, object->fringe_resid_2)) {
    17978         psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_resid_2");
    17979         psFree(md);
    17980         return false;
    17981     }
    1798217700    if (!psMetadataAdd(md, PS_LIST_TAIL, "user_1", PS_DATA_F64, NULL, object->user_1)) {
    1798317701        psError(PS_ERR_UNKNOWN, false, "failed to add item user_1");
     
    1806417782        return false;
    1806517783    }
    18066     psF64 bg_skewness = psMetadataLookupF64(&status, md, "bg_skewness");
    18067     if (!status) {
    18068         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bg_skewness");
    18069         return false;
    18070     }
    18071     psF64 bg_kurtosis = psMetadataLookupF64(&status, md, "bg_kurtosis");
    18072     if (!status) {
    18073         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bg_kurtosis");
    18074         return false;
    18075     }
    1807617784    psF64 bin_stdev = psMetadataLookupF64(&status, md, "bin_stdev");
    1807717785    if (!status) {
     
    1809417802        return false;
    1809517803    }
    18096     psF64 fringe_resid_0 = psMetadataLookupF64(&status, md, "fringe_resid_0");
    18097     if (!status) {
    18098         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fringe_resid_0");
    18099         return false;
    18100     }
    18101     psF64 fringe_resid_1 = psMetadataLookupF64(&status, md, "fringe_resid_1");
    18102     if (!status) {
    18103         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fringe_resid_1");
    18104         return false;
    18105     }
    18106     psF64 fringe_resid_2 = psMetadataLookupF64(&status, md, "fringe_resid_2");
    18107     if (!status) {
    18108         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fringe_resid_2");
    18109         return false;
    18110     }
    1811117804    psF64 user_1 = psMetadataLookupF64(&status, md, "user_1");
    1811217805    if (!status) {
     
    1815017843    }
    1815117844
    18152     return detResidExpRowAlloc(det_id, iteration, exp_id, recipe, bg, bg_stdev, bg_mean_stdev, bg_skewness, bg_kurtosis, bin_stdev, fringe_0, fringe_1, fringe_2, fringe_resid_0, fringe_resid_1, fringe_resid_2, user_1, user_2, user_3, user_4, user_5, path_base, accept, fault);
     17845    return detResidExpRowAlloc(det_id, iteration, exp_id, recipe, bg, bg_stdev, bg_mean_stdev, bin_stdev, fringe_0, fringe_1, fringe_2, user_1, user_2, user_3, user_4, user_5, path_base, accept, fault);
    1815317846}
    1815417847psArray *detResidExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    1828717980{
    1828817981    psMetadata *md = psMetadataAlloc();
    18289     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key fkey(det_id, iteration) ref detInputExp(det_id, iteration)", 0)) {
     17982    if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key", 0)) {
    1829017983        psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    1829117984        psFree(md);
    1829217985        return false;
    1829317986    }
    18294     if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key fkey(det_id, iteration) ref detResidExp(det_id, iteration)", 0)) {
     17987    if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key", 0)) {
    1829517988        psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");
    1829617989        psFree(md);
     
    1865918352    return true;
    1866018353}
    18661 static void detRegisteredImfileRowFree(detRegisteredImfileRow *object);
    18662 
    18663 detRegisteredImfileRow *detRegisteredImfileRowAlloc(psS64 det_id, psS32 iteration, const char *class_id, const char *uri, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
    18664 {
    18665     detRegisteredImfileRow *_object;
    18666 
    18667     _object = psAlloc(sizeof(detRegisteredImfileRow));
    18668     psMemSetDeallocator(_object, (psFreeFunc)detRegisteredImfileRowFree);
    18669 
    18670     _object->det_id = det_id;
    18671     _object->iteration = iteration;
    18672     _object->class_id = psStringCopy(class_id);
    18673     _object->uri = psStringCopy(uri);
    18674     _object->bg = bg;
    18675     _object->bg_stdev = bg_stdev;
    18676     _object->bg_mean_stdev = bg_mean_stdev;
    18677     _object->user_1 = user_1;
    18678     _object->user_2 = user_2;
    18679     _object->user_3 = user_3;
    18680     _object->user_4 = user_4;
    18681     _object->user_5 = user_5;
    18682     _object->path_base = psStringCopy(path_base);
    18683     _object->fault = fault;
    18684 
    18685     return _object;
    18686 }
    18687 
    18688 static void detRegisteredImfileRowFree(detRegisteredImfileRow *object)
    18689 {
    18690     psFree(object->class_id);
    18691     psFree(object->uri);
    18692     psFree(object->path_base);
    18693 }
    18694 
    18695 bool detRegisteredImfileCreateTable(psDB *dbh)
    18696 {
    18697     psMetadata *md = psMetadataAlloc();
    18698     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key fkey(det_id, iteration) ref detRun(det_id, iteration)", 0)) {
    18699         psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    18700         psFree(md);
    18701         return false;
    18702     }
    18703     if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, "Primary Key", 0)) {
    18704         psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");
    18705         psFree(md);
    18706         return false;
    18707     }
    18708     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
    18709         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    18710         psFree(md);
    18711         return false;
    18712     }
    18713     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
    18714         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    18715         psFree(md);
    18716         return false;
    18717     }
    18718     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg", PS_DATA_F64, NULL, 0.0)) {
    18719         psError(PS_ERR_UNKNOWN, false, "failed to add item bg");
    18720         psFree(md);
    18721         return false;
    18722     }
    18723     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_stdev", PS_DATA_F64, NULL, 0.0)) {
    18724         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_stdev");
    18725         psFree(md);
    18726         return false;
    18727     }
    18728     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_mean_stdev", PS_DATA_F64, NULL, 0.0)) {
    18729         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev");
    18730         psFree(md);
    18731         return false;
    18732     }
    18733     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_1", PS_DATA_F64, NULL, 0.0)) {
    18734         psError(PS_ERR_UNKNOWN, false, "failed to add item user_1");
    18735         psFree(md);
    18736         return false;
    18737     }
    18738     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_2", PS_DATA_F64, NULL, 0.0)) {
    18739         psError(PS_ERR_UNKNOWN, false, "failed to add item user_2");
    18740         psFree(md);
    18741         return false;
    18742     }
    18743     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_3", PS_DATA_F64, NULL, 0.0)) {
    18744         psError(PS_ERR_UNKNOWN, false, "failed to add item user_3");
    18745         psFree(md);
    18746         return false;
    18747     }
    18748     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_4", PS_DATA_F64, NULL, 0.0)) {
    18749         psError(PS_ERR_UNKNOWN, false, "failed to add item user_4");
    18750         psFree(md);
    18751         return false;
    18752     }
    18753     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_5", PS_DATA_F64, NULL, 0.0)) {
    18754         psError(PS_ERR_UNKNOWN, false, "failed to add item user_5");
    18755         psFree(md);
    18756         return false;
    18757     }
    18758     if (!psMetadataAdd(md, PS_LIST_TAIL, "path_base", PS_DATA_STRING, NULL, "255")) {
    18759         psError(PS_ERR_UNKNOWN, false, "failed to add item path_base");
    18760         psFree(md);
    18761         return false;
    18762     }
    18763     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, "Key NOT NULL", 0)) {
    18764         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    18765         psFree(md);
    18766         return false;
    18767     }
    18768 
    18769     bool status = psDBCreateTable(dbh, DETREGISTEREDIMFILE_TABLE_NAME, md);
    18770 
    18771     psFree(md);
    18772 
    18773     return status;
    18774 }
    18775 
    18776 bool detRegisteredImfileDropTable(psDB *dbh)
    18777 {
    18778     return psDBDropTable(dbh, DETREGISTEREDIMFILE_TABLE_NAME);
    18779 }
    18780 
    18781 bool detRegisteredImfileInsert(psDB * dbh, psS64 det_id, psS32 iteration, const char *class_id, const char *uri, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
    18782 {
    18783     psMetadata *md = psMetadataAlloc();
    18784     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, NULL, det_id)) {
    18785         psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    18786         psFree(md);
    18787         return false;
    18788     }
    18789     if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, NULL, iteration)) {
    18790         psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");
    18791         psFree(md);
    18792         return false;
    18793     }
    18794     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
    18795         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    18796         psFree(md);
    18797         return false;
    18798     }
    18799     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
    18800         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    18801         psFree(md);
    18802         return false;
    18803     }
    18804     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg", PS_DATA_F64, NULL, bg)) {
    18805         psError(PS_ERR_UNKNOWN, false, "failed to add item bg");
    18806         psFree(md);
    18807         return false;
    18808     }
    18809     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_stdev", PS_DATA_F64, NULL, bg_stdev)) {
    18810         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_stdev");
    18811         psFree(md);
    18812         return false;
    18813     }
    18814     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_mean_stdev", PS_DATA_F64, NULL, bg_mean_stdev)) {
    18815         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev");
    18816         psFree(md);
    18817         return false;
    18818     }
    18819     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_1", PS_DATA_F64, NULL, user_1)) {
    18820         psError(PS_ERR_UNKNOWN, false, "failed to add item user_1");
    18821         psFree(md);
    18822         return false;
    18823     }
    18824     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_2", PS_DATA_F64, NULL, user_2)) {
    18825         psError(PS_ERR_UNKNOWN, false, "failed to add item user_2");
    18826         psFree(md);
    18827         return false;
    18828     }
    18829     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_3", PS_DATA_F64, NULL, user_3)) {
    18830         psError(PS_ERR_UNKNOWN, false, "failed to add item user_3");
    18831         psFree(md);
    18832         return false;
    18833     }
    18834     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_4", PS_DATA_F64, NULL, user_4)) {
    18835         psError(PS_ERR_UNKNOWN, false, "failed to add item user_4");
    18836         psFree(md);
    18837         return false;
    18838     }
    18839     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_5", PS_DATA_F64, NULL, user_5)) {
    18840         psError(PS_ERR_UNKNOWN, false, "failed to add item user_5");
    18841         psFree(md);
    18842         return false;
    18843     }
    18844     if (!psMetadataAdd(md, PS_LIST_TAIL, "path_base", PS_DATA_STRING, NULL, path_base)) {
    18845         psError(PS_ERR_UNKNOWN, false, "failed to add item path_base");
    18846         psFree(md);
    18847         return false;
    18848     }
    18849     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, fault)) {
    18850         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    18851         psFree(md);
    18852         return false;
    18853     }
    18854 
    18855     bool status = psDBInsertOneRow(dbh, DETREGISTEREDIMFILE_TABLE_NAME, md);
    18856     psFree(md);
    18857 
    18858     return status;
    18859 }
    18860 
    18861 long long detRegisteredImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    18862 {
    18863     long long       deleted = 0;
    18864 
    18865     long long count = psDBDeleteRows(dbh, DETREGISTEREDIMFILE_TABLE_NAME, where, limit);
    18866     if (count < 0) {
    18867         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detRegisteredImfile");
    18868         return count;
    18869 
    18870         deleted += count;
    18871     }
    18872 
    18873     return deleted;
    18874 }
    18875 bool detRegisteredImfileInsertObject(psDB *dbh, detRegisteredImfileRow *object)
    18876 {
    18877     return detRegisteredImfileInsert(dbh, object->det_id, object->iteration, object->class_id, object->uri, object->bg, object->bg_stdev, object->bg_mean_stdev, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->path_base, object->fault);
    18878 }
    18879 
    18880 bool detRegisteredImfileInsertObjects(psDB *dbh, psArray *objects)
    18881 {
    18882     for (long i = 0; i < psArrayLength(objects); i++) {
    18883         if (!detRegisteredImfileInsertObject(dbh, objects->data[i])) {
    18884             return false;
    18885         }
    18886     }
    18887 
    18888     return true;
    18889 }
    18890 
    18891 bool detRegisteredImfileInsertFits(psDB *dbh, const psFits *fits)
    18892 {
    18893     psArray         *rowSet;
    18894 
    18895     // move to (the first?) extension named  DETREGISTEREDIMFILE_TABLE_NAME
    18896     if (!psFitsMoveExtName(fits, DETREGISTEREDIMFILE_TABLE_NAME)) {
    18897         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", DETREGISTEREDIMFILE_TABLE_NAME);
    18898         return false;
    18899     }
    18900 
    18901     // check HDU type
    18902     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    18903         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    18904         return false;
    18905     }
    18906 
    18907     // read fits table
    18908     rowSet = psFitsReadTable(fits);
    18909     if (!rowSet) {
    18910         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    18911         psFree(rowSet);
    18912         return false;
    18913     }
    18914 
    18915     if (!psDBInsertRows(dbh, DETREGISTEREDIMFILE_TABLE_NAME, rowSet)) {
    18916         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    18917         psFree(rowSet);
    18918         return false;
    18919     }
    18920 
    18921     psFree(rowSet);
    18922 
    18923     return true;
    18924 }
    18925 
    18926 bool detRegisteredImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    18927 {
    18928     psArray         *rowSet;
    18929 
    18930     rowSet = psDBSelectRows(dbh, DETREGISTEREDIMFILE_TABLE_NAME, where, limit);
    18931     if (!rowSet) {
    18932         return false;
    18933     }
    18934 
    18935     // output to fits
    18936     if (!psFitsWriteTable(fits, NULL, rowSet, DETREGISTEREDIMFILE_TABLE_NAME)) {
    18937         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    18938         psFree(rowSet);
    18939         return false;
    18940     }
    18941 
    18942     psFree(rowSet);
    18943 
    18944     return true;
    18945 }
    18946 
    18947 psMetadata *detRegisteredImfileMetadataFromObject(const detRegisteredImfileRow *object)
    18948 {
    18949     psMetadata *md = psMetadataAlloc();
    18950     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, NULL, object->det_id)) {
    18951         psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    18952         psFree(md);
    18953         return false;
    18954     }
    18955     if (!psMetadataAdd(md, PS_LIST_TAIL, "iteration", PS_DATA_S32, NULL, object->iteration)) {
    18956         psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");
    18957         psFree(md);
    18958         return false;
    18959     }
    18960     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) {
    18961         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    18962         psFree(md);
    18963         return false;
    18964     }
    18965     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
    18966         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    18967         psFree(md);
    18968         return false;
    18969     }
    18970     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg", PS_DATA_F64, NULL, object->bg)) {
    18971         psError(PS_ERR_UNKNOWN, false, "failed to add item bg");
    18972         psFree(md);
    18973         return false;
    18974     }
    18975     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_stdev", PS_DATA_F64, NULL, object->bg_stdev)) {
    18976         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_stdev");
    18977         psFree(md);
    18978         return false;
    18979     }
    18980     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_mean_stdev", PS_DATA_F64, NULL, object->bg_mean_stdev)) {
    18981         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev");
    18982         psFree(md);
    18983         return false;
    18984     }
    18985     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_1", PS_DATA_F64, NULL, object->user_1)) {
    18986         psError(PS_ERR_UNKNOWN, false, "failed to add item user_1");
    18987         psFree(md);
    18988         return false;
    18989     }
    18990     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_2", PS_DATA_F64, NULL, object->user_2)) {
    18991         psError(PS_ERR_UNKNOWN, false, "failed to add item user_2");
    18992         psFree(md);
    18993         return false;
    18994     }
    18995     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_3", PS_DATA_F64, NULL, object->user_3)) {
    18996         psError(PS_ERR_UNKNOWN, false, "failed to add item user_3");
    18997         psFree(md);
    18998         return false;
    18999     }
    19000     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_4", PS_DATA_F64, NULL, object->user_4)) {
    19001         psError(PS_ERR_UNKNOWN, false, "failed to add item user_4");
    19002         psFree(md);
    19003         return false;
    19004     }
    19005     if (!psMetadataAdd(md, PS_LIST_TAIL, "user_5", PS_DATA_F64, NULL, object->user_5)) {
    19006         psError(PS_ERR_UNKNOWN, false, "failed to add item user_5");
    19007         psFree(md);
    19008         return false;
    19009     }
    19010     if (!psMetadataAdd(md, PS_LIST_TAIL, "path_base", PS_DATA_STRING, NULL, object->path_base)) {
    19011         psError(PS_ERR_UNKNOWN, false, "failed to add item path_base");
    19012         psFree(md);
    19013         return false;
    19014     }
    19015     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, object->fault)) {
    19016         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    19017         psFree(md);
    19018         return false;
    19019     }
    19020 
    19021 
    19022     return md;
    19023 }
    19024 
    19025 detRegisteredImfileRow *detRegisteredImfileObjectFromMetadata(psMetadata *md)
    19026 {
    19027 
    19028 bool status = false;
    19029     psS64 det_id = psMetadataLookupS64(&status, md, "det_id");
    19030     if (!status) {
    19031         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item det_id");
    19032         return false;
    19033     }
    19034     psS32 iteration = psMetadataLookupS32(&status, md, "iteration");
    19035     if (!status) {
    19036         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item iteration");
    19037         return false;
    19038     }
    19039     char* class_id = psMetadataLookupPtr(&status, md, "class_id");
    19040     if (!status) {
    19041         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id");
    19042         return false;
    19043     }
    19044     char* uri = psMetadataLookupPtr(&status, md, "uri");
    19045     if (!status) {
    19046         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
    19047         return false;
    19048     }
    19049     psF64 bg = psMetadataLookupF64(&status, md, "bg");
    19050     if (!status) {
    19051         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bg");
    19052         return false;
    19053     }
    19054     psF64 bg_stdev = psMetadataLookupF64(&status, md, "bg_stdev");
    19055     if (!status) {
    19056         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bg_stdev");
    19057         return false;
    19058     }
    19059     psF64 bg_mean_stdev = psMetadataLookupF64(&status, md, "bg_mean_stdev");
    19060     if (!status) {
    19061         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bg_mean_stdev");
    19062         return false;
    19063     }
    19064     psF64 user_1 = psMetadataLookupF64(&status, md, "user_1");
    19065     if (!status) {
    19066         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item user_1");
    19067         return false;
    19068     }
    19069     psF64 user_2 = psMetadataLookupF64(&status, md, "user_2");
    19070     if (!status) {
    19071         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item user_2");
    19072         return false;
    19073     }
    19074     psF64 user_3 = psMetadataLookupF64(&status, md, "user_3");
    19075     if (!status) {
    19076         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item user_3");
    19077         return false;
    19078     }
    19079     psF64 user_4 = psMetadataLookupF64(&status, md, "user_4");
    19080     if (!status) {
    19081         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item user_4");
    19082         return false;
    19083     }
    19084     psF64 user_5 = psMetadataLookupF64(&status, md, "user_5");
    19085     if (!status) {
    19086         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item user_5");
    19087         return false;
    19088     }
    19089     char* path_base = psMetadataLookupPtr(&status, md, "path_base");
    19090     if (!status) {
    19091         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item path_base");
    19092         return false;
    19093     }
    19094     psS16 fault = psMetadataLookupS16(&status, md, "fault");
    19095     if (!status) {
    19096         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fault");
    19097         return false;
    19098     }
    19099 
    19100     return detRegisteredImfileRowAlloc(det_id, iteration, class_id, uri, bg, bg_stdev, bg_mean_stdev, user_1, user_2, user_3, user_4, user_5, path_base, fault);
    19101 }
    19102 psArray *detRegisteredImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    19103 {
    19104     psArray         *rowSet;
    19105     psArray         *returnSet;
    19106     psU64           i;
    19107 
    19108     rowSet = psDBSelectRows(dbh, DETREGISTEREDIMFILE_TABLE_NAME, where, limit);
    19109     if (!rowSet) {
    19110         return NULL;
    19111     }
    19112 
    19113     // convert psMetadata rows to row objects
    19114 
    19115     returnSet = psArrayAllocEmpty(rowSet->n);
    19116 
    19117     for (i = 0; i < rowSet->n; i++) {
    19118         detRegisteredImfileRow *object = detRegisteredImfileObjectFromMetadata(rowSet->data[i]);
    19119         psArrayAdd(returnSet, 0, object);
    19120         psFree(object);
    19121     }
    19122 
    19123     psFree(rowSet);
    19124 
    19125     return returnSet;
    19126 }
    19127 bool detRegisteredImfileDeleteObject(psDB *dbh, const detRegisteredImfileRow *object)
    19128 {
    19129     psMetadata *where = detRegisteredImfileMetadataFromObject(object);
    19130     long long count = psDBDeleteRows(dbh, DETREGISTEREDIMFILE_TABLE_NAME, where, 0);
    19131     psFree(where);
    19132     if (count < 0) {
    19133         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detRegisteredImfile");
    19134         return false;
    19135     }
    19136     if (count > 1) {
    19137         // XXX should this be a psAbort() instead?  It is possible that
    19138         // having an object match multiple rows was by design.
    19139         psError(PS_ERR_UNKNOWN, true, "detRegisteredImfileRow object matched more then one row.  Check your database schema");
    19140         return false;
    19141     }
    19142 
    19143     return true;
    19144 }
    19145 long long detRegisteredImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    19146 {
    19147     long long       deleted = 0;
    19148 
    19149     for (long long i = 0; i < objects->n; i++) {
    19150         detRegisteredImfileRow *object = objects->data[i];
    19151         psMetadata *where = detRegisteredImfileMetadataFromObject(object);
    19152         long long count = psDBDeleteRows(dbh, DETREGISTEREDIMFILE_TABLE_NAME, where, limit);
    19153         psFree(where);
    19154         if (count < 0) {
    19155             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detRegisteredImfile");
    19156             return count;
    19157         }
    19158 
    19159         deleted += count;
    19160     }
    19161 
    19162     return deleted;
    19163 }
    19164 bool detRegisteredImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
    19165 {
    19166     PS_ASSERT_PTR_NON_NULL(objects, false);
    19167 
    19168     psMetadata *output = psMetadataAlloc();
    19169     for (long i = 0; i < psArrayLength(objects); i++) {
    19170         psMetadata *md = detRegisteredImfileMetadataFromObject(objects->data[i]);
    19171         if (!psMetadataAddMetadata(
    19172             output,
    19173             PS_LIST_TAIL,
    19174             DETREGISTEREDIMFILE_TABLE_NAME,
    19175             PS_META_DUPLICATE_OK,
    19176             NULL,
    19177             md
    19178         )) {
    19179             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    19180             psFree(md);
    19181             psFree(output);
    19182             return false;
    19183         }
    19184         psFree(md);
    19185     }
    19186 
    19187     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    19188         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    19189         psFree(output);
    19190     }
    19191     psFree(output);
    19192 
    19193     return true;
    19194 }
    19195 bool detRegisteredImfilePrintObject(FILE *stream, detRegisteredImfileRow *object, bool mdcf)
    19196 {
    19197     PS_ASSERT_PTR_NON_NULL(object, false);
    19198 
    19199     psMetadata *md = detRegisteredImfileMetadataFromObject(object);
    19200 
    19201     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    19202         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    19203         psFree(md);
    19204     }
    19205 
    19206     psFree(md);
    19207 
    19208     return true;
    19209 }
    19210 static void detCorrectedExpRowFree(detCorrectedExpRow *object);
    19211 
    19212 detCorrectedExpRow *detCorrectedExpRowAlloc(psS64 det_id, psS64 exp_id, const char *uri, psS64 corr_id, const char *corr_type, const char *recipe, const char *path_base, psS16 fault)
    19213 {
    19214     detCorrectedExpRow *_object;
    19215 
    19216     _object = psAlloc(sizeof(detCorrectedExpRow));
    19217     psMemSetDeallocator(_object, (psFreeFunc)detCorrectedExpRowFree);
    19218 
    19219     _object->det_id = det_id;
    19220     _object->exp_id = exp_id;
    19221     _object->uri = psStringCopy(uri);
    19222     _object->corr_id = corr_id;
    19223     _object->corr_type = psStringCopy(corr_type);
    19224     _object->recipe = psStringCopy(recipe);
    19225     _object->path_base = psStringCopy(path_base);
    19226     _object->fault = fault;
    19227 
    19228     return _object;
    19229 }
    19230 
    19231 static void detCorrectedExpRowFree(detCorrectedExpRow *object)
    19232 {
    19233     psFree(object->uri);
    19234     psFree(object->corr_type);
    19235     psFree(object->recipe);
    19236     psFree(object->path_base);
    19237 }
    19238 
    19239 bool detCorrectedExpCreateTable(psDB *dbh)
    19240 {
    19241     psMetadata *md = psMetadataAlloc();
    19242     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key fkey(det_id, exp_id) ref detInputExp(det_id, exp_id)", 0)) {
    19243         psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    19244         psFree(md);
    19245         return false;
    19246     }
    19247     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key fkey(exp_id, class_id) ref rawImfile(exp_id, class_id)", 64)) {
    19248         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    19249         psFree(md);
    19250         return false;
    19251     }
    19252     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, "INDEX(det_id, exp_id)", "255")) {
    19253         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    19254         psFree(md);
    19255         return false;
    19256     }
    19257     if (!psMetadataAdd(md, PS_LIST_TAIL, "corr_id", PS_DATA_S64, NULL, 0)) {
    19258         psError(PS_ERR_UNKNOWN, false, "failed to add item corr_id");
    19259         psFree(md);
    19260         return false;
    19261     }
    19262     if (!psMetadataAdd(md, PS_LIST_TAIL, "corr_type", PS_DATA_STRING, NULL, "64")) {
    19263         psError(PS_ERR_UNKNOWN, false, "failed to add item corr_type");
    19264         psFree(md);
    19265         return false;
    19266     }
    19267     if (!psMetadataAdd(md, PS_LIST_TAIL, "recipe", PS_DATA_STRING, NULL, "64")) {
    19268         psError(PS_ERR_UNKNOWN, false, "failed to add item recipe");
    19269         psFree(md);
    19270         return false;
    19271     }
    19272     if (!psMetadataAdd(md, PS_LIST_TAIL, "path_base", PS_DATA_STRING, NULL, "255")) {
    19273         psError(PS_ERR_UNKNOWN, false, "failed to add item path_base");
    19274         psFree(md);
    19275         return false;
    19276     }
    19277     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, "Key NOT NULL", 0)) {
    19278         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    19279         psFree(md);
    19280         return false;
    19281     }
    19282 
    19283     bool status = psDBCreateTable(dbh, DETCORRECTEDEXP_TABLE_NAME, md);
    19284 
    19285     psFree(md);
    19286 
    19287     return status;
    19288 }
    19289 
    19290 bool detCorrectedExpDropTable(psDB *dbh)
    19291 {
    19292     return psDBDropTable(dbh, DETCORRECTEDEXP_TABLE_NAME);
    19293 }
    19294 
    19295 bool detCorrectedExpInsert(psDB * dbh, psS64 det_id, psS64 exp_id, const char *uri, psS64 corr_id, const char *corr_type, const char *recipe, const char *path_base, psS16 fault)
    19296 {
    19297     psMetadata *md = psMetadataAlloc();
    19298     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, NULL, det_id)) {
    19299         psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    19300         psFree(md);
    19301         return false;
    19302     }
    19303     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
    19304         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    19305         psFree(md);
    19306         return false;
    19307     }
    19308     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
    19309         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    19310         psFree(md);
    19311         return false;
    19312     }
    19313     if (!psMetadataAdd(md, PS_LIST_TAIL, "corr_id", PS_DATA_S64, NULL, corr_id)) {
    19314         psError(PS_ERR_UNKNOWN, false, "failed to add item corr_id");
    19315         psFree(md);
    19316         return false;
    19317     }
    19318     if (!psMetadataAdd(md, PS_LIST_TAIL, "corr_type", PS_DATA_STRING, NULL, corr_type)) {
    19319         psError(PS_ERR_UNKNOWN, false, "failed to add item corr_type");
    19320         psFree(md);
    19321         return false;
    19322     }
    19323     if (!psMetadataAdd(md, PS_LIST_TAIL, "recipe", PS_DATA_STRING, NULL, recipe)) {
    19324         psError(PS_ERR_UNKNOWN, false, "failed to add item recipe");
    19325         psFree(md);
    19326         return false;
    19327     }
    19328     if (!psMetadataAdd(md, PS_LIST_TAIL, "path_base", PS_DATA_STRING, NULL, path_base)) {
    19329         psError(PS_ERR_UNKNOWN, false, "failed to add item path_base");
    19330         psFree(md);
    19331         return false;
    19332     }
    19333     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, fault)) {
    19334         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    19335         psFree(md);
    19336         return false;
    19337     }
    19338 
    19339     bool status = psDBInsertOneRow(dbh, DETCORRECTEDEXP_TABLE_NAME, md);
    19340     psFree(md);
    19341 
    19342     return status;
    19343 }
    19344 
    19345 long long detCorrectedExpDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    19346 {
    19347     long long       deleted = 0;
    19348 
    19349     long long count = psDBDeleteRows(dbh, DETCORRECTEDEXP_TABLE_NAME, where, limit);
    19350     if (count < 0) {
    19351         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detCorrectedExp");
    19352         return count;
    19353 
    19354         deleted += count;
    19355     }
    19356 
    19357     return deleted;
    19358 }
    19359 bool detCorrectedExpInsertObject(psDB *dbh, detCorrectedExpRow *object)
    19360 {
    19361     return detCorrectedExpInsert(dbh, object->det_id, object->exp_id, object->uri, object->corr_id, object->corr_type, object->recipe, object->path_base, object->fault);
    19362 }
    19363 
    19364 bool detCorrectedExpInsertObjects(psDB *dbh, psArray *objects)
    19365 {
    19366     for (long i = 0; i < psArrayLength(objects); i++) {
    19367         if (!detCorrectedExpInsertObject(dbh, objects->data[i])) {
    19368             return false;
    19369         }
    19370     }
    19371 
    19372     return true;
    19373 }
    19374 
    19375 bool detCorrectedExpInsertFits(psDB *dbh, const psFits *fits)
    19376 {
    19377     psArray         *rowSet;
    19378 
    19379     // move to (the first?) extension named  DETCORRECTEDEXP_TABLE_NAME
    19380     if (!psFitsMoveExtName(fits, DETCORRECTEDEXP_TABLE_NAME)) {
    19381         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", DETCORRECTEDEXP_TABLE_NAME);
    19382         return false;
    19383     }
    19384 
    19385     // check HDU type
    19386     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    19387         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    19388         return false;
    19389     }
    19390 
    19391     // read fits table
    19392     rowSet = psFitsReadTable(fits);
    19393     if (!rowSet) {
    19394         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    19395         psFree(rowSet);
    19396         return false;
    19397     }
    19398 
    19399     if (!psDBInsertRows(dbh, DETCORRECTEDEXP_TABLE_NAME, rowSet)) {
    19400         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    19401         psFree(rowSet);
    19402         return false;
    19403     }
    19404 
    19405     psFree(rowSet);
    19406 
    19407     return true;
    19408 }
    19409 
    19410 bool detCorrectedExpSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    19411 {
    19412     psArray         *rowSet;
    19413 
    19414     rowSet = psDBSelectRows(dbh, DETCORRECTEDEXP_TABLE_NAME, where, limit);
    19415     if (!rowSet) {
    19416         return false;
    19417     }
    19418 
    19419     // output to fits
    19420     if (!psFitsWriteTable(fits, NULL, rowSet, DETCORRECTEDEXP_TABLE_NAME)) {
    19421         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    19422         psFree(rowSet);
    19423         return false;
    19424     }
    19425 
    19426     psFree(rowSet);
    19427 
    19428     return true;
    19429 }
    19430 
    19431 psMetadata *detCorrectedExpMetadataFromObject(const detCorrectedExpRow *object)
    19432 {
    19433     psMetadata *md = psMetadataAlloc();
    19434     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, NULL, object->det_id)) {
    19435         psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    19436         psFree(md);
    19437         return false;
    19438     }
    19439     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
    19440         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    19441         psFree(md);
    19442         return false;
    19443     }
    19444     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
    19445         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    19446         psFree(md);
    19447         return false;
    19448     }
    19449     if (!psMetadataAdd(md, PS_LIST_TAIL, "corr_id", PS_DATA_S64, NULL, object->corr_id)) {
    19450         psError(PS_ERR_UNKNOWN, false, "failed to add item corr_id");
    19451         psFree(md);
    19452         return false;
    19453     }
    19454     if (!psMetadataAdd(md, PS_LIST_TAIL, "corr_type", PS_DATA_STRING, NULL, object->corr_type)) {
    19455         psError(PS_ERR_UNKNOWN, false, "failed to add item corr_type");
    19456         psFree(md);
    19457         return false;
    19458     }
    19459     if (!psMetadataAdd(md, PS_LIST_TAIL, "recipe", PS_DATA_STRING, NULL, object->recipe)) {
    19460         psError(PS_ERR_UNKNOWN, false, "failed to add item recipe");
    19461         psFree(md);
    19462         return false;
    19463     }
    19464     if (!psMetadataAdd(md, PS_LIST_TAIL, "path_base", PS_DATA_STRING, NULL, object->path_base)) {
    19465         psError(PS_ERR_UNKNOWN, false, "failed to add item path_base");
    19466         psFree(md);
    19467         return false;
    19468     }
    19469     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, object->fault)) {
    19470         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    19471         psFree(md);
    19472         return false;
    19473     }
    19474 
    19475 
    19476     return md;
    19477 }
    19478 
    19479 detCorrectedExpRow *detCorrectedExpObjectFromMetadata(psMetadata *md)
    19480 {
    19481 
    19482 bool status = false;
    19483     psS64 det_id = psMetadataLookupS64(&status, md, "det_id");
    19484     if (!status) {
    19485         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item det_id");
    19486         return false;
    19487     }
    19488     psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
    19489     if (!status) {
    19490         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
    19491         return false;
    19492     }
    19493     char* uri = psMetadataLookupPtr(&status, md, "uri");
    19494     if (!status) {
    19495         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
    19496         return false;
    19497     }
    19498     psS64 corr_id = psMetadataLookupS64(&status, md, "corr_id");
    19499     if (!status) {
    19500         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item corr_id");
    19501         return false;
    19502     }
    19503     char* corr_type = psMetadataLookupPtr(&status, md, "corr_type");
    19504     if (!status) {
    19505         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item corr_type");
    19506         return false;
    19507     }
    19508     char* recipe = psMetadataLookupPtr(&status, md, "recipe");
    19509     if (!status) {
    19510         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item recipe");
    19511         return false;
    19512     }
    19513     char* path_base = psMetadataLookupPtr(&status, md, "path_base");
    19514     if (!status) {
    19515         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item path_base");
    19516         return false;
    19517     }
    19518     psS16 fault = psMetadataLookupS16(&status, md, "fault");
    19519     if (!status) {
    19520         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fault");
    19521         return false;
    19522     }
    19523 
    19524     return detCorrectedExpRowAlloc(det_id, exp_id, uri, corr_id, corr_type, recipe, path_base, fault);
    19525 }
    19526 psArray *detCorrectedExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    19527 {
    19528     psArray         *rowSet;
    19529     psArray         *returnSet;
    19530     psU64           i;
    19531 
    19532     rowSet = psDBSelectRows(dbh, DETCORRECTEDEXP_TABLE_NAME, where, limit);
    19533     if (!rowSet) {
    19534         return NULL;
    19535     }
    19536 
    19537     // convert psMetadata rows to row objects
    19538 
    19539     returnSet = psArrayAllocEmpty(rowSet->n);
    19540 
    19541     for (i = 0; i < rowSet->n; i++) {
    19542         detCorrectedExpRow *object = detCorrectedExpObjectFromMetadata(rowSet->data[i]);
    19543         psArrayAdd(returnSet, 0, object);
    19544         psFree(object);
    19545     }
    19546 
    19547     psFree(rowSet);
    19548 
    19549     return returnSet;
    19550 }
    19551 bool detCorrectedExpDeleteObject(psDB *dbh, const detCorrectedExpRow *object)
    19552 {
    19553     psMetadata *where = detCorrectedExpMetadataFromObject(object);
    19554     long long count = psDBDeleteRows(dbh, DETCORRECTEDEXP_TABLE_NAME, where, 0);
    19555     psFree(where);
    19556     if (count < 0) {
    19557         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detCorrectedExp");
    19558         return false;
    19559     }
    19560     if (count > 1) {
    19561         // XXX should this be a psAbort() instead?  It is possible that
    19562         // having an object match multiple rows was by design.
    19563         psError(PS_ERR_UNKNOWN, true, "detCorrectedExpRow object matched more then one row.  Check your database schema");
    19564         return false;
    19565     }
    19566 
    19567     return true;
    19568 }
    19569 long long detCorrectedExpDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    19570 {
    19571     long long       deleted = 0;
    19572 
    19573     for (long long i = 0; i < objects->n; i++) {
    19574         detCorrectedExpRow *object = objects->data[i];
    19575         psMetadata *where = detCorrectedExpMetadataFromObject(object);
    19576         long long count = psDBDeleteRows(dbh, DETCORRECTEDEXP_TABLE_NAME, where, limit);
    19577         psFree(where);
    19578         if (count < 0) {
    19579             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detCorrectedExp");
    19580             return count;
    19581         }
    19582 
    19583         deleted += count;
    19584     }
    19585 
    19586     return deleted;
    19587 }
    19588 bool detCorrectedExpPrintObjects(FILE *stream, psArray *objects, bool mdcf)
    19589 {
    19590     PS_ASSERT_PTR_NON_NULL(objects, false);
    19591 
    19592     psMetadata *output = psMetadataAlloc();
    19593     for (long i = 0; i < psArrayLength(objects); i++) {
    19594         psMetadata *md = detCorrectedExpMetadataFromObject(objects->data[i]);
    19595         if (!psMetadataAddMetadata(
    19596             output,
    19597             PS_LIST_TAIL,
    19598             DETCORRECTEDEXP_TABLE_NAME,
    19599             PS_META_DUPLICATE_OK,
    19600             NULL,
    19601             md
    19602         )) {
    19603             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    19604             psFree(md);
    19605             psFree(output);
    19606             return false;
    19607         }
    19608         psFree(md);
    19609     }
    19610 
    19611     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    19612         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    19613         psFree(output);
    19614     }
    19615     psFree(output);
    19616 
    19617     return true;
    19618 }
    19619 bool detCorrectedExpPrintObject(FILE *stream, detCorrectedExpRow *object, bool mdcf)
    19620 {
    19621     PS_ASSERT_PTR_NON_NULL(object, false);
    19622 
    19623     psMetadata *md = detCorrectedExpMetadataFromObject(object);
    19624 
    19625     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    19626         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    19627         psFree(md);
    19628     }
    19629 
    19630     psFree(md);
    19631 
    19632     return true;
    19633 }
    19634 static void detCorrectedImfileRowFree(detCorrectedImfileRow *object);
    19635 
    19636 detCorrectedImfileRow *detCorrectedImfileRowAlloc(psS64 det_id, psS64 exp_id, const char *class_id, const char *uri, const char *path_base, psS16 fault)
    19637 {
    19638     detCorrectedImfileRow *_object;
    19639 
    19640     _object = psAlloc(sizeof(detCorrectedImfileRow));
    19641     psMemSetDeallocator(_object, (psFreeFunc)detCorrectedImfileRowFree);
    19642 
    19643     _object->det_id = det_id;
    19644     _object->exp_id = exp_id;
    19645     _object->class_id = psStringCopy(class_id);
    19646     _object->uri = psStringCopy(uri);
    19647     _object->path_base = psStringCopy(path_base);
    19648     _object->fault = fault;
    19649 
    19650     return _object;
    19651 }
    19652 
    19653 static void detCorrectedImfileRowFree(detCorrectedImfileRow *object)
    19654 {
    19655     psFree(object->class_id);
    19656     psFree(object->uri);
    19657     psFree(object->path_base);
    19658 }
    19659 
    19660 bool detCorrectedImfileCreateTable(psDB *dbh)
    19661 {
    19662     psMetadata *md = psMetadataAlloc();
    19663     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, "Primary Key fkey(det_id, exp_id) ref detInputExp(det_id, exp_id)", 0)) {
    19664         psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    19665         psFree(md);
    19666         return false;
    19667     }
    19668     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key fkey(exp_id, class_id) ref rawImfile(exp_id, class_id)", 64)) {
    19669         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    19670         psFree(md);
    19671         return false;
    19672     }
    19673     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key INDEX(det_id, class_id)", "64")) {
    19674         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    19675         psFree(md);
    19676         return false;
    19677     }
    19678     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, "INDEX(det_id, exp_id)", "255")) {
    19679         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    19680         psFree(md);
    19681         return false;
    19682     }
    19683     if (!psMetadataAdd(md, PS_LIST_TAIL, "path_base", PS_DATA_STRING, NULL, "255")) {
    19684         psError(PS_ERR_UNKNOWN, false, "failed to add item path_base");
    19685         psFree(md);
    19686         return false;
    19687     }
    19688     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, "Key NOT NULL", 0)) {
    19689         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    19690         psFree(md);
    19691         return false;
    19692     }
    19693 
    19694     bool status = psDBCreateTable(dbh, DETCORRECTEDIMFILE_TABLE_NAME, md);
    19695 
    19696     psFree(md);
    19697 
    19698     return status;
    19699 }
    19700 
    19701 bool detCorrectedImfileDropTable(psDB *dbh)
    19702 {
    19703     return psDBDropTable(dbh, DETCORRECTEDIMFILE_TABLE_NAME);
    19704 }
    19705 
    19706 bool detCorrectedImfileInsert(psDB * dbh, psS64 det_id, psS64 exp_id, const char *class_id, const char *uri, const char *path_base, psS16 fault)
    19707 {
    19708     psMetadata *md = psMetadataAlloc();
    19709     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, NULL, det_id)) {
    19710         psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    19711         psFree(md);
    19712         return false;
    19713     }
    19714     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
    19715         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    19716         psFree(md);
    19717         return false;
    19718     }
    19719     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
    19720         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    19721         psFree(md);
    19722         return false;
    19723     }
    19724     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
    19725         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    19726         psFree(md);
    19727         return false;
    19728     }
    19729     if (!psMetadataAdd(md, PS_LIST_TAIL, "path_base", PS_DATA_STRING, NULL, path_base)) {
    19730         psError(PS_ERR_UNKNOWN, false, "failed to add item path_base");
    19731         psFree(md);
    19732         return false;
    19733     }
    19734     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, fault)) {
    19735         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    19736         psFree(md);
    19737         return false;
    19738     }
    19739 
    19740     bool status = psDBInsertOneRow(dbh, DETCORRECTEDIMFILE_TABLE_NAME, md);
    19741     psFree(md);
    19742 
    19743     return status;
    19744 }
    19745 
    19746 long long detCorrectedImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    19747 {
    19748     long long       deleted = 0;
    19749 
    19750     long long count = psDBDeleteRows(dbh, DETCORRECTEDIMFILE_TABLE_NAME, where, limit);
    19751     if (count < 0) {
    19752         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detCorrectedImfile");
    19753         return count;
    19754 
    19755         deleted += count;
    19756     }
    19757 
    19758     return deleted;
    19759 }
    19760 bool detCorrectedImfileInsertObject(psDB *dbh, detCorrectedImfileRow *object)
    19761 {
    19762     return detCorrectedImfileInsert(dbh, object->det_id, object->exp_id, object->class_id, object->uri, object->path_base, object->fault);
    19763 }
    19764 
    19765 bool detCorrectedImfileInsertObjects(psDB *dbh, psArray *objects)
    19766 {
    19767     for (long i = 0; i < psArrayLength(objects); i++) {
    19768         if (!detCorrectedImfileInsertObject(dbh, objects->data[i])) {
    19769             return false;
    19770         }
    19771     }
    19772 
    19773     return true;
    19774 }
    19775 
    19776 bool detCorrectedImfileInsertFits(psDB *dbh, const psFits *fits)
    19777 {
    19778     psArray         *rowSet;
    19779 
    19780     // move to (the first?) extension named  DETCORRECTEDIMFILE_TABLE_NAME
    19781     if (!psFitsMoveExtName(fits, DETCORRECTEDIMFILE_TABLE_NAME)) {
    19782         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", DETCORRECTEDIMFILE_TABLE_NAME);
    19783         return false;
    19784     }
    19785 
    19786     // check HDU type
    19787     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    19788         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    19789         return false;
    19790     }
    19791 
    19792     // read fits table
    19793     rowSet = psFitsReadTable(fits);
    19794     if (!rowSet) {
    19795         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    19796         psFree(rowSet);
    19797         return false;
    19798     }
    19799 
    19800     if (!psDBInsertRows(dbh, DETCORRECTEDIMFILE_TABLE_NAME, rowSet)) {
    19801         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    19802         psFree(rowSet);
    19803         return false;
    19804     }
    19805 
    19806     psFree(rowSet);
    19807 
    19808     return true;
    19809 }
    19810 
    19811 bool detCorrectedImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    19812 {
    19813     psArray         *rowSet;
    19814 
    19815     rowSet = psDBSelectRows(dbh, DETCORRECTEDIMFILE_TABLE_NAME, where, limit);
    19816     if (!rowSet) {
    19817         return false;
    19818     }
    19819 
    19820     // output to fits
    19821     if (!psFitsWriteTable(fits, NULL, rowSet, DETCORRECTEDIMFILE_TABLE_NAME)) {
    19822         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    19823         psFree(rowSet);
    19824         return false;
    19825     }
    19826 
    19827     psFree(rowSet);
    19828 
    19829     return true;
    19830 }
    19831 
    19832 psMetadata *detCorrectedImfileMetadataFromObject(const detCorrectedImfileRow *object)
    19833 {
    19834     psMetadata *md = psMetadataAlloc();
    19835     if (!psMetadataAdd(md, PS_LIST_TAIL, "det_id", PS_DATA_S64, NULL, object->det_id)) {
    19836         psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");
    19837         psFree(md);
    19838         return false;
    19839     }
    19840     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
    19841         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
    19842         psFree(md);
    19843         return false;
    19844     }
    19845     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) {
    19846         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    19847         psFree(md);
    19848         return false;
    19849     }
    19850     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
    19851         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    19852         psFree(md);
    19853         return false;
    19854     }
    19855     if (!psMetadataAdd(md, PS_LIST_TAIL, "path_base", PS_DATA_STRING, NULL, object->path_base)) {
    19856         psError(PS_ERR_UNKNOWN, false, "failed to add item path_base");
    19857         psFree(md);
    19858         return false;
    19859     }
    19860     if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, object->fault)) {
    19861         psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
    19862         psFree(md);
    19863         return false;
    19864     }
    19865 
    19866 
    19867     return md;
    19868 }
    19869 
    19870 detCorrectedImfileRow *detCorrectedImfileObjectFromMetadata(psMetadata *md)
    19871 {
    19872 
    19873 bool status = false;
    19874     psS64 det_id = psMetadataLookupS64(&status, md, "det_id");
    19875     if (!status) {
    19876         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item det_id");
    19877         return false;
    19878     }
    19879     psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
    19880     if (!status) {
    19881         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
    19882         return false;
    19883     }
    19884     char* class_id = psMetadataLookupPtr(&status, md, "class_id");
    19885     if (!status) {
    19886         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id");
    19887         return false;
    19888     }
    19889     char* uri = psMetadataLookupPtr(&status, md, "uri");
    19890     if (!status) {
    19891         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
    19892         return false;
    19893     }
    19894     char* path_base = psMetadataLookupPtr(&status, md, "path_base");
    19895     if (!status) {
    19896         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item path_base");
    19897         return false;
    19898     }
    19899     psS16 fault = psMetadataLookupS16(&status, md, "fault");
    19900     if (!status) {
    19901         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fault");
    19902         return false;
    19903     }
    19904 
    19905     return detCorrectedImfileRowAlloc(det_id, exp_id, class_id, uri, path_base, fault);
    19906 }
    19907 psArray *detCorrectedImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    19908 {
    19909     psArray         *rowSet;
    19910     psArray         *returnSet;
    19911     psU64           i;
    19912 
    19913     rowSet = psDBSelectRows(dbh, DETCORRECTEDIMFILE_TABLE_NAME, where, limit);
    19914     if (!rowSet) {
    19915         return NULL;
    19916     }
    19917 
    19918     // convert psMetadata rows to row objects
    19919 
    19920     returnSet = psArrayAllocEmpty(rowSet->n);
    19921 
    19922     for (i = 0; i < rowSet->n; i++) {
    19923         detCorrectedImfileRow *object = detCorrectedImfileObjectFromMetadata(rowSet->data[i]);
    19924         psArrayAdd(returnSet, 0, object);
    19925         psFree(object);
    19926     }
    19927 
    19928     psFree(rowSet);
    19929 
    19930     return returnSet;
    19931 }
    19932 bool detCorrectedImfileDeleteObject(psDB *dbh, const detCorrectedImfileRow *object)
    19933 {
    19934     psMetadata *where = detCorrectedImfileMetadataFromObject(object);
    19935     long long count = psDBDeleteRows(dbh, DETCORRECTEDIMFILE_TABLE_NAME, where, 0);
    19936     psFree(where);
    19937     if (count < 0) {
    19938         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detCorrectedImfile");
    19939         return false;
    19940     }
    19941     if (count > 1) {
    19942         // XXX should this be a psAbort() instead?  It is possible that
    19943         // having an object match multiple rows was by design.
    19944         psError(PS_ERR_UNKNOWN, true, "detCorrectedImfileRow object matched more then one row.  Check your database schema");
    19945         return false;
    19946     }
    19947 
    19948     return true;
    19949 }
    19950 long long detCorrectedImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    19951 {
    19952     long long       deleted = 0;
    19953 
    19954     for (long long i = 0; i < objects->n; i++) {
    19955         detCorrectedImfileRow *object = objects->data[i];
    19956         psMetadata *where = detCorrectedImfileMetadataFromObject(object);
    19957         long long count = psDBDeleteRows(dbh, DETCORRECTEDIMFILE_TABLE_NAME, where, limit);
    19958         psFree(where);
    19959         if (count < 0) {
    19960             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detCorrectedImfile");
    19961             return count;
    19962         }
    19963 
    19964         deleted += count;
    19965     }
    19966 
    19967     return deleted;
    19968 }
    19969 bool detCorrectedImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
    19970 {
    19971     PS_ASSERT_PTR_NON_NULL(objects, false);
    19972 
    19973     psMetadata *output = psMetadataAlloc();
    19974     for (long i = 0; i < psArrayLength(objects); i++) {
    19975         psMetadata *md = detCorrectedImfileMetadataFromObject(objects->data[i]);
    19976         if (!psMetadataAddMetadata(
    19977             output,
    19978             PS_LIST_TAIL,
    19979             DETCORRECTEDIMFILE_TABLE_NAME,
    19980             PS_META_DUPLICATE_OK,
    19981             NULL,
    19982             md
    19983         )) {
    19984             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    19985             psFree(md);
    19986             psFree(output);
    19987             return false;
    19988         }
    19989         psFree(md);
    19990     }
    19991 
    19992     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    19993         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    19994         psFree(output);
    19995     }
    19996     psFree(output);
    19997 
    19998     return true;
    19999 }
    20000 bool detCorrectedImfilePrintObject(FILE *stream, detCorrectedImfileRow *object, bool mdcf)
    20001 {
    20002     PS_ASSERT_PTR_NON_NULL(object, false);
    20003 
    20004     psMetadata *md = detCorrectedImfileMetadataFromObject(object);
    20005 
    20006     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    20007         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    20008         psFree(md);
    20009     }
    20010 
    20011     psFree(md);
    20012 
    20013     return true;
    20014 }
    20015 static void magicRunRowFree(magicRunRow *object);
    20016 
    20017 magicRunRow *magicRunRowAlloc(psS64 magic_id, const char *state, const char *workdir, const char *workdir_state, const char *label, const char *dvodb, psTime* registered)
    20018 {
    20019     magicRunRow     *_object;
    20020 
    20021     _object = psAlloc(sizeof(magicRunRow));
    20022     psMemSetDeallocator(_object, (psFreeFunc)magicRunRowFree);
    20023 
    20024     _object->magic_id = magic_id;
    20025     _object->state = psStringCopy(state);
    20026     _object->workdir = psStringCopy(workdir);
    20027     _object->workdir_state = psStringCopy(workdir_state);
    20028     _object->label = psStringCopy(label);
    20029     _object->dvodb = psStringCopy(dvodb);
    20030     _object->registered = psTimeCopy(registered);
    20031 
    20032     return _object;
    20033 }
    20034 
    20035 static void magicRunRowFree(magicRunRow *object)
    20036 {
    20037     psFree(object->state);
    20038     psFree(object->workdir);
    20039     psFree(object->workdir_state);
    20040     psFree(object->label);
    20041     psFree(object->dvodb);
    20042     psFree(object->registered);
    20043 }
    20044 
    20045 bool magicRunCreateTable(psDB *dbh)
    20046 {
    20047     psMetadata *md = psMetadataAlloc();
    20048     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, "Primary Key AUTO_INCREMENT", 0)) {
    20049         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    20050         psFree(md);
    20051         return false;
    20052     }
    20053     if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, "Key", "64")) {
    20054         psError(PS_ERR_UNKNOWN, false, "failed to add item state");
    20055         psFree(md);
    20056         return false;
    20057     }
    20058     if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, "255")) {
    20059         psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
    20060         psFree(md);
    20061         return false;
    20062     }
    20063     if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, "Key", "255")) {
    20064         psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
    20065         psFree(md);
    20066         return false;
    20067     }
    20068     if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, "key", "64")) {
    20069         psError(PS_ERR_UNKNOWN, false, "failed to add item label");
    20070         psFree(md);
    20071         return false;
    20072     }
    20073     if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, "255")) {
    20074         psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
    20075         psFree(md);
    20076         return false;
    20077     }
    20078     if (!psMetadataAdd(md, PS_LIST_TAIL, "registered", PS_DATA_TIME, NULL, NULL)) {
    20079         psError(PS_ERR_UNKNOWN, false, "failed to add item registered");
    20080         psFree(md);
    20081         return false;
    20082     }
    20083 
    20084     bool status = psDBCreateTable(dbh, MAGICRUN_TABLE_NAME, md);
    20085 
    20086     psFree(md);
    20087 
    20088     return status;
    20089 }
    20090 
    20091 bool magicRunDropTable(psDB *dbh)
    20092 {
    20093     return psDBDropTable(dbh, MAGICRUN_TABLE_NAME);
    20094 }
    20095 
    20096 bool magicRunInsert(psDB * dbh, psS64 magic_id, const char *state, const char *workdir, const char *workdir_state, const char *label, const char *dvodb, psTime* registered)
    20097 {
    20098     psMetadata *md = psMetadataAlloc();
    20099     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, magic_id)) {
    20100         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    20101         psFree(md);
    20102         return false;
    20103     }
    20104     if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, state)) {
    20105         psError(PS_ERR_UNKNOWN, false, "failed to add item state");
    20106         psFree(md);
    20107         return false;
    20108     }
    20109     if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, workdir)) {
    20110         psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
    20111         psFree(md);
    20112         return false;
    20113     }
    20114     if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, NULL, workdir_state)) {
    20115         psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
    20116         psFree(md);
    20117         return false;
    20118     }
    20119     if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, NULL, label)) {
    20120         psError(PS_ERR_UNKNOWN, false, "failed to add item label");
    20121         psFree(md);
    20122         return false;
    20123     }
    20124     if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, dvodb)) {
    20125         psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
    20126         psFree(md);
    20127         return false;
    20128     }
    20129     if (!psMetadataAdd(md, PS_LIST_TAIL, "registered", PS_DATA_TIME, NULL, registered)) {
    20130         psError(PS_ERR_UNKNOWN, false, "failed to add item registered");
    20131         psFree(md);
    20132         return false;
    20133     }
    20134 
    20135     bool status = psDBInsertOneRow(dbh, MAGICRUN_TABLE_NAME, md);
    20136     psFree(md);
    20137 
    20138     return status;
    20139 }
    20140 
    20141 long long magicRunDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    20142 {
    20143     long long       deleted = 0;
    20144 
    20145     long long count = psDBDeleteRows(dbh, MAGICRUN_TABLE_NAME, where, limit);
    20146     if (count < 0) {
    20147         psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicRun");
    20148         return count;
    20149 
    20150         deleted += count;
    20151     }
    20152 
    20153     return deleted;
    20154 }
    20155 bool magicRunInsertObject(psDB *dbh, magicRunRow *object)
    20156 {
    20157     return magicRunInsert(dbh, object->magic_id, object->state, object->workdir, object->workdir_state, object->label, object->dvodb, object->registered);
    20158 }
    20159 
    20160 bool magicRunInsertObjects(psDB *dbh, psArray *objects)
    20161 {
    20162     for (long i = 0; i < psArrayLength(objects); i++) {
    20163         if (!magicRunInsertObject(dbh, objects->data[i])) {
    20164             return false;
    20165         }
    20166     }
    20167 
    20168     return true;
    20169 }
    20170 
    20171 bool magicRunInsertFits(psDB *dbh, const psFits *fits)
    20172 {
    20173     psArray         *rowSet;
    20174 
    20175     // move to (the first?) extension named  MAGICRUN_TABLE_NAME
    20176     if (!psFitsMoveExtName(fits, MAGICRUN_TABLE_NAME)) {
    20177         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", MAGICRUN_TABLE_NAME);
    20178         return false;
    20179     }
    20180 
    20181     // check HDU type
    20182     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    20183         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    20184         return false;
    20185     }
    20186 
    20187     // read fits table
    20188     rowSet = psFitsReadTable(fits);
    20189     if (!rowSet) {
    20190         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    20191         psFree(rowSet);
    20192         return false;
    20193     }
    20194 
    20195     if (!psDBInsertRows(dbh, MAGICRUN_TABLE_NAME, rowSet)) {
    20196         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    20197         psFree(rowSet);
    20198         return false;
    20199     }
    20200 
    20201     psFree(rowSet);
    20202 
    20203     return true;
    20204 }
    20205 
    20206 bool magicRunSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    20207 {
    20208     psArray         *rowSet;
    20209 
    20210     rowSet = psDBSelectRows(dbh, MAGICRUN_TABLE_NAME, where, limit);
    20211     if (!rowSet) {
    20212         return false;
    20213     }
    20214 
    20215     // output to fits
    20216     if (!psFitsWriteTable(fits, NULL, rowSet, MAGICRUN_TABLE_NAME)) {
    20217         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    20218         psFree(rowSet);
    20219         return false;
    20220     }
    20221 
    20222     psFree(rowSet);
    20223 
    20224     return true;
    20225 }
    20226 
    20227 psMetadata *magicRunMetadataFromObject(const magicRunRow *object)
    20228 {
    20229     psMetadata *md = psMetadataAlloc();
    20230     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, object->magic_id)) {
    20231         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    20232         psFree(md);
    20233         return false;
    20234     }
    20235     if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
    20236         psError(PS_ERR_UNKNOWN, false, "failed to add item state");
    20237         psFree(md);
    20238         return false;
    20239     }
    20240     if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, object->workdir)) {
    20241         psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
    20242         psFree(md);
    20243         return false;
    20244     }
    20245     if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, NULL, object->workdir_state)) {
    20246         psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
    20247         psFree(md);
    20248         return false;
    20249     }
    20250     if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, NULL, object->label)) {
    20251         psError(PS_ERR_UNKNOWN, false, "failed to add item label");
    20252         psFree(md);
    20253         return false;
    20254     }
    20255     if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, object->dvodb)) {
    20256         psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
    20257         psFree(md);
    20258         return false;
    20259     }
    20260     if (!psMetadataAdd(md, PS_LIST_TAIL, "registered", PS_DATA_TIME, NULL, object->registered)) {
    20261         psError(PS_ERR_UNKNOWN, false, "failed to add item registered");
    20262         psFree(md);
    20263         return false;
    20264     }
    20265 
    20266 
    20267     return md;
    20268 }
    20269 
    20270 magicRunRow *magicRunObjectFromMetadata(psMetadata *md)
    20271 {
    20272 
    20273 bool status = false;
    20274     psS64 magic_id = psMetadataLookupS64(&status, md, "magic_id");
    20275     if (!status) {
    20276         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic_id");
    20277         return false;
    20278     }
    20279     char* state = psMetadataLookupPtr(&status, md, "state");
    20280     if (!status) {
    20281         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
    20282         return false;
    20283     }
    20284     char* workdir = psMetadataLookupPtr(&status, md, "workdir");
    20285     if (!status) {
    20286         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item workdir");
    20287         return false;
    20288     }
    20289     char* workdir_state = psMetadataLookupPtr(&status, md, "workdir_state");
    20290     if (!status) {
    20291         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item workdir_state");
    20292         return false;
    20293     }
    20294     char* label = psMetadataLookupPtr(&status, md, "label");
    20295     if (!status) {
    20296         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item label");
    20297         return false;
    20298     }
    20299     char* dvodb = psMetadataLookupPtr(&status, md, "dvodb");
    20300     if (!status) {
    20301         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dvodb");
    20302         return false;
    20303     }
    20304     psTime* registered = psMetadataLookupPtr(&status, md, "registered");
    20305     if (!status) {
    20306         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item registered");
    20307         return false;
    20308     }
    20309 
    20310     return magicRunRowAlloc(magic_id, state, workdir, workdir_state, label, dvodb, registered);
    20311 }
    20312 psArray *magicRunSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    20313 {
    20314     psArray         *rowSet;
    20315     psArray         *returnSet;
    20316     psU64           i;
    20317 
    20318     rowSet = psDBSelectRows(dbh, MAGICRUN_TABLE_NAME, where, limit);
    20319     if (!rowSet) {
    20320         return NULL;
    20321     }
    20322 
    20323     // convert psMetadata rows to row objects
    20324 
    20325     returnSet = psArrayAllocEmpty(rowSet->n);
    20326 
    20327     for (i = 0; i < rowSet->n; i++) {
    20328         magicRunRow *object = magicRunObjectFromMetadata(rowSet->data[i]);
    20329         psArrayAdd(returnSet, 0, object);
    20330         psFree(object);
    20331     }
    20332 
    20333     psFree(rowSet);
    20334 
    20335     return returnSet;
    20336 }
    20337 bool magicRunDeleteObject(psDB *dbh, const magicRunRow *object)
    20338 {
    20339     psMetadata *where = magicRunMetadataFromObject(object);
    20340     long long count = psDBDeleteRows(dbh, MAGICRUN_TABLE_NAME, where, 0);
    20341     psFree(where);
    20342     if (count < 0) {
    20343         psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicRun");
    20344         return false;
    20345     }
    20346     if (count > 1) {
    20347         // XXX should this be a psAbort() instead?  It is possible that
    20348         // having an object match multiple rows was by design.
    20349         psError(PS_ERR_UNKNOWN, true, "magicRunRow object matched more then one row.  Check your database schema");
    20350         return false;
    20351     }
    20352 
    20353     return true;
    20354 }
    20355 long long magicRunDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    20356 {
    20357     long long       deleted = 0;
    20358 
    20359     for (long long i = 0; i < objects->n; i++) {
    20360         magicRunRow *object = objects->data[i];
    20361         psMetadata *where = magicRunMetadataFromObject(object);
    20362         long long count = psDBDeleteRows(dbh, MAGICRUN_TABLE_NAME, where, limit);
    20363         psFree(where);
    20364         if (count < 0) {
    20365             psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicRun");
    20366             return count;
    20367         }
    20368 
    20369         deleted += count;
    20370     }
    20371 
    20372     return deleted;
    20373 }
    20374 bool magicRunPrintObjects(FILE *stream, psArray *objects, bool mdcf)
    20375 {
    20376     PS_ASSERT_PTR_NON_NULL(objects, false);
    20377 
    20378     psMetadata *output = psMetadataAlloc();
    20379     for (long i = 0; i < psArrayLength(objects); i++) {
    20380         psMetadata *md = magicRunMetadataFromObject(objects->data[i]);
    20381         if (!psMetadataAddMetadata(
    20382             output,
    20383             PS_LIST_TAIL,
    20384             MAGICRUN_TABLE_NAME,
    20385             PS_META_DUPLICATE_OK,
    20386             NULL,
    20387             md
    20388         )) {
    20389             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    20390             psFree(md);
    20391             psFree(output);
    20392             return false;
    20393         }
    20394         psFree(md);
    20395     }
    20396 
    20397     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    20398         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    20399         psFree(output);
    20400     }
    20401     psFree(output);
    20402 
    20403     return true;
    20404 }
    20405 bool magicRunPrintObject(FILE *stream, magicRunRow *object, bool mdcf)
    20406 {
    20407     PS_ASSERT_PTR_NON_NULL(object, false);
    20408 
    20409     psMetadata *md = magicRunMetadataFromObject(object);
    20410 
    20411     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    20412         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    20413         psFree(md);
    20414     }
    20415 
    20416     psFree(md);
    20417 
    20418     return true;
    20419 }
    20420 static void magicInputSkyfileRowFree(magicInputSkyfileRow *object);
    20421 
    20422 magicInputSkyfileRow *magicInputSkyfileRowAlloc(psS64 magic_id, psS64 diff_id, const char *node)
    20423 {
    20424     magicInputSkyfileRow *_object;
    20425 
    20426     _object = psAlloc(sizeof(magicInputSkyfileRow));
    20427     psMemSetDeallocator(_object, (psFreeFunc)magicInputSkyfileRowFree);
    20428 
    20429     _object->magic_id = magic_id;
    20430     _object->diff_id = diff_id;
    20431     _object->node = psStringCopy(node);
    20432 
    20433     return _object;
    20434 }
    20435 
    20436 static void magicInputSkyfileRowFree(magicInputSkyfileRow *object)
    20437 {
    20438     psFree(object->node);
    20439 }
    20440 
    20441 bool magicInputSkyfileCreateTable(psDB *dbh)
    20442 {
    20443     psMetadata *md = psMetadataAlloc();
    20444     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, "Primary Key fkey(magic_id) ref magicRun(magic_id)", 0)) {
    20445         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    20446         psFree(md);
    20447         return false;
    20448     }
    20449     if (!psMetadataAdd(md, PS_LIST_TAIL, "diff_id", PS_DATA_S64, "Primary Key fkey(diff_id) ref diffRun(diff_id)", 0)) {
    20450         psError(PS_ERR_UNKNOWN, false, "failed to add item diff_id");
    20451         psFree(md);
    20452         return false;
    20453     }
    20454     if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, NULL, "64")) {
    20455         psError(PS_ERR_UNKNOWN, false, "failed to add item node");
    20456         psFree(md);
    20457         return false;
    20458     }
    20459 
    20460     bool status = psDBCreateTable(dbh, MAGICINPUTSKYFILE_TABLE_NAME, md);
    20461 
    20462     psFree(md);
    20463 
    20464     return status;
    20465 }
    20466 
    20467 bool magicInputSkyfileDropTable(psDB *dbh)
    20468 {
    20469     return psDBDropTable(dbh, MAGICINPUTSKYFILE_TABLE_NAME);
    20470 }
    20471 
    20472 bool magicInputSkyfileInsert(psDB * dbh, psS64 magic_id, psS64 diff_id, const char *node)
    20473 {
    20474     psMetadata *md = psMetadataAlloc();
    20475     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, magic_id)) {
    20476         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    20477         psFree(md);
    20478         return false;
    20479     }
    20480     if (!psMetadataAdd(md, PS_LIST_TAIL, "diff_id", PS_DATA_S64, NULL, diff_id)) {
    20481         psError(PS_ERR_UNKNOWN, false, "failed to add item diff_id");
    20482         psFree(md);
    20483         return false;
    20484     }
    20485     if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, NULL, node)) {
    20486         psError(PS_ERR_UNKNOWN, false, "failed to add item node");
    20487         psFree(md);
    20488         return false;
    20489     }
    20490 
    20491     bool status = psDBInsertOneRow(dbh, MAGICINPUTSKYFILE_TABLE_NAME, md);
    20492     psFree(md);
    20493 
    20494     return status;
    20495 }
    20496 
    20497 long long magicInputSkyfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    20498 {
    20499     long long       deleted = 0;
    20500 
    20501     long long count = psDBDeleteRows(dbh, MAGICINPUTSKYFILE_TABLE_NAME, where, limit);
    20502     if (count < 0) {
    20503         psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicInputSkyfile");
    20504         return count;
    20505 
    20506         deleted += count;
    20507     }
    20508 
    20509     return deleted;
    20510 }
    20511 bool magicInputSkyfileInsertObject(psDB *dbh, magicInputSkyfileRow *object)
    20512 {
    20513     return magicInputSkyfileInsert(dbh, object->magic_id, object->diff_id, object->node);
    20514 }
    20515 
    20516 bool magicInputSkyfileInsertObjects(psDB *dbh, psArray *objects)
    20517 {
    20518     for (long i = 0; i < psArrayLength(objects); i++) {
    20519         if (!magicInputSkyfileInsertObject(dbh, objects->data[i])) {
    20520             return false;
    20521         }
    20522     }
    20523 
    20524     return true;
    20525 }
    20526 
    20527 bool magicInputSkyfileInsertFits(psDB *dbh, const psFits *fits)
    20528 {
    20529     psArray         *rowSet;
    20530 
    20531     // move to (the first?) extension named  MAGICINPUTSKYFILE_TABLE_NAME
    20532     if (!psFitsMoveExtName(fits, MAGICINPUTSKYFILE_TABLE_NAME)) {
    20533         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", MAGICINPUTSKYFILE_TABLE_NAME);
    20534         return false;
    20535     }
    20536 
    20537     // check HDU type
    20538     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    20539         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    20540         return false;
    20541     }
    20542 
    20543     // read fits table
    20544     rowSet = psFitsReadTable(fits);
    20545     if (!rowSet) {
    20546         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    20547         psFree(rowSet);
    20548         return false;
    20549     }
    20550 
    20551     if (!psDBInsertRows(dbh, MAGICINPUTSKYFILE_TABLE_NAME, rowSet)) {
    20552         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    20553         psFree(rowSet);
    20554         return false;
    20555     }
    20556 
    20557     psFree(rowSet);
    20558 
    20559     return true;
    20560 }
    20561 
    20562 bool magicInputSkyfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    20563 {
    20564     psArray         *rowSet;
    20565 
    20566     rowSet = psDBSelectRows(dbh, MAGICINPUTSKYFILE_TABLE_NAME, where, limit);
    20567     if (!rowSet) {
    20568         return false;
    20569     }
    20570 
    20571     // output to fits
    20572     if (!psFitsWriteTable(fits, NULL, rowSet, MAGICINPUTSKYFILE_TABLE_NAME)) {
    20573         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    20574         psFree(rowSet);
    20575         return false;
    20576     }
    20577 
    20578     psFree(rowSet);
    20579 
    20580     return true;
    20581 }
    20582 
    20583 psMetadata *magicInputSkyfileMetadataFromObject(const magicInputSkyfileRow *object)
    20584 {
    20585     psMetadata *md = psMetadataAlloc();
    20586     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, object->magic_id)) {
    20587         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    20588         psFree(md);
    20589         return false;
    20590     }
    20591     if (!psMetadataAdd(md, PS_LIST_TAIL, "diff_id", PS_DATA_S64, NULL, object->diff_id)) {
    20592         psError(PS_ERR_UNKNOWN, false, "failed to add item diff_id");
    20593         psFree(md);
    20594         return false;
    20595     }
    20596     if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, NULL, object->node)) {
    20597         psError(PS_ERR_UNKNOWN, false, "failed to add item node");
    20598         psFree(md);
    20599         return false;
    20600     }
    20601 
    20602 
    20603     return md;
    20604 }
    20605 
    20606 magicInputSkyfileRow *magicInputSkyfileObjectFromMetadata(psMetadata *md)
    20607 {
    20608 
    20609 bool status = false;
    20610     psS64 magic_id = psMetadataLookupS64(&status, md, "magic_id");
    20611     if (!status) {
    20612         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic_id");
    20613         return false;
    20614     }
    20615     psS64 diff_id = psMetadataLookupS64(&status, md, "diff_id");
    20616     if (!status) {
    20617         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item diff_id");
    20618         return false;
    20619     }
    20620     char* node = psMetadataLookupPtr(&status, md, "node");
    20621     if (!status) {
    20622         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item node");
    20623         return false;
    20624     }
    20625 
    20626     return magicInputSkyfileRowAlloc(magic_id, diff_id, node);
    20627 }
    20628 psArray *magicInputSkyfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    20629 {
    20630     psArray         *rowSet;
    20631     psArray         *returnSet;
    20632     psU64           i;
    20633 
    20634     rowSet = psDBSelectRows(dbh, MAGICINPUTSKYFILE_TABLE_NAME, where, limit);
    20635     if (!rowSet) {
    20636         return NULL;
    20637     }
    20638 
    20639     // convert psMetadata rows to row objects
    20640 
    20641     returnSet = psArrayAllocEmpty(rowSet->n);
    20642 
    20643     for (i = 0; i < rowSet->n; i++) {
    20644         magicInputSkyfileRow *object = magicInputSkyfileObjectFromMetadata(rowSet->data[i]);
    20645         psArrayAdd(returnSet, 0, object);
    20646         psFree(object);
    20647     }
    20648 
    20649     psFree(rowSet);
    20650 
    20651     return returnSet;
    20652 }
    20653 bool magicInputSkyfileDeleteObject(psDB *dbh, const magicInputSkyfileRow *object)
    20654 {
    20655     psMetadata *where = magicInputSkyfileMetadataFromObject(object);
    20656     long long count = psDBDeleteRows(dbh, MAGICINPUTSKYFILE_TABLE_NAME, where, 0);
    20657     psFree(where);
    20658     if (count < 0) {
    20659         psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicInputSkyfile");
    20660         return false;
    20661     }
    20662     if (count > 1) {
    20663         // XXX should this be a psAbort() instead?  It is possible that
    20664         // having an object match multiple rows was by design.
    20665         psError(PS_ERR_UNKNOWN, true, "magicInputSkyfileRow object matched more then one row.  Check your database schema");
    20666         return false;
    20667     }
    20668 
    20669     return true;
    20670 }
    20671 long long magicInputSkyfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    20672 {
    20673     long long       deleted = 0;
    20674 
    20675     for (long long i = 0; i < objects->n; i++) {
    20676         magicInputSkyfileRow *object = objects->data[i];
    20677         psMetadata *where = magicInputSkyfileMetadataFromObject(object);
    20678         long long count = psDBDeleteRows(dbh, MAGICINPUTSKYFILE_TABLE_NAME, where, limit);
    20679         psFree(where);
    20680         if (count < 0) {
    20681             psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicInputSkyfile");
    20682             return count;
    20683         }
    20684 
    20685         deleted += count;
    20686     }
    20687 
    20688     return deleted;
    20689 }
    20690 bool magicInputSkyfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
    20691 {
    20692     PS_ASSERT_PTR_NON_NULL(objects, false);
    20693 
    20694     psMetadata *output = psMetadataAlloc();
    20695     for (long i = 0; i < psArrayLength(objects); i++) {
    20696         psMetadata *md = magicInputSkyfileMetadataFromObject(objects->data[i]);
    20697         if (!psMetadataAddMetadata(
    20698             output,
    20699             PS_LIST_TAIL,
    20700             MAGICINPUTSKYFILE_TABLE_NAME,
    20701             PS_META_DUPLICATE_OK,
    20702             NULL,
    20703             md
    20704         )) {
    20705             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    20706             psFree(md);
    20707             psFree(output);
    20708             return false;
    20709         }
    20710         psFree(md);
    20711     }
    20712 
    20713     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    20714         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    20715         psFree(output);
    20716     }
    20717     psFree(output);
    20718 
    20719     return true;
    20720 }
    20721 bool magicInputSkyfilePrintObject(FILE *stream, magicInputSkyfileRow *object, bool mdcf)
    20722 {
    20723     PS_ASSERT_PTR_NON_NULL(object, false);
    20724 
    20725     psMetadata *md = magicInputSkyfileMetadataFromObject(object);
    20726 
    20727     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    20728         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    20729         psFree(md);
    20730     }
    20731 
    20732     psFree(md);
    20733 
    20734     return true;
    20735 }
    20736 static void magicTreeRowFree(magicTreeRow *object);
    20737 
    20738 magicTreeRow *magicTreeRowAlloc(psS64 magic_id, const char *node, const char *dep)
    20739 {
    20740     magicTreeRow    *_object;
    20741 
    20742     _object = psAlloc(sizeof(magicTreeRow));
    20743     psMemSetDeallocator(_object, (psFreeFunc)magicTreeRowFree);
    20744 
    20745     _object->magic_id = magic_id;
    20746     _object->node = psStringCopy(node);
    20747     _object->dep = psStringCopy(dep);
    20748 
    20749     return _object;
    20750 }
    20751 
    20752 static void magicTreeRowFree(magicTreeRow *object)
    20753 {
    20754     psFree(object->node);
    20755     psFree(object->dep);
    20756 }
    20757 
    20758 bool magicTreeCreateTable(psDB *dbh)
    20759 {
    20760     psMetadata *md = psMetadataAlloc();
    20761     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, "Key fkey(magic_id) ref magicRun(magic_id)", 0)) {
    20762         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    20763         psFree(md);
    20764         return false;
    20765     }
    20766     if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, "Key INDEX(magic_id, node)", "64")) {
    20767         psError(PS_ERR_UNKNOWN, false, "failed to add item node");
    20768         psFree(md);
    20769         return false;
    20770     }
    20771     if (!psMetadataAdd(md, PS_LIST_TAIL, "dep", PS_DATA_STRING, "Key", "64")) {
    20772         psError(PS_ERR_UNKNOWN, false, "failed to add item dep");
    20773         psFree(md);
    20774         return false;
    20775     }
    20776 
    20777     bool status = psDBCreateTable(dbh, MAGICTREE_TABLE_NAME, md);
    20778 
    20779     psFree(md);
    20780 
    20781     return status;
    20782 }
    20783 
    20784 bool magicTreeDropTable(psDB *dbh)
    20785 {
    20786     return psDBDropTable(dbh, MAGICTREE_TABLE_NAME);
    20787 }
    20788 
    20789 bool magicTreeInsert(psDB * dbh, psS64 magic_id, const char *node, const char *dep)
    20790 {
    20791     psMetadata *md = psMetadataAlloc();
    20792     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, magic_id)) {
    20793         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    20794         psFree(md);
    20795         return false;
    20796     }
    20797     if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, NULL, node)) {
    20798         psError(PS_ERR_UNKNOWN, false, "failed to add item node");
    20799         psFree(md);
    20800         return false;
    20801     }
    20802     if (!psMetadataAdd(md, PS_LIST_TAIL, "dep", PS_DATA_STRING, NULL, dep)) {
    20803         psError(PS_ERR_UNKNOWN, false, "failed to add item dep");
    20804         psFree(md);
    20805         return false;
    20806     }
    20807 
    20808     bool status = psDBInsertOneRow(dbh, MAGICTREE_TABLE_NAME, md);
    20809     psFree(md);
    20810 
    20811     return status;
    20812 }
    20813 
    20814 long long magicTreeDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    20815 {
    20816     long long       deleted = 0;
    20817 
    20818     long long count = psDBDeleteRows(dbh, MAGICTREE_TABLE_NAME, where, limit);
    20819     if (count < 0) {
    20820         psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicTree");
    20821         return count;
    20822 
    20823         deleted += count;
    20824     }
    20825 
    20826     return deleted;
    20827 }
    20828 bool magicTreeInsertObject(psDB *dbh, magicTreeRow *object)
    20829 {
    20830     return magicTreeInsert(dbh, object->magic_id, object->node, object->dep);
    20831 }
    20832 
    20833 bool magicTreeInsertObjects(psDB *dbh, psArray *objects)
    20834 {
    20835     for (long i = 0; i < psArrayLength(objects); i++) {
    20836         if (!magicTreeInsertObject(dbh, objects->data[i])) {
    20837             return false;
    20838         }
    20839     }
    20840 
    20841     return true;
    20842 }
    20843 
    20844 bool magicTreeInsertFits(psDB *dbh, const psFits *fits)
    20845 {
    20846     psArray         *rowSet;
    20847 
    20848     // move to (the first?) extension named  MAGICTREE_TABLE_NAME
    20849     if (!psFitsMoveExtName(fits, MAGICTREE_TABLE_NAME)) {
    20850         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", MAGICTREE_TABLE_NAME);
    20851         return false;
    20852     }
    20853 
    20854     // check HDU type
    20855     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    20856         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    20857         return false;
    20858     }
    20859 
    20860     // read fits table
    20861     rowSet = psFitsReadTable(fits);
    20862     if (!rowSet) {
    20863         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    20864         psFree(rowSet);
    20865         return false;
    20866     }
    20867 
    20868     if (!psDBInsertRows(dbh, MAGICTREE_TABLE_NAME, rowSet)) {
    20869         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    20870         psFree(rowSet);
    20871         return false;
    20872     }
    20873 
    20874     psFree(rowSet);
    20875 
    20876     return true;
    20877 }
    20878 
    20879 bool magicTreeSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    20880 {
    20881     psArray         *rowSet;
    20882 
    20883     rowSet = psDBSelectRows(dbh, MAGICTREE_TABLE_NAME, where, limit);
    20884     if (!rowSet) {
    20885         return false;
    20886     }
    20887 
    20888     // output to fits
    20889     if (!psFitsWriteTable(fits, NULL, rowSet, MAGICTREE_TABLE_NAME)) {
    20890         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    20891         psFree(rowSet);
    20892         return false;
    20893     }
    20894 
    20895     psFree(rowSet);
    20896 
    20897     return true;
    20898 }
    20899 
    20900 psMetadata *magicTreeMetadataFromObject(const magicTreeRow *object)
    20901 {
    20902     psMetadata *md = psMetadataAlloc();
    20903     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, object->magic_id)) {
    20904         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    20905         psFree(md);
    20906         return false;
    20907     }
    20908     if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, NULL, object->node)) {
    20909         psError(PS_ERR_UNKNOWN, false, "failed to add item node");
    20910         psFree(md);
    20911         return false;
    20912     }
    20913     if (!psMetadataAdd(md, PS_LIST_TAIL, "dep", PS_DATA_STRING, NULL, object->dep)) {
    20914         psError(PS_ERR_UNKNOWN, false, "failed to add item dep");
    20915         psFree(md);
    20916         return false;
    20917     }
    20918 
    20919 
    20920     return md;
    20921 }
    20922 
    20923 magicTreeRow *magicTreeObjectFromMetadata(psMetadata *md)
    20924 {
    20925 
    20926 bool status = false;
    20927     psS64 magic_id = psMetadataLookupS64(&status, md, "magic_id");
    20928     if (!status) {
    20929         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic_id");
    20930         return false;
    20931     }
    20932     char* node = psMetadataLookupPtr(&status, md, "node");
    20933     if (!status) {
    20934         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item node");
    20935         return false;
    20936     }
    20937     char* dep = psMetadataLookupPtr(&status, md, "dep");
    20938     if (!status) {
    20939         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dep");
    20940         return false;
    20941     }
    20942 
    20943     return magicTreeRowAlloc(magic_id, node, dep);
    20944 }
    20945 psArray *magicTreeSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    20946 {
    20947     psArray         *rowSet;
    20948     psArray         *returnSet;
    20949     psU64           i;
    20950 
    20951     rowSet = psDBSelectRows(dbh, MAGICTREE_TABLE_NAME, where, limit);
    20952     if (!rowSet) {
    20953         return NULL;
    20954     }
    20955 
    20956     // convert psMetadata rows to row objects
    20957 
    20958     returnSet = psArrayAllocEmpty(rowSet->n);
    20959 
    20960     for (i = 0; i < rowSet->n; i++) {
    20961         magicTreeRow *object = magicTreeObjectFromMetadata(rowSet->data[i]);
    20962         psArrayAdd(returnSet, 0, object);
    20963         psFree(object);
    20964     }
    20965 
    20966     psFree(rowSet);
    20967 
    20968     return returnSet;
    20969 }
    20970 bool magicTreeDeleteObject(psDB *dbh, const magicTreeRow *object)
    20971 {
    20972     psMetadata *where = magicTreeMetadataFromObject(object);
    20973     long long count = psDBDeleteRows(dbh, MAGICTREE_TABLE_NAME, where, 0);
    20974     psFree(where);
    20975     if (count < 0) {
    20976         psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicTree");
    20977         return false;
    20978     }
    20979     if (count > 1) {
    20980         // XXX should this be a psAbort() instead?  It is possible that
    20981         // having an object match multiple rows was by design.
    20982         psError(PS_ERR_UNKNOWN, true, "magicTreeRow object matched more then one row.  Check your database schema");
    20983         return false;
    20984     }
    20985 
    20986     return true;
    20987 }
    20988 long long magicTreeDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    20989 {
    20990     long long       deleted = 0;
    20991 
    20992     for (long long i = 0; i < objects->n; i++) {
    20993         magicTreeRow *object = objects->data[i];
    20994         psMetadata *where = magicTreeMetadataFromObject(object);
    20995         long long count = psDBDeleteRows(dbh, MAGICTREE_TABLE_NAME, where, limit);
    20996         psFree(where);
    20997         if (count < 0) {
    20998             psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicTree");
    20999             return count;
    21000         }
    21001 
    21002         deleted += count;
    21003     }
    21004 
    21005     return deleted;
    21006 }
    21007 bool magicTreePrintObjects(FILE *stream, psArray *objects, bool mdcf)
    21008 {
    21009     PS_ASSERT_PTR_NON_NULL(objects, false);
    21010 
    21011     psMetadata *output = psMetadataAlloc();
    21012     for (long i = 0; i < psArrayLength(objects); i++) {
    21013         psMetadata *md = magicTreeMetadataFromObject(objects->data[i]);
    21014         if (!psMetadataAddMetadata(
    21015             output,
    21016             PS_LIST_TAIL,
    21017             MAGICTREE_TABLE_NAME,
    21018             PS_META_DUPLICATE_OK,
    21019             NULL,
    21020             md
    21021         )) {
    21022             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    21023             psFree(md);
    21024             psFree(output);
    21025             return false;
    21026         }
    21027         psFree(md);
    21028     }
    21029 
    21030     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    21031         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    21032         psFree(output);
    21033     }
    21034     psFree(output);
    21035 
    21036     return true;
    21037 }
    21038 bool magicTreePrintObject(FILE *stream, magicTreeRow *object, bool mdcf)
    21039 {
    21040     PS_ASSERT_PTR_NON_NULL(object, false);
    21041 
    21042     psMetadata *md = magicTreeMetadataFromObject(object);
    21043 
    21044     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    21045         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    21046         psFree(md);
    21047     }
    21048 
    21049     psFree(md);
    21050 
    21051     return true;
    21052 }
    21053 static void magicNodeResultRowFree(magicNodeResultRow *object);
    21054 
    21055 magicNodeResultRow *magicNodeResultRowAlloc(psS64 magic_id, const char *node, const char *uri)
    21056 {
    21057     magicNodeResultRow *_object;
    21058 
    21059     _object = psAlloc(sizeof(magicNodeResultRow));
    21060     psMemSetDeallocator(_object, (psFreeFunc)magicNodeResultRowFree);
    21061 
    21062     _object->magic_id = magic_id;
    21063     _object->node = psStringCopy(node);
    21064     _object->uri = psStringCopy(uri);
    21065 
    21066     return _object;
    21067 }
    21068 
    21069 static void magicNodeResultRowFree(magicNodeResultRow *object)
    21070 {
    21071     psFree(object->node);
    21072     psFree(object->uri);
    21073 }
    21074 
    21075 bool magicNodeResultCreateTable(psDB *dbh)
    21076 {
    21077     psMetadata *md = psMetadataAlloc();
    21078     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, "Primary Key fkey(magic_id) ref magicRun(magic_id)", 0)) {
    21079         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    21080         psFree(md);
    21081         return false;
    21082     }
    21083     if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, "Primary Key fkey(magic_id, node) ref magicTree(magic_id, node)", "64")) {
    21084         psError(PS_ERR_UNKNOWN, false, "failed to add item node");
    21085         psFree(md);
    21086         return false;
    21087     }
    21088     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
    21089         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    21090         psFree(md);
    21091         return false;
    21092     }
    21093 
    21094     bool status = psDBCreateTable(dbh, MAGICNODERESULT_TABLE_NAME, md);
    21095 
    21096     psFree(md);
    21097 
    21098     return status;
    21099 }
    21100 
    21101 bool magicNodeResultDropTable(psDB *dbh)
    21102 {
    21103     return psDBDropTable(dbh, MAGICNODERESULT_TABLE_NAME);
    21104 }
    21105 
    21106 bool magicNodeResultInsert(psDB * dbh, psS64 magic_id, const char *node, const char *uri)
    21107 {
    21108     psMetadata *md = psMetadataAlloc();
    21109     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, magic_id)) {
    21110         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    21111         psFree(md);
    21112         return false;
    21113     }
    21114     if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, NULL, node)) {
    21115         psError(PS_ERR_UNKNOWN, false, "failed to add item node");
    21116         psFree(md);
    21117         return false;
    21118     }
    21119     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
    21120         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    21121         psFree(md);
    21122         return false;
    21123     }
    21124 
    21125     bool status = psDBInsertOneRow(dbh, MAGICNODERESULT_TABLE_NAME, md);
    21126     psFree(md);
    21127 
    21128     return status;
    21129 }
    21130 
    21131 long long magicNodeResultDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    21132 {
    21133     long long       deleted = 0;
    21134 
    21135     long long count = psDBDeleteRows(dbh, MAGICNODERESULT_TABLE_NAME, where, limit);
    21136     if (count < 0) {
    21137         psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicNodeResult");
    21138         return count;
    21139 
    21140         deleted += count;
    21141     }
    21142 
    21143     return deleted;
    21144 }
    21145 bool magicNodeResultInsertObject(psDB *dbh, magicNodeResultRow *object)
    21146 {
    21147     return magicNodeResultInsert(dbh, object->magic_id, object->node, object->uri);
    21148 }
    21149 
    21150 bool magicNodeResultInsertObjects(psDB *dbh, psArray *objects)
    21151 {
    21152     for (long i = 0; i < psArrayLength(objects); i++) {
    21153         if (!magicNodeResultInsertObject(dbh, objects->data[i])) {
    21154             return false;
    21155         }
    21156     }
    21157 
    21158     return true;
    21159 }
    21160 
    21161 bool magicNodeResultInsertFits(psDB *dbh, const psFits *fits)
    21162 {
    21163     psArray         *rowSet;
    21164 
    21165     // move to (the first?) extension named  MAGICNODERESULT_TABLE_NAME
    21166     if (!psFitsMoveExtName(fits, MAGICNODERESULT_TABLE_NAME)) {
    21167         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", MAGICNODERESULT_TABLE_NAME);
    21168         return false;
    21169     }
    21170 
    21171     // check HDU type
    21172     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    21173         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    21174         return false;
    21175     }
    21176 
    21177     // read fits table
    21178     rowSet = psFitsReadTable(fits);
    21179     if (!rowSet) {
    21180         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    21181         psFree(rowSet);
    21182         return false;
    21183     }
    21184 
    21185     if (!psDBInsertRows(dbh, MAGICNODERESULT_TABLE_NAME, rowSet)) {
    21186         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    21187         psFree(rowSet);
    21188         return false;
    21189     }
    21190 
    21191     psFree(rowSet);
    21192 
    21193     return true;
    21194 }
    21195 
    21196 bool magicNodeResultSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    21197 {
    21198     psArray         *rowSet;
    21199 
    21200     rowSet = psDBSelectRows(dbh, MAGICNODERESULT_TABLE_NAME, where, limit);
    21201     if (!rowSet) {
    21202         return false;
    21203     }
    21204 
    21205     // output to fits
    21206     if (!psFitsWriteTable(fits, NULL, rowSet, MAGICNODERESULT_TABLE_NAME)) {
    21207         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    21208         psFree(rowSet);
    21209         return false;
    21210     }
    21211 
    21212     psFree(rowSet);
    21213 
    21214     return true;
    21215 }
    21216 
    21217 psMetadata *magicNodeResultMetadataFromObject(const magicNodeResultRow *object)
    21218 {
    21219     psMetadata *md = psMetadataAlloc();
    21220     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, object->magic_id)) {
    21221         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    21222         psFree(md);
    21223         return false;
    21224     }
    21225     if (!psMetadataAdd(md, PS_LIST_TAIL, "node", PS_DATA_STRING, NULL, object->node)) {
    21226         psError(PS_ERR_UNKNOWN, false, "failed to add item node");
    21227         psFree(md);
    21228         return false;
    21229     }
    21230     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
    21231         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    21232         psFree(md);
    21233         return false;
    21234     }
    21235 
    21236 
    21237     return md;
    21238 }
    21239 
    21240 magicNodeResultRow *magicNodeResultObjectFromMetadata(psMetadata *md)
    21241 {
    21242 
    21243 bool status = false;
    21244     psS64 magic_id = psMetadataLookupS64(&status, md, "magic_id");
    21245     if (!status) {
    21246         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic_id");
    21247         return false;
    21248     }
    21249     char* node = psMetadataLookupPtr(&status, md, "node");
    21250     if (!status) {
    21251         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item node");
    21252         return false;
    21253     }
    21254     char* uri = psMetadataLookupPtr(&status, md, "uri");
    21255     if (!status) {
    21256         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
    21257         return false;
    21258     }
    21259 
    21260     return magicNodeResultRowAlloc(magic_id, node, uri);
    21261 }
    21262 psArray *magicNodeResultSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    21263 {
    21264     psArray         *rowSet;
    21265     psArray         *returnSet;
    21266     psU64           i;
    21267 
    21268     rowSet = psDBSelectRows(dbh, MAGICNODERESULT_TABLE_NAME, where, limit);
    21269     if (!rowSet) {
    21270         return NULL;
    21271     }
    21272 
    21273     // convert psMetadata rows to row objects
    21274 
    21275     returnSet = psArrayAllocEmpty(rowSet->n);
    21276 
    21277     for (i = 0; i < rowSet->n; i++) {
    21278         magicNodeResultRow *object = magicNodeResultObjectFromMetadata(rowSet->data[i]);
    21279         psArrayAdd(returnSet, 0, object);
    21280         psFree(object);
    21281     }
    21282 
    21283     psFree(rowSet);
    21284 
    21285     return returnSet;
    21286 }
    21287 bool magicNodeResultDeleteObject(psDB *dbh, const magicNodeResultRow *object)
    21288 {
    21289     psMetadata *where = magicNodeResultMetadataFromObject(object);
    21290     long long count = psDBDeleteRows(dbh, MAGICNODERESULT_TABLE_NAME, where, 0);
    21291     psFree(where);
    21292     if (count < 0) {
    21293         psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicNodeResult");
    21294         return false;
    21295     }
    21296     if (count > 1) {
    21297         // XXX should this be a psAbort() instead?  It is possible that
    21298         // having an object match multiple rows was by design.
    21299         psError(PS_ERR_UNKNOWN, true, "magicNodeResultRow object matched more then one row.  Check your database schema");
    21300         return false;
    21301     }
    21302 
    21303     return true;
    21304 }
    21305 long long magicNodeResultDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    21306 {
    21307     long long       deleted = 0;
    21308 
    21309     for (long long i = 0; i < objects->n; i++) {
    21310         magicNodeResultRow *object = objects->data[i];
    21311         psMetadata *where = magicNodeResultMetadataFromObject(object);
    21312         long long count = psDBDeleteRows(dbh, MAGICNODERESULT_TABLE_NAME, where, limit);
    21313         psFree(where);
    21314         if (count < 0) {
    21315             psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicNodeResult");
    21316             return count;
    21317         }
    21318 
    21319         deleted += count;
    21320     }
    21321 
    21322     return deleted;
    21323 }
    21324 bool magicNodeResultPrintObjects(FILE *stream, psArray *objects, bool mdcf)
    21325 {
    21326     PS_ASSERT_PTR_NON_NULL(objects, false);
    21327 
    21328     psMetadata *output = psMetadataAlloc();
    21329     for (long i = 0; i < psArrayLength(objects); i++) {
    21330         psMetadata *md = magicNodeResultMetadataFromObject(objects->data[i]);
    21331         if (!psMetadataAddMetadata(
    21332             output,
    21333             PS_LIST_TAIL,
    21334             MAGICNODERESULT_TABLE_NAME,
    21335             PS_META_DUPLICATE_OK,
    21336             NULL,
    21337             md
    21338         )) {
    21339             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    21340             psFree(md);
    21341             psFree(output);
    21342             return false;
    21343         }
    21344         psFree(md);
    21345     }
    21346 
    21347     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    21348         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    21349         psFree(output);
    21350     }
    21351     psFree(output);
    21352 
    21353     return true;
    21354 }
    21355 bool magicNodeResultPrintObject(FILE *stream, magicNodeResultRow *object, bool mdcf)
    21356 {
    21357     PS_ASSERT_PTR_NON_NULL(object, false);
    21358 
    21359     psMetadata *md = magicNodeResultMetadataFromObject(object);
    21360 
    21361     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    21362         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    21363         psFree(md);
    21364     }
    21365 
    21366     psFree(md);
    21367 
    21368     return true;
    21369 }
    21370 static void magicMaskRowFree(magicMaskRow *object);
    21371 
    21372 magicMaskRow *magicMaskRowAlloc(psS64 magic_id, const char *uri)
    21373 {
    21374     magicMaskRow    *_object;
    21375 
    21376     _object = psAlloc(sizeof(magicMaskRow));
    21377     psMemSetDeallocator(_object, (psFreeFunc)magicMaskRowFree);
    21378 
    21379     _object->magic_id = magic_id;
    21380     _object->uri = psStringCopy(uri);
    21381 
    21382     return _object;
    21383 }
    21384 
    21385 static void magicMaskRowFree(magicMaskRow *object)
    21386 {
    21387     psFree(object->uri);
    21388 }
    21389 
    21390 bool magicMaskCreateTable(psDB *dbh)
    21391 {
    21392     psMetadata *md = psMetadataAlloc();
    21393     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, "Primary Key fkey(magic_id) ref magicRun(magic_id)", 0)) {
    21394         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    21395         psFree(md);
    21396         return false;
    21397     }
    21398     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
    21399         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    21400         psFree(md);
    21401         return false;
    21402     }
    21403 
    21404     bool status = psDBCreateTable(dbh, MAGICMASK_TABLE_NAME, md);
    21405 
    21406     psFree(md);
    21407 
    21408     return status;
    21409 }
    21410 
    21411 bool magicMaskDropTable(psDB *dbh)
    21412 {
    21413     return psDBDropTable(dbh, MAGICMASK_TABLE_NAME);
    21414 }
    21415 
    21416 bool magicMaskInsert(psDB * dbh, psS64 magic_id, const char *uri)
    21417 {
    21418     psMetadata *md = psMetadataAlloc();
    21419     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, magic_id)) {
    21420         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    21421         psFree(md);
    21422         return false;
    21423     }
    21424     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
    21425         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    21426         psFree(md);
    21427         return false;
    21428     }
    21429 
    21430     bool status = psDBInsertOneRow(dbh, MAGICMASK_TABLE_NAME, md);
    21431     psFree(md);
    21432 
    21433     return status;
    21434 }
    21435 
    21436 long long magicMaskDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    21437 {
    21438     long long       deleted = 0;
    21439 
    21440     long long count = psDBDeleteRows(dbh, MAGICMASK_TABLE_NAME, where, limit);
    21441     if (count < 0) {
    21442         psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicMask");
    21443         return count;
    21444 
    21445         deleted += count;
    21446     }
    21447 
    21448     return deleted;
    21449 }
    21450 bool magicMaskInsertObject(psDB *dbh, magicMaskRow *object)
    21451 {
    21452     return magicMaskInsert(dbh, object->magic_id, object->uri);
    21453 }
    21454 
    21455 bool magicMaskInsertObjects(psDB *dbh, psArray *objects)
    21456 {
    21457     for (long i = 0; i < psArrayLength(objects); i++) {
    21458         if (!magicMaskInsertObject(dbh, objects->data[i])) {
    21459             return false;
    21460         }
    21461     }
    21462 
    21463     return true;
    21464 }
    21465 
    21466 bool magicMaskInsertFits(psDB *dbh, const psFits *fits)
    21467 {
    21468     psArray         *rowSet;
    21469 
    21470     // move to (the first?) extension named  MAGICMASK_TABLE_NAME
    21471     if (!psFitsMoveExtName(fits, MAGICMASK_TABLE_NAME)) {
    21472         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", MAGICMASK_TABLE_NAME);
    21473         return false;
    21474     }
    21475 
    21476     // check HDU type
    21477     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    21478         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    21479         return false;
    21480     }
    21481 
    21482     // read fits table
    21483     rowSet = psFitsReadTable(fits);
    21484     if (!rowSet) {
    21485         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    21486         psFree(rowSet);
    21487         return false;
    21488     }
    21489 
    21490     if (!psDBInsertRows(dbh, MAGICMASK_TABLE_NAME, rowSet)) {
    21491         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    21492         psFree(rowSet);
    21493         return false;
    21494     }
    21495 
    21496     psFree(rowSet);
    21497 
    21498     return true;
    21499 }
    21500 
    21501 bool magicMaskSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    21502 {
    21503     psArray         *rowSet;
    21504 
    21505     rowSet = psDBSelectRows(dbh, MAGICMASK_TABLE_NAME, where, limit);
    21506     if (!rowSet) {
    21507         return false;
    21508     }
    21509 
    21510     // output to fits
    21511     if (!psFitsWriteTable(fits, NULL, rowSet, MAGICMASK_TABLE_NAME)) {
    21512         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    21513         psFree(rowSet);
    21514         return false;
    21515     }
    21516 
    21517     psFree(rowSet);
    21518 
    21519     return true;
    21520 }
    21521 
    21522 psMetadata *magicMaskMetadataFromObject(const magicMaskRow *object)
    21523 {
    21524     psMetadata *md = psMetadataAlloc();
    21525     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, object->magic_id)) {
    21526         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    21527         psFree(md);
    21528         return false;
    21529     }
    21530     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
    21531         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    21532         psFree(md);
    21533         return false;
    21534     }
    21535 
    21536 
    21537     return md;
    21538 }
    21539 
    21540 magicMaskRow *magicMaskObjectFromMetadata(psMetadata *md)
    21541 {
    21542 
    21543 bool status = false;
    21544     psS64 magic_id = psMetadataLookupS64(&status, md, "magic_id");
    21545     if (!status) {
    21546         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic_id");
    21547         return false;
    21548     }
    21549     char* uri = psMetadataLookupPtr(&status, md, "uri");
    21550     if (!status) {
    21551         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
    21552         return false;
    21553     }
    21554 
    21555     return magicMaskRowAlloc(magic_id, uri);
    21556 }
    21557 psArray *magicMaskSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    21558 {
    21559     psArray         *rowSet;
    21560     psArray         *returnSet;
    21561     psU64           i;
    21562 
    21563     rowSet = psDBSelectRows(dbh, MAGICMASK_TABLE_NAME, where, limit);
    21564     if (!rowSet) {
    21565         return NULL;
    21566     }
    21567 
    21568     // convert psMetadata rows to row objects
    21569 
    21570     returnSet = psArrayAllocEmpty(rowSet->n);
    21571 
    21572     for (i = 0; i < rowSet->n; i++) {
    21573         magicMaskRow *object = magicMaskObjectFromMetadata(rowSet->data[i]);
    21574         psArrayAdd(returnSet, 0, object);
    21575         psFree(object);
    21576     }
    21577 
    21578     psFree(rowSet);
    21579 
    21580     return returnSet;
    21581 }
    21582 bool magicMaskDeleteObject(psDB *dbh, const magicMaskRow *object)
    21583 {
    21584     psMetadata *where = magicMaskMetadataFromObject(object);
    21585     long long count = psDBDeleteRows(dbh, MAGICMASK_TABLE_NAME, where, 0);
    21586     psFree(where);
    21587     if (count < 0) {
    21588         psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicMask");
    21589         return false;
    21590     }
    21591     if (count > 1) {
    21592         // XXX should this be a psAbort() instead?  It is possible that
    21593         // having an object match multiple rows was by design.
    21594         psError(PS_ERR_UNKNOWN, true, "magicMaskRow object matched more then one row.  Check your database schema");
    21595         return false;
    21596     }
    21597 
    21598     return true;
    21599 }
    21600 long long magicMaskDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    21601 {
    21602     long long       deleted = 0;
    21603 
    21604     for (long long i = 0; i < objects->n; i++) {
    21605         magicMaskRow *object = objects->data[i];
    21606         psMetadata *where = magicMaskMetadataFromObject(object);
    21607         long long count = psDBDeleteRows(dbh, MAGICMASK_TABLE_NAME, where, limit);
    21608         psFree(where);
    21609         if (count < 0) {
    21610             psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicMask");
    21611             return count;
    21612         }
    21613 
    21614         deleted += count;
    21615     }
    21616 
    21617     return deleted;
    21618 }
    21619 bool magicMaskPrintObjects(FILE *stream, psArray *objects, bool mdcf)
    21620 {
    21621     PS_ASSERT_PTR_NON_NULL(objects, false);
    21622 
    21623     psMetadata *output = psMetadataAlloc();
    21624     for (long i = 0; i < psArrayLength(objects); i++) {
    21625         psMetadata *md = magicMaskMetadataFromObject(objects->data[i]);
    21626         if (!psMetadataAddMetadata(
    21627             output,
    21628             PS_LIST_TAIL,
    21629             MAGICMASK_TABLE_NAME,
    21630             PS_META_DUPLICATE_OK,
    21631             NULL,
    21632             md
    21633         )) {
    21634             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    21635             psFree(md);
    21636             psFree(output);
    21637             return false;
    21638         }
    21639         psFree(md);
    21640     }
    21641 
    21642     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    21643         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    21644         psFree(output);
    21645     }
    21646     psFree(output);
    21647 
    21648     return true;
    21649 }
    21650 bool magicMaskPrintObject(FILE *stream, magicMaskRow *object, bool mdcf)
    21651 {
    21652     PS_ASSERT_PTR_NON_NULL(object, false);
    21653 
    21654     psMetadata *md = magicMaskMetadataFromObject(object);
    21655 
    21656     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    21657         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    21658         psFree(md);
    21659     }
    21660 
    21661     psFree(md);
    21662 
    21663     return true;
    21664 }
    21665 static void magicSkyfileMaskRowFree(magicSkyfileMaskRow *object);
    21666 
    21667 magicSkyfileMaskRow *magicSkyfileMaskRowAlloc(psS64 magic_id, psS64 diff_id, const char *uri)
    21668 {
    21669     magicSkyfileMaskRow *_object;
    21670 
    21671     _object = psAlloc(sizeof(magicSkyfileMaskRow));
    21672     psMemSetDeallocator(_object, (psFreeFunc)magicSkyfileMaskRowFree);
    21673 
    21674     _object->magic_id = magic_id;
    21675     _object->diff_id = diff_id;
    21676     _object->uri = psStringCopy(uri);
    21677 
    21678     return _object;
    21679 }
    21680 
    21681 static void magicSkyfileMaskRowFree(magicSkyfileMaskRow *object)
    21682 {
    21683     psFree(object->uri);
    21684 }
    21685 
    21686 bool magicSkyfileMaskCreateTable(psDB *dbh)
    21687 {
    21688     psMetadata *md = psMetadataAlloc();
    21689     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, "Primary Key fkey(magic_id) ref magicRun(magic_id)", 0)) {
    21690         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    21691         psFree(md);
    21692         return false;
    21693     }
    21694     if (!psMetadataAdd(md, PS_LIST_TAIL, "diff_id", PS_DATA_S64, "Primary Key fkey(magic_id, diff_id) ref magicInputSkyfile(magic_id, diff_id)", 0)) {
    21695         psError(PS_ERR_UNKNOWN, false, "failed to add item diff_id");
    21696         psFree(md);
    21697         return false;
    21698     }
    21699     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, "fkey(magic_id) ref magicMask(magic_id)", "255")) {
    21700         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    21701         psFree(md);
    21702         return false;
    21703     }
    21704 
    21705     bool status = psDBCreateTable(dbh, MAGICSKYFILEMASK_TABLE_NAME, md);
    21706 
    21707     psFree(md);
    21708 
    21709     return status;
    21710 }
    21711 
    21712 bool magicSkyfileMaskDropTable(psDB *dbh)
    21713 {
    21714     return psDBDropTable(dbh, MAGICSKYFILEMASK_TABLE_NAME);
    21715 }
    21716 
    21717 bool magicSkyfileMaskInsert(psDB * dbh, psS64 magic_id, psS64 diff_id, const char *uri)
    21718 {
    21719     psMetadata *md = psMetadataAlloc();
    21720     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, magic_id)) {
    21721         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    21722         psFree(md);
    21723         return false;
    21724     }
    21725     if (!psMetadataAdd(md, PS_LIST_TAIL, "diff_id", PS_DATA_S64, NULL, diff_id)) {
    21726         psError(PS_ERR_UNKNOWN, false, "failed to add item diff_id");
    21727         psFree(md);
    21728         return false;
    21729     }
    21730     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
    21731         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    21732         psFree(md);
    21733         return false;
    21734     }
    21735 
    21736     bool status = psDBInsertOneRow(dbh, MAGICSKYFILEMASK_TABLE_NAME, md);
    21737     psFree(md);
    21738 
    21739     return status;
    21740 }
    21741 
    21742 long long magicSkyfileMaskDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    21743 {
    21744     long long       deleted = 0;
    21745 
    21746     long long count = psDBDeleteRows(dbh, MAGICSKYFILEMASK_TABLE_NAME, where, limit);
    21747     if (count < 0) {
    21748         psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicSkyfileMask");
    21749         return count;
    21750 
    21751         deleted += count;
    21752     }
    21753 
    21754     return deleted;
    21755 }
    21756 bool magicSkyfileMaskInsertObject(psDB *dbh, magicSkyfileMaskRow *object)
    21757 {
    21758     return magicSkyfileMaskInsert(dbh, object->magic_id, object->diff_id, object->uri);
    21759 }
    21760 
    21761 bool magicSkyfileMaskInsertObjects(psDB *dbh, psArray *objects)
    21762 {
    21763     for (long i = 0; i < psArrayLength(objects); i++) {
    21764         if (!magicSkyfileMaskInsertObject(dbh, objects->data[i])) {
    21765             return false;
    21766         }
    21767     }
    21768 
    21769     return true;
    21770 }
    21771 
    21772 bool magicSkyfileMaskInsertFits(psDB *dbh, const psFits *fits)
    21773 {
    21774     psArray         *rowSet;
    21775 
    21776     // move to (the first?) extension named  MAGICSKYFILEMASK_TABLE_NAME
    21777     if (!psFitsMoveExtName(fits, MAGICSKYFILEMASK_TABLE_NAME)) {
    21778         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", MAGICSKYFILEMASK_TABLE_NAME);
    21779         return false;
    21780     }
    21781 
    21782     // check HDU type
    21783     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    21784         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    21785         return false;
    21786     }
    21787 
    21788     // read fits table
    21789     rowSet = psFitsReadTable(fits);
    21790     if (!rowSet) {
    21791         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    21792         psFree(rowSet);
    21793         return false;
    21794     }
    21795 
    21796     if (!psDBInsertRows(dbh, MAGICSKYFILEMASK_TABLE_NAME, rowSet)) {
    21797         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    21798         psFree(rowSet);
    21799         return false;
    21800     }
    21801 
    21802     psFree(rowSet);
    21803 
    21804     return true;
    21805 }
    21806 
    21807 bool magicSkyfileMaskSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    21808 {
    21809     psArray         *rowSet;
    21810 
    21811     rowSet = psDBSelectRows(dbh, MAGICSKYFILEMASK_TABLE_NAME, where, limit);
    21812     if (!rowSet) {
    21813         return false;
    21814     }
    21815 
    21816     // output to fits
    21817     if (!psFitsWriteTable(fits, NULL, rowSet, MAGICSKYFILEMASK_TABLE_NAME)) {
    21818         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    21819         psFree(rowSet);
    21820         return false;
    21821     }
    21822 
    21823     psFree(rowSet);
    21824 
    21825     return true;
    21826 }
    21827 
    21828 psMetadata *magicSkyfileMaskMetadataFromObject(const magicSkyfileMaskRow *object)
    21829 {
    21830     psMetadata *md = psMetadataAlloc();
    21831     if (!psMetadataAdd(md, PS_LIST_TAIL, "magic_id", PS_DATA_S64, NULL, object->magic_id)) {
    21832         psError(PS_ERR_UNKNOWN, false, "failed to add item magic_id");
    21833         psFree(md);
    21834         return false;
    21835     }
    21836     if (!psMetadataAdd(md, PS_LIST_TAIL, "diff_id", PS_DATA_S64, NULL, object->diff_id)) {
    21837         psError(PS_ERR_UNKNOWN, false, "failed to add item diff_id");
    21838         psFree(md);
    21839         return false;
    21840     }
    21841     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
    21842         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    21843         psFree(md);
    21844         return false;
    21845     }
    21846 
    21847 
    21848     return md;
    21849 }
    21850 
    21851 magicSkyfileMaskRow *magicSkyfileMaskObjectFromMetadata(psMetadata *md)
    21852 {
    21853 
    21854 bool status = false;
    21855     psS64 magic_id = psMetadataLookupS64(&status, md, "magic_id");
    21856     if (!status) {
    21857         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic_id");
    21858         return false;
    21859     }
    21860     psS64 diff_id = psMetadataLookupS64(&status, md, "diff_id");
    21861     if (!status) {
    21862         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item diff_id");
    21863         return false;
    21864     }
    21865     char* uri = psMetadataLookupPtr(&status, md, "uri");
    21866     if (!status) {
    21867         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
    21868         return false;
    21869     }
    21870 
    21871     return magicSkyfileMaskRowAlloc(magic_id, diff_id, uri);
    21872 }
    21873 psArray *magicSkyfileMaskSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    21874 {
    21875     psArray         *rowSet;
    21876     psArray         *returnSet;
    21877     psU64           i;
    21878 
    21879     rowSet = psDBSelectRows(dbh, MAGICSKYFILEMASK_TABLE_NAME, where, limit);
    21880     if (!rowSet) {
    21881         return NULL;
    21882     }
    21883 
    21884     // convert psMetadata rows to row objects
    21885 
    21886     returnSet = psArrayAllocEmpty(rowSet->n);
    21887 
    21888     for (i = 0; i < rowSet->n; i++) {
    21889         magicSkyfileMaskRow *object = magicSkyfileMaskObjectFromMetadata(rowSet->data[i]);
    21890         psArrayAdd(returnSet, 0, object);
    21891         psFree(object);
    21892     }
    21893 
    21894     psFree(rowSet);
    21895 
    21896     return returnSet;
    21897 }
    21898 bool magicSkyfileMaskDeleteObject(psDB *dbh, const magicSkyfileMaskRow *object)
    21899 {
    21900     psMetadata *where = magicSkyfileMaskMetadataFromObject(object);
    21901     long long count = psDBDeleteRows(dbh, MAGICSKYFILEMASK_TABLE_NAME, where, 0);
    21902     psFree(where);
    21903     if (count < 0) {
    21904         psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicSkyfileMask");
    21905         return false;
    21906     }
    21907     if (count > 1) {
    21908         // XXX should this be a psAbort() instead?  It is possible that
    21909         // having an object match multiple rows was by design.
    21910         psError(PS_ERR_UNKNOWN, true, "magicSkyfileMaskRow object matched more then one row.  Check your database schema");
    21911         return false;
    21912     }
    21913 
    21914     return true;
    21915 }
    21916 long long magicSkyfileMaskDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    21917 {
    21918     long long       deleted = 0;
    21919 
    21920     for (long long i = 0; i < objects->n; i++) {
    21921         magicSkyfileMaskRow *object = objects->data[i];
    21922         psMetadata *where = magicSkyfileMaskMetadataFromObject(object);
    21923         long long count = psDBDeleteRows(dbh, MAGICSKYFILEMASK_TABLE_NAME, where, limit);
    21924         psFree(where);
    21925         if (count < 0) {
    21926             psError(PS_ERR_UNKNOWN, true, "failed to delete row from magicSkyfileMask");
    21927             return count;
    21928         }
    21929 
    21930         deleted += count;
    21931     }
    21932 
    21933     return deleted;
    21934 }
    21935 bool magicSkyfileMaskPrintObjects(FILE *stream, psArray *objects, bool mdcf)
    21936 {
    21937     PS_ASSERT_PTR_NON_NULL(objects, false);
    21938 
    21939     psMetadata *output = psMetadataAlloc();
    21940     for (long i = 0; i < psArrayLength(objects); i++) {
    21941         psMetadata *md = magicSkyfileMaskMetadataFromObject(objects->data[i]);
    21942         if (!psMetadataAddMetadata(
    21943             output,
    21944             PS_LIST_TAIL,
    21945             MAGICSKYFILEMASK_TABLE_NAME,
    21946             PS_META_DUPLICATE_OK,
    21947             NULL,
    21948             md
    21949         )) {
    21950             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    21951             psFree(md);
    21952             psFree(output);
    21953             return false;
    21954         }
    21955         psFree(md);
    21956     }
    21957 
    21958     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    21959         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    21960         psFree(output);
    21961     }
    21962     psFree(output);
    21963 
    21964     return true;
    21965 }
    21966 bool magicSkyfileMaskPrintObject(FILE *stream, magicSkyfileMaskRow *object, bool mdcf)
    21967 {
    21968     PS_ASSERT_PTR_NON_NULL(object, false);
    21969 
    21970     psMetadata *md = magicSkyfileMaskMetadataFromObject(object);
    21971 
    21972     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    21973         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    21974         psFree(md);
    21975     }
    21976 
    21977     psFree(md);
    21978 
    21979     return true;
    21980 }
Note: See TracChangeset for help on using the changeset viewer.