IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 13, 2007, 12:33:39 PM (19 years ago)
Author:
jhoblitt
Message:

VERSION 1.1.5

File:
1 edited

Legend:

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

    r11733 r11780  
    6464#define P4RUN_TABLE_NAME "p4Run"
    6565#define P4INPUTEXP_TABLE_NAME "p4InputExp"
     66#define P4SKYCELLMAP_TABLE_NAME "p4SkyCellMap"
    6667#define P4SCFILE_TABLE_NAME "p4Scfile"
    67 #define P4INPUTSCFILE_TABLE_NAME "p4InputScfile"
    68 #define P4DIFFSCFILE_TABLE_NAME "p4DiffScfile"
    69 #define P4MAGICMASKIMFILE_TABLE_NAME "p4MagicMaskImfile"
    70 #define SKYCELL_TABLE_NAME "skyCell"
    71 #define SKYCELLMAP_TABLE_NAME "skyCellMap"
    7268#define MAX_STRING_LENGTH 1024
    7369
     
    1346213458static void p4RunRowFree(p4RunRow *object);
    1346313459
    13464 p4RunRow *p4RunRowAlloc(psS32 p4a_id, const char *mode, const char *state, const char *workdir, psTime* registered)
     13460p4RunRow *p4RunRowAlloc(psS32 p4_id, const char *mode, const char *state, const char *workdir, psTime* registered)
    1346513461{
    1346613462    p4RunRow        *_object;
     
    1346913465    psMemSetDeallocator(_object, (psFreeFunc)p4RunRowFree);
    1347013466
    13471     _object->p4a_id = p4a_id;
     13467    _object->p4_id = p4_id;
    1347213468    _object->mode = psStringCopy(mode);
    1347313469    _object->state = psStringCopy(state);
     
    1348913485{
    1349013486    psMetadata *md = psMetadataAlloc();
    13491     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, "Primary Key AUTO_INCREMENT", 0)) {
    13492         psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
     13487    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key AUTO_INCREMENT", 0)) {
     13488        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
    1349313489        psFree(md);
    1349413490        return false;
     
    1352713523}
    1352813524
    13529 bool p4RunInsert(psDB * dbh, psS32 p4a_id, const char *mode, const char *state, const char *workdir, psTime* registered)
     13525bool p4RunInsert(psDB * dbh, psS32 p4_id, const char *mode, const char *state, const char *workdir, psTime* registered)
    1353013526{
    1353113527    psMetadata *md = psMetadataAlloc();
    13532     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, NULL, p4a_id)) {
    13533         psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
     13528    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) {
     13529        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
    1353413530        psFree(md);
    1353513531        return false;
     
    1357813574bool p4RunInsertObject(psDB *dbh, p4RunRow *object)
    1357913575{
    13580     return p4RunInsert(dbh, object->p4a_id, object->mode, object->state, object->workdir, object->registered);
     13576    return p4RunInsert(dbh, object->p4_id, object->mode, object->state, object->workdir, object->registered);
    1358113577}
    1358213578
     
    1365113647{
    1365213648    psMetadata *md = psMetadataAlloc();
    13653     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, NULL, object->p4a_id)) {
    13654         psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
     13649    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) {
     13650        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
    1365513651        psFree(md);
    1365613652        return false;
     
    1368513681
    1368613682bool status = false;
    13687     psS32 p4a_id = psMetadataLookupS32(&status, md, "p4a_id");
    13688     if (!status) {
    13689         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4a_id");
     13683    psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id");
     13684    if (!status) {
     13685        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id");
    1369013686        return false;
    1369113687    }
     
    1371113707    }
    1371213708
    13713     return p4RunRowAlloc(p4a_id, mode, state, workdir, registered);
     13709    return p4RunRowAlloc(p4_id, mode, state, workdir, registered);
    1371413710}
    1371513711psArray *p4RunSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    1382313819static void p4InputExpRowFree(p4InputExpRow *object);
    1382413820
    13825 p4InputExpRow *p4InputExpRowAlloc(psS32 p4a_id, const char *exp_tag, psS32 p3_version, bool magiced)
     13821p4InputExpRow *p4InputExpRowAlloc(psS32 p4_id, const char *exp_tag, psS32 p3_version, bool magiced)
    1382613822{
    1382713823    p4InputExpRow   *_object;
     
    1383013826    psMemSetDeallocator(_object, (psFreeFunc)p4InputExpRowFree);
    1383113827
    13832     _object->p4a_id = p4a_id;
     13828    _object->p4_id = p4_id;
    1383313829    _object->exp_tag = psStringCopy(exp_tag);
    1383413830    _object->p3_version = p3_version;
     
    1384613842{
    1384713843    psMetadata *md = psMetadataAlloc();
    13848     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, "Primary Key", 0)) {
    13849         psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
     13844    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key", 0)) {
     13845        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
    1385013846        psFree(md);
    1385113847        return false;
     
    1387913875}
    1388013876
    13881 bool p4InputExpInsert(psDB * dbh, psS32 p4a_id, const char *exp_tag, psS32 p3_version, bool magiced)
     13877bool p4InputExpInsert(psDB * dbh, psS32 p4_id, const char *exp_tag, psS32 p3_version, bool magiced)
    1388213878{
    1388313879    psMetadata *md = psMetadataAlloc();
    13884     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, NULL, p4a_id)) {
    13885         psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
     13880    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) {
     13881        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
    1388613882        psFree(md);
    1388713883        return false;
     
    1392513921bool p4InputExpInsertObject(psDB *dbh, p4InputExpRow *object)
    1392613922{
    13927     return p4InputExpInsert(dbh, object->p4a_id, object->exp_tag, object->p3_version, object->magiced);
     13923    return p4InputExpInsert(dbh, object->p4_id, object->exp_tag, object->p3_version, object->magiced);
    1392813924}
    1392913925
     
    1399813994{
    1399913995    psMetadata *md = psMetadataAlloc();
    14000     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, NULL, object->p4a_id)) {
    14001         psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
     13996    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) {
     13997        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
    1400213998        psFree(md);
    1400313999        return false;
     
    1402714023
    1402814024bool status = false;
    14029     psS32 p4a_id = psMetadataLookupS32(&status, md, "p4a_id");
    14030     if (!status) {
    14031         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4a_id");
     14025    psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id");
     14026    if (!status) {
     14027        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id");
    1403214028        return false;
    1403314029    }
     
    1404814044    }
    1404914045
    14050     return p4InputExpRowAlloc(p4a_id, exp_tag, p3_version, magiced);
     14046    return p4InputExpRowAlloc(p4_id, exp_tag, p3_version, magiced);
    1405114047}
    1405214048psArray *p4InputExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    1415814154    return true;
    1415914155}
     14156static void p4SkyCellMapRowFree(p4SkyCellMapRow *object);
     14157
     14158p4SkyCellMapRow *p4SkyCellMapRowAlloc(psS32 p4_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *class_id)
     14159{
     14160    p4SkyCellMapRow *_object;
     14161
     14162    _object = psAlloc(sizeof(p4SkyCellMapRow));
     14163    psMemSetDeallocator(_object, (psFreeFunc)p4SkyCellMapRowFree);
     14164
     14165    _object->p4_id = p4_id;
     14166    _object->skycell_id = psStringCopy(skycell_id);
     14167    _object->tess_id = psStringCopy(tess_id);
     14168    _object->exp_tag = psStringCopy(exp_tag);
     14169    _object->p3_version = p3_version;
     14170    _object->class_id = psStringCopy(class_id);
     14171
     14172    return _object;
     14173}
     14174
     14175static void p4SkyCellMapRowFree(p4SkyCellMapRow *object)
     14176{
     14177    psFree(object->skycell_id);
     14178    psFree(object->tess_id);
     14179    psFree(object->exp_tag);
     14180    psFree(object->class_id);
     14181}
     14182
     14183bool p4SkyCellMapCreateTable(psDB *dbh)
     14184{
     14185    psMetadata *md = psMetadataAlloc();
     14186    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key", 0)) {
     14187        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
     14188        psFree(md);
     14189        return false;
     14190    }
     14191    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, "Primary Key", "64")) {
     14192        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
     14193        psFree(md);
     14194        return false;
     14195    }
     14196    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, "Primary Key", "64")) {
     14197        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
     14198        psFree(md);
     14199        return false;
     14200    }
     14201    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
     14202        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
     14203        psFree(md);
     14204        return false;
     14205    }
     14206    if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, "Primary Key", 0)) {
     14207        psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
     14208        psFree(md);
     14209        return false;
     14210    }
     14211    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
     14212        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
     14213        psFree(md);
     14214        return false;
     14215    }
     14216
     14217    bool status = psDBCreateTable(dbh, P4SKYCELLMAP_TABLE_NAME, md);
     14218
     14219    psFree(md);
     14220
     14221    return status;
     14222}
     14223
     14224bool p4SkyCellMapDropTable(psDB *dbh)
     14225{
     14226    return psDBDropTable(dbh, P4SKYCELLMAP_TABLE_NAME);
     14227}
     14228
     14229bool p4SkyCellMapInsert(psDB * dbh, psS32 p4_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *class_id)
     14230{
     14231    psMetadata *md = psMetadataAlloc();
     14232    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) {
     14233        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
     14234        psFree(md);
     14235        return false;
     14236    }
     14237    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) {
     14238        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
     14239        psFree(md);
     14240        return false;
     14241    }
     14242    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) {
     14243        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
     14244        psFree(md);
     14245        return false;
     14246    }
     14247    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
     14248        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
     14249        psFree(md);
     14250        return false;
     14251    }
     14252    if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, p3_version)) {
     14253        psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
     14254        psFree(md);
     14255        return false;
     14256    }
     14257    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
     14258        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
     14259        psFree(md);
     14260        return false;
     14261    }
     14262
     14263    bool status = psDBInsertOneRow(dbh, P4SKYCELLMAP_TABLE_NAME, md);
     14264    psFree(md);
     14265
     14266    return status;
     14267}
     14268
     14269long long p4SkyCellMapDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
     14270{
     14271    long long       deleted = 0;
     14272
     14273    long long count = psDBDeleteRows(dbh, P4SKYCELLMAP_TABLE_NAME, where, limit);
     14274    if (count < 0) {
     14275        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4SkyCellMap");
     14276        return count;
     14277
     14278        deleted += count;
     14279    }
     14280
     14281    return deleted;
     14282}
     14283bool p4SkyCellMapInsertObject(psDB *dbh, p4SkyCellMapRow *object)
     14284{
     14285    return p4SkyCellMapInsert(dbh, object->p4_id, object->skycell_id, object->tess_id, object->exp_tag, object->p3_version, object->class_id);
     14286}
     14287
     14288bool p4SkyCellMapInsertObjects(psDB *dbh, psArray *objects)
     14289{
     14290    for (long i = 0; i < psArrayLength(objects); i++) {
     14291        if (!p4SkyCellMapInsertObject(dbh, objects->data[i])) {
     14292            return false;
     14293        }
     14294    }
     14295
     14296    return true;
     14297}
     14298
     14299bool p4SkyCellMapInsertFits(psDB *dbh, const psFits *fits)
     14300{
     14301    psArray         *rowSet;
     14302
     14303    // move to (the first?) extension named  P4SKYCELLMAP_TABLE_NAME
     14304    if (!psFitsMoveExtName(fits, P4SKYCELLMAP_TABLE_NAME)) {
     14305        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4SKYCELLMAP_TABLE_NAME);
     14306        return false;
     14307    }
     14308
     14309    // check HDU type
     14310    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
     14311        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
     14312        return false;
     14313    }
     14314
     14315    // read fits table
     14316    rowSet = psFitsReadTable(fits);
     14317    if (!rowSet) {
     14318        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
     14319        psFree(rowSet);
     14320        return false;
     14321    }
     14322
     14323    if (!psDBInsertRows(dbh, P4SKYCELLMAP_TABLE_NAME, rowSet)) {
     14324        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
     14325        psFree(rowSet);
     14326        return false;
     14327    }
     14328
     14329    psFree(rowSet);
     14330
     14331    return true;
     14332}
     14333
     14334bool p4SkyCellMapSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
     14335{
     14336    psArray         *rowSet;
     14337
     14338    rowSet = psDBSelectRows(dbh, P4SKYCELLMAP_TABLE_NAME, where, limit);
     14339    if (!rowSet) {
     14340        return false;
     14341    }
     14342
     14343    // output to fits
     14344    if (!psFitsWriteTable(fits, NULL, rowSet, P4SKYCELLMAP_TABLE_NAME)) {
     14345        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
     14346        psFree(rowSet);
     14347        return false;
     14348    }
     14349
     14350    psFree(rowSet);
     14351
     14352    return true;
     14353}
     14354
     14355psMetadata *p4SkyCellMapMetadataFromObject(const p4SkyCellMapRow *object)
     14356{
     14357    psMetadata *md = psMetadataAlloc();
     14358    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) {
     14359        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
     14360        psFree(md);
     14361        return false;
     14362    }
     14363    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) {
     14364        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
     14365        psFree(md);
     14366        return false;
     14367    }
     14368    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) {
     14369        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
     14370        psFree(md);
     14371        return false;
     14372    }
     14373    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
     14374        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
     14375        psFree(md);
     14376        return false;
     14377    }
     14378    if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, object->p3_version)) {
     14379        psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
     14380        psFree(md);
     14381        return false;
     14382    }
     14383    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) {
     14384        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
     14385        psFree(md);
     14386        return false;
     14387    }
     14388
     14389
     14390    return md;
     14391}
     14392
     14393p4SkyCellMapRow *p4SkyCellMapObjectFromMetadata(psMetadata *md)
     14394{
     14395
     14396bool status = false;
     14397    psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id");
     14398    if (!status) {
     14399        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id");
     14400        return false;
     14401    }
     14402    char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id");
     14403    if (!status) {
     14404        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id");
     14405        return false;
     14406    }
     14407    char* tess_id = psMetadataLookupPtr(&status, md, "tess_id");
     14408    if (!status) {
     14409        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id");
     14410        return false;
     14411    }
     14412    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
     14413    if (!status) {
     14414        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
     14415        return false;
     14416    }
     14417    psS32 p3_version = psMetadataLookupS32(&status, md, "p3_version");
     14418    if (!status) {
     14419        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p3_version");
     14420        return false;
     14421    }
     14422    char* class_id = psMetadataLookupPtr(&status, md, "class_id");
     14423    if (!status) {
     14424        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id");
     14425        return false;
     14426    }
     14427
     14428    return p4SkyCellMapRowAlloc(p4_id, skycell_id, tess_id, exp_tag, p3_version, class_id);
     14429}
     14430psArray *p4SkyCellMapSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     14431{
     14432    psArray         *rowSet;
     14433    psArray         *returnSet;
     14434    psU64           i;
     14435
     14436    rowSet = psDBSelectRows(dbh, P4SKYCELLMAP_TABLE_NAME, where, limit);
     14437    if (!rowSet) {
     14438        return NULL;
     14439    }
     14440
     14441    // convert psMetadata rows to row objects
     14442
     14443    returnSet = psArrayAllocEmpty(rowSet->n);
     14444
     14445    for (i = 0; i < rowSet->n; i++) {
     14446        p4SkyCellMapRow *object = p4SkyCellMapObjectFromMetadata(rowSet->data[i]);
     14447        psArrayAdd(returnSet, 0, object);
     14448        psFree(object);
     14449    }
     14450
     14451    psFree(rowSet);
     14452
     14453    return returnSet;
     14454}
     14455bool p4SkyCellMapDeleteObject(psDB *dbh, const p4SkyCellMapRow *object)
     14456{
     14457    psMetadata *where = p4SkyCellMapMetadataFromObject(object);
     14458    long long count = psDBDeleteRows(dbh, P4SKYCELLMAP_TABLE_NAME, where, 0);
     14459    psFree(where);
     14460    if (count < 0) {
     14461        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4SkyCellMap");
     14462        return false;
     14463    }
     14464    if (count > 1) {
     14465        // XXX should this be a psAbort() instead?  It is possible that
     14466        // having an object match multiple rows was by design.
     14467        psError(PS_ERR_UNKNOWN, true, "p4SkyCellMapRow object matched more then one row.  Check your database schema");
     14468        return false;
     14469    }
     14470
     14471    return true;
     14472}
     14473long long p4SkyCellMapDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
     14474{
     14475    long long       deleted = 0;
     14476
     14477    for (long long i = 0; i < objects->n; i++) {
     14478        p4SkyCellMapRow *object = objects->data[i];
     14479        psMetadata *where = p4SkyCellMapMetadataFromObject(object);
     14480        long long count = psDBDeleteRows(dbh, P4SKYCELLMAP_TABLE_NAME, where, limit);
     14481        psFree(where);
     14482        if (count < 0) {
     14483            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4SkyCellMap");
     14484            return count;
     14485        }
     14486
     14487        deleted += count;
     14488    }
     14489
     14490    return deleted;
     14491}
     14492bool p4SkyCellMapPrintObjects(FILE *stream, psArray *objects, bool mdcf)
     14493{
     14494    PS_ASSERT_PTR_NON_NULL(objects, false);
     14495
     14496    psMetadata *output = psMetadataAlloc();
     14497    for (long i = 0; i < psArrayLength(objects); i++) {
     14498        psMetadata *md = p4SkyCellMapMetadataFromObject(objects->data[i]);
     14499        if (!psMetadataAddMetadata(
     14500            output,
     14501            PS_LIST_TAIL,
     14502            P4SKYCELLMAP_TABLE_NAME,
     14503            PS_META_DUPLICATE_OK,
     14504            NULL,
     14505            md
     14506        )) {
     14507            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
     14508            psFree(md);
     14509            psFree(output);
     14510            return false;
     14511        }
     14512        psFree(md);
     14513    }
     14514
     14515    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
     14516        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     14517        psFree(output);
     14518    }
     14519    psFree(output);
     14520
     14521    return true;
     14522}
     14523bool p4SkyCellMapPrintObject(FILE *stream, p4SkyCellMapRow *object, bool mdcf)
     14524{
     14525    PS_ASSERT_PTR_NON_NULL(object, false);
     14526
     14527    psMetadata *md = p4SkyCellMapMetadataFromObject(object);
     14528
     14529    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
     14530        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     14531        psFree(md);
     14532    }
     14533
     14534    psFree(md);
     14535
     14536    return true;
     14537}
    1416014538static void p4ScfileRowFree(p4ScfileRow *object);
    1416114539
    14162 p4ScfileRow *p4ScfileRowAlloc(psS32 p4a_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *uri, psF64 bg, psF64 bg_mean_stdev)
     14540p4ScfileRow *p4ScfileRowAlloc(psS32 p4_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *uri, psF64 bg, psF64 bg_mean_stdev)
    1416314541{
    1416414542    p4ScfileRow     *_object;
     
    1416714545    psMemSetDeallocator(_object, (psFreeFunc)p4ScfileRowFree);
    1416814546
    14169     _object->p4a_id = p4a_id;
     14547    _object->p4_id = p4_id;
    1417014548    _object->skycell_id = psStringCopy(skycell_id);
    1417114549    _object->tess_id = psStringCopy(tess_id);
     
    1419014568{
    1419114569    psMetadata *md = psMetadataAlloc();
    14192     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, "Primary Key", 0)) {
    14193         psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
     14570    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key", 0)) {
     14571        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
    1419414572        psFree(md);
    1419514573        return false;
     
    1424314621}
    1424414622
    14245 bool p4ScfileInsert(psDB * dbh, psS32 p4a_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *uri, psF64 bg, psF64 bg_mean_stdev)
     14623bool p4ScfileInsert(psDB * dbh, psS32 p4_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *uri, psF64 bg, psF64 bg_mean_stdev)
    1424614624{
    1424714625    psMetadata *md = psMetadataAlloc();
    14248     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, NULL, p4a_id)) {
    14249         psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
     14626    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) {
     14627        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
    1425014628        psFree(md);
    1425114629        return false;
     
    1430914687bool p4ScfileInsertObject(psDB *dbh, p4ScfileRow *object)
    1431014688{
    14311     return p4ScfileInsert(dbh, object->p4a_id, object->skycell_id, object->tess_id, object->exp_tag, object->p3_version, object->uri, object->bg, object->bg_mean_stdev);
     14689    return p4ScfileInsert(dbh, object->p4_id, object->skycell_id, object->tess_id, object->exp_tag, object->p3_version, object->uri, object->bg, object->bg_mean_stdev);
    1431214690}
    1431314691
     
    1438214760{
    1438314761    psMetadata *md = psMetadataAlloc();
    14384     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, NULL, object->p4a_id)) {
    14385         psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
     14762    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) {
     14763        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
    1438614764        psFree(md);
    1438714765        return false;
     
    1443114809
    1443214810bool status = false;
    14433     psS32 p4a_id = psMetadataLookupS32(&status, md, "p4a_id");
    14434     if (!status) {
    14435         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4a_id");
     14811    psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id");
     14812    if (!status) {
     14813        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id");
    1443614814        return false;
    1443714815    }
     
    1447214850    }
    1447314851
    14474     return p4ScfileRowAlloc(p4a_id, skycell_id, tess_id, exp_tag, p3_version, uri, bg, bg_mean_stdev);
     14852    return p4ScfileRowAlloc(p4_id, skycell_id, tess_id, exp_tag, p3_version, uri, bg, bg_mean_stdev);
    1447514853}
    1447614854psArray *p4ScfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    1458214960    return true;
    1458314961}
    14584 static void p4InputScfileRowFree(p4InputScfileRow *object);
    14585 
    14586 p4InputScfileRow *p4InputScfileRowAlloc(psS32 p4b_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *kind)
    14587 {
    14588     p4InputScfileRow *_object;
    14589 
    14590     _object = psAlloc(sizeof(p4InputScfileRow));
    14591     psMemSetDeallocator(_object, (psFreeFunc)p4InputScfileRowFree);
    14592 
    14593     _object->p4b_id = p4b_id;
    14594     _object->skycell_id = psStringCopy(skycell_id);
    14595     _object->tess_id = psStringCopy(tess_id);
    14596     _object->exp_tag = psStringCopy(exp_tag);
    14597     _object->p3_version = p3_version;
    14598     _object->kind = psStringCopy(kind);
    14599 
    14600     return _object;
    14601 }
    14602 
    14603 static void p4InputScfileRowFree(p4InputScfileRow *object)
    14604 {
    14605     psFree(object->skycell_id);
    14606     psFree(object->tess_id);
    14607     psFree(object->exp_tag);
    14608     psFree(object->kind);
    14609 }
    14610 
    14611 bool p4InputScfileCreateTable(psDB *dbh)
    14612 {
    14613     psMetadata *md = psMetadataAlloc();
    14614     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, "Primary Key", 0)) {
    14615         psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
    14616         psFree(md);
    14617         return false;
    14618     }
    14619     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, "Primary Key", "64")) {
    14620         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    14621         psFree(md);
    14622         return false;
    14623     }
    14624     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, "Primary Key", "64")) {
    14625         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    14626         psFree(md);
    14627         return false;
    14628     }
    14629     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
    14630         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
    14631         psFree(md);
    14632         return false;
    14633     }
    14634     if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, "Primary Key", 0)) {
    14635         psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
    14636         psFree(md);
    14637         return false;
    14638     }
    14639     if (!psMetadataAdd(md, PS_LIST_TAIL, "kind", PS_DATA_STRING, "Key", "64")) {
    14640         psError(PS_ERR_UNKNOWN, false, "failed to add item kind");
    14641         psFree(md);
    14642         return false;
    14643     }
    14644 
    14645     bool status = psDBCreateTable(dbh, P4INPUTSCFILE_TABLE_NAME, md);
    14646 
    14647     psFree(md);
    14648 
    14649     return status;
    14650 }
    14651 
    14652 bool p4InputScfileDropTable(psDB *dbh)
    14653 {
    14654     return psDBDropTable(dbh, P4INPUTSCFILE_TABLE_NAME);
    14655 }
    14656 
    14657 bool p4InputScfileInsert(psDB * dbh, psS32 p4b_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *kind)
    14658 {
    14659     psMetadata *md = psMetadataAlloc();
    14660     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, NULL, p4b_id)) {
    14661         psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
    14662         psFree(md);
    14663         return false;
    14664     }
    14665     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) {
    14666         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    14667         psFree(md);
    14668         return false;
    14669     }
    14670     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) {
    14671         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    14672         psFree(md);
    14673         return false;
    14674     }
    14675     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
    14676         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
    14677         psFree(md);
    14678         return false;
    14679     }
    14680     if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, p3_version)) {
    14681         psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
    14682         psFree(md);
    14683         return false;
    14684     }
    14685     if (!psMetadataAdd(md, PS_LIST_TAIL, "kind", PS_DATA_STRING, NULL, kind)) {
    14686         psError(PS_ERR_UNKNOWN, false, "failed to add item kind");
    14687         psFree(md);
    14688         return false;
    14689     }
    14690 
    14691     bool status = psDBInsertOneRow(dbh, P4INPUTSCFILE_TABLE_NAME, md);
    14692     psFree(md);
    14693 
    14694     return status;
    14695 }
    14696 
    14697 long long p4InputScfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    14698 {
    14699     long long       deleted = 0;
    14700 
    14701     long long count = psDBDeleteRows(dbh, P4INPUTSCFILE_TABLE_NAME, where, limit);
    14702     if (count < 0) {
    14703         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4InputScfile");
    14704         return count;
    14705 
    14706         deleted += count;
    14707     }
    14708 
    14709     return deleted;
    14710 }
    14711 bool p4InputScfileInsertObject(psDB *dbh, p4InputScfileRow *object)
    14712 {
    14713     return p4InputScfileInsert(dbh, object->p4b_id, object->skycell_id, object->tess_id, object->exp_tag, object->p3_version, object->kind);
    14714 }
    14715 
    14716 bool p4InputScfileInsertObjects(psDB *dbh, psArray *objects)
    14717 {
    14718     for (long i = 0; i < psArrayLength(objects); i++) {
    14719         if (!p4InputScfileInsertObject(dbh, objects->data[i])) {
    14720             return false;
    14721         }
    14722     }
    14723 
    14724     return true;
    14725 }
    14726 
    14727 bool p4InputScfileInsertFits(psDB *dbh, const psFits *fits)
    14728 {
    14729     psArray         *rowSet;
    14730 
    14731     // move to (the first?) extension named  P4INPUTSCFILE_TABLE_NAME
    14732     if (!psFitsMoveExtName(fits, P4INPUTSCFILE_TABLE_NAME)) {
    14733         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4INPUTSCFILE_TABLE_NAME);
    14734         return false;
    14735     }
    14736 
    14737     // check HDU type
    14738     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    14739         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    14740         return false;
    14741     }
    14742 
    14743     // read fits table
    14744     rowSet = psFitsReadTable(fits);
    14745     if (!rowSet) {
    14746         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    14747         psFree(rowSet);
    14748         return false;
    14749     }
    14750 
    14751     if (!psDBInsertRows(dbh, P4INPUTSCFILE_TABLE_NAME, rowSet)) {
    14752         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    14753         psFree(rowSet);
    14754         return false;
    14755     }
    14756 
    14757     psFree(rowSet);
    14758 
    14759     return true;
    14760 }
    14761 
    14762 bool p4InputScfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    14763 {
    14764     psArray         *rowSet;
    14765 
    14766     rowSet = psDBSelectRows(dbh, P4INPUTSCFILE_TABLE_NAME, where, limit);
    14767     if (!rowSet) {
    14768         return false;
    14769     }
    14770 
    14771     // output to fits
    14772     if (!psFitsWriteTable(fits, NULL, rowSet, P4INPUTSCFILE_TABLE_NAME)) {
    14773         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    14774         psFree(rowSet);
    14775         return false;
    14776     }
    14777 
    14778     psFree(rowSet);
    14779 
    14780     return true;
    14781 }
    14782 
    14783 psMetadata *p4InputScfileMetadataFromObject(const p4InputScfileRow *object)
    14784 {
    14785     psMetadata *md = psMetadataAlloc();
    14786     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, NULL, object->p4b_id)) {
    14787         psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
    14788         psFree(md);
    14789         return false;
    14790     }
    14791     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) {
    14792         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    14793         psFree(md);
    14794         return false;
    14795     }
    14796     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) {
    14797         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    14798         psFree(md);
    14799         return false;
    14800     }
    14801     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
    14802         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
    14803         psFree(md);
    14804         return false;
    14805     }
    14806     if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, object->p3_version)) {
    14807         psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
    14808         psFree(md);
    14809         return false;
    14810     }
    14811     if (!psMetadataAdd(md, PS_LIST_TAIL, "kind", PS_DATA_STRING, NULL, object->kind)) {
    14812         psError(PS_ERR_UNKNOWN, false, "failed to add item kind");
    14813         psFree(md);
    14814         return false;
    14815     }
    14816 
    14817 
    14818     return md;
    14819 }
    14820 
    14821 p4InputScfileRow *p4InputScfileObjectFromMetadata(psMetadata *md)
    14822 {
    14823 
    14824 bool status = false;
    14825     psS32 p4b_id = psMetadataLookupS32(&status, md, "p4b_id");
    14826     if (!status) {
    14827         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4b_id");
    14828         return false;
    14829     }
    14830     char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id");
    14831     if (!status) {
    14832         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id");
    14833         return false;
    14834     }
    14835     char* tess_id = psMetadataLookupPtr(&status, md, "tess_id");
    14836     if (!status) {
    14837         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id");
    14838         return false;
    14839     }
    14840     char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
    14841     if (!status) {
    14842         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
    14843         return false;
    14844     }
    14845     psS32 p3_version = psMetadataLookupS32(&status, md, "p3_version");
    14846     if (!status) {
    14847         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p3_version");
    14848         return false;
    14849     }
    14850     char* kind = psMetadataLookupPtr(&status, md, "kind");
    14851     if (!status) {
    14852         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item kind");
    14853         return false;
    14854     }
    14855 
    14856     return p4InputScfileRowAlloc(p4b_id, skycell_id, tess_id, exp_tag, p3_version, kind);
    14857 }
    14858 psArray *p4InputScfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    14859 {
    14860     psArray         *rowSet;
    14861     psArray         *returnSet;
    14862     psU64           i;
    14863 
    14864     rowSet = psDBSelectRows(dbh, P4INPUTSCFILE_TABLE_NAME, where, limit);
    14865     if (!rowSet) {
    14866         return NULL;
    14867     }
    14868 
    14869     // convert psMetadata rows to row objects
    14870 
    14871     returnSet = psArrayAllocEmpty(rowSet->n);
    14872 
    14873     for (i = 0; i < rowSet->n; i++) {
    14874         p4InputScfileRow *object = p4InputScfileObjectFromMetadata(rowSet->data[i]);
    14875         psArrayAdd(returnSet, 0, object);
    14876         psFree(object);
    14877     }
    14878 
    14879     psFree(rowSet);
    14880 
    14881     return returnSet;
    14882 }
    14883 bool p4InputScfileDeleteObject(psDB *dbh, const p4InputScfileRow *object)
    14884 {
    14885     psMetadata *where = p4InputScfileMetadataFromObject(object);
    14886     long long count = psDBDeleteRows(dbh, P4INPUTSCFILE_TABLE_NAME, where, 0);
    14887     psFree(where);
    14888     if (count < 0) {
    14889         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4InputScfile");
    14890         return false;
    14891     }
    14892     if (count > 1) {
    14893         // XXX should this be a psAbort() instead?  It is possible that
    14894         // having an object match multiple rows was by design.
    14895         psError(PS_ERR_UNKNOWN, true, "p4InputScfileRow object matched more then one row.  Check your database schema");
    14896         return false;
    14897     }
    14898 
    14899     return true;
    14900 }
    14901 long long p4InputScfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    14902 {
    14903     long long       deleted = 0;
    14904 
    14905     for (long long i = 0; i < objects->n; i++) {
    14906         p4InputScfileRow *object = objects->data[i];
    14907         psMetadata *where = p4InputScfileMetadataFromObject(object);
    14908         long long count = psDBDeleteRows(dbh, P4INPUTSCFILE_TABLE_NAME, where, limit);
    14909         psFree(where);
    14910         if (count < 0) {
    14911             psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4InputScfile");
    14912             return count;
    14913         }
    14914 
    14915         deleted += count;
    14916     }
    14917 
    14918     return deleted;
    14919 }
    14920 bool p4InputScfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
    14921 {
    14922     PS_ASSERT_PTR_NON_NULL(objects, false);
    14923 
    14924     psMetadata *output = psMetadataAlloc();
    14925     for (long i = 0; i < psArrayLength(objects); i++) {
    14926         psMetadata *md = p4InputScfileMetadataFromObject(objects->data[i]);
    14927         if (!psMetadataAddMetadata(
    14928             output,
    14929             PS_LIST_TAIL,
    14930             P4INPUTSCFILE_TABLE_NAME,
    14931             PS_META_DUPLICATE_OK,
    14932             NULL,
    14933             md
    14934         )) {
    14935             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    14936             psFree(md);
    14937             psFree(output);
    14938             return false;
    14939         }
    14940         psFree(md);
    14941     }
    14942 
    14943     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    14944         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    14945         psFree(output);
    14946     }
    14947     psFree(output);
    14948 
    14949     return true;
    14950 }
    14951 bool p4InputScfilePrintObject(FILE *stream, p4InputScfileRow *object, bool mdcf)
    14952 {
    14953     PS_ASSERT_PTR_NON_NULL(object, false);
    14954 
    14955     psMetadata *md = p4InputScfileMetadataFromObject(object);
    14956 
    14957     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    14958         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    14959         psFree(md);
    14960     }
    14961 
    14962     psFree(md);
    14963 
    14964     return true;
    14965 }
    14966 static void p4DiffScfileRowFree(p4DiffScfileRow *object);
    14967 
    14968 p4DiffScfileRow *p4DiffScfileRowAlloc(psS32 p4b_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *uri, psF64 bg, psF64 bg_mean_stdev)
    14969 {
    14970     p4DiffScfileRow *_object;
    14971 
    14972     _object = psAlloc(sizeof(p4DiffScfileRow));
    14973     psMemSetDeallocator(_object, (psFreeFunc)p4DiffScfileRowFree);
    14974 
    14975     _object->p4b_id = p4b_id;
    14976     _object->skycell_id = psStringCopy(skycell_id);
    14977     _object->tess_id = psStringCopy(tess_id);
    14978     _object->exp_tag = psStringCopy(exp_tag);
    14979     _object->p3_version = p3_version;
    14980     _object->uri = psStringCopy(uri);
    14981     _object->bg = bg;
    14982     _object->bg_mean_stdev = bg_mean_stdev;
    14983 
    14984     return _object;
    14985 }
    14986 
    14987 static void p4DiffScfileRowFree(p4DiffScfileRow *object)
    14988 {
    14989     psFree(object->skycell_id);
    14990     psFree(object->tess_id);
    14991     psFree(object->exp_tag);
    14992     psFree(object->uri);
    14993 }
    14994 
    14995 bool p4DiffScfileCreateTable(psDB *dbh)
    14996 {
    14997     psMetadata *md = psMetadataAlloc();
    14998     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, "Primary Key", 0)) {
    14999         psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
    15000         psFree(md);
    15001         return false;
    15002     }
    15003     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, "Primary Key", "64")) {
    15004         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    15005         psFree(md);
    15006         return false;
    15007     }
    15008     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, "Primary Key", "64")) {
    15009         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    15010         psFree(md);
    15011         return false;
    15012     }
    15013     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
    15014         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
    15015         psFree(md);
    15016         return false;
    15017     }
    15018     if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, "Primary Key", 0)) {
    15019         psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
    15020         psFree(md);
    15021         return false;
    15022     }
    15023     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
    15024         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    15025         psFree(md);
    15026         return false;
    15027     }
    15028     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg", PS_DATA_F64, NULL, 0.0)) {
    15029         psError(PS_ERR_UNKNOWN, false, "failed to add item bg");
    15030         psFree(md);
    15031         return false;
    15032     }
    15033     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_mean_stdev", PS_DATA_F64, NULL, 0.0)) {
    15034         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev");
    15035         psFree(md);
    15036         return false;
    15037     }
    15038 
    15039     bool status = psDBCreateTable(dbh, P4DIFFSCFILE_TABLE_NAME, md);
    15040 
    15041     psFree(md);
    15042 
    15043     return status;
    15044 }
    15045 
    15046 bool p4DiffScfileDropTable(psDB *dbh)
    15047 {
    15048     return psDBDropTable(dbh, P4DIFFSCFILE_TABLE_NAME);
    15049 }
    15050 
    15051 bool p4DiffScfileInsert(psDB * dbh, psS32 p4b_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *uri, psF64 bg, psF64 bg_mean_stdev)
    15052 {
    15053     psMetadata *md = psMetadataAlloc();
    15054     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, NULL, p4b_id)) {
    15055         psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
    15056         psFree(md);
    15057         return false;
    15058     }
    15059     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) {
    15060         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    15061         psFree(md);
    15062         return false;
    15063     }
    15064     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) {
    15065         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    15066         psFree(md);
    15067         return false;
    15068     }
    15069     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
    15070         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
    15071         psFree(md);
    15072         return false;
    15073     }
    15074     if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, p3_version)) {
    15075         psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
    15076         psFree(md);
    15077         return false;
    15078     }
    15079     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
    15080         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    15081         psFree(md);
    15082         return false;
    15083     }
    15084     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg", PS_DATA_F64, NULL, bg)) {
    15085         psError(PS_ERR_UNKNOWN, false, "failed to add item bg");
    15086         psFree(md);
    15087         return false;
    15088     }
    15089     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_mean_stdev", PS_DATA_F64, NULL, bg_mean_stdev)) {
    15090         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev");
    15091         psFree(md);
    15092         return false;
    15093     }
    15094 
    15095     bool status = psDBInsertOneRow(dbh, P4DIFFSCFILE_TABLE_NAME, md);
    15096     psFree(md);
    15097 
    15098     return status;
    15099 }
    15100 
    15101 long long p4DiffScfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    15102 {
    15103     long long       deleted = 0;
    15104 
    15105     long long count = psDBDeleteRows(dbh, P4DIFFSCFILE_TABLE_NAME, where, limit);
    15106     if (count < 0) {
    15107         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4DiffScfile");
    15108         return count;
    15109 
    15110         deleted += count;
    15111     }
    15112 
    15113     return deleted;
    15114 }
    15115 bool p4DiffScfileInsertObject(psDB *dbh, p4DiffScfileRow *object)
    15116 {
    15117     return p4DiffScfileInsert(dbh, object->p4b_id, object->skycell_id, object->tess_id, object->exp_tag, object->p3_version, object->uri, object->bg, object->bg_mean_stdev);
    15118 }
    15119 
    15120 bool p4DiffScfileInsertObjects(psDB *dbh, psArray *objects)
    15121 {
    15122     for (long i = 0; i < psArrayLength(objects); i++) {
    15123         if (!p4DiffScfileInsertObject(dbh, objects->data[i])) {
    15124             return false;
    15125         }
    15126     }
    15127 
    15128     return true;
    15129 }
    15130 
    15131 bool p4DiffScfileInsertFits(psDB *dbh, const psFits *fits)
    15132 {
    15133     psArray         *rowSet;
    15134 
    15135     // move to (the first?) extension named  P4DIFFSCFILE_TABLE_NAME
    15136     if (!psFitsMoveExtName(fits, P4DIFFSCFILE_TABLE_NAME)) {
    15137         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4DIFFSCFILE_TABLE_NAME);
    15138         return false;
    15139     }
    15140 
    15141     // check HDU type
    15142     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    15143         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    15144         return false;
    15145     }
    15146 
    15147     // read fits table
    15148     rowSet = psFitsReadTable(fits);
    15149     if (!rowSet) {
    15150         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    15151         psFree(rowSet);
    15152         return false;
    15153     }
    15154 
    15155     if (!psDBInsertRows(dbh, P4DIFFSCFILE_TABLE_NAME, rowSet)) {
    15156         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    15157         psFree(rowSet);
    15158         return false;
    15159     }
    15160 
    15161     psFree(rowSet);
    15162 
    15163     return true;
    15164 }
    15165 
    15166 bool p4DiffScfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    15167 {
    15168     psArray         *rowSet;
    15169 
    15170     rowSet = psDBSelectRows(dbh, P4DIFFSCFILE_TABLE_NAME, where, limit);
    15171     if (!rowSet) {
    15172         return false;
    15173     }
    15174 
    15175     // output to fits
    15176     if (!psFitsWriteTable(fits, NULL, rowSet, P4DIFFSCFILE_TABLE_NAME)) {
    15177         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    15178         psFree(rowSet);
    15179         return false;
    15180     }
    15181 
    15182     psFree(rowSet);
    15183 
    15184     return true;
    15185 }
    15186 
    15187 psMetadata *p4DiffScfileMetadataFromObject(const p4DiffScfileRow *object)
    15188 {
    15189     psMetadata *md = psMetadataAlloc();
    15190     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, NULL, object->p4b_id)) {
    15191         psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
    15192         psFree(md);
    15193         return false;
    15194     }
    15195     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) {
    15196         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    15197         psFree(md);
    15198         return false;
    15199     }
    15200     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) {
    15201         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    15202         psFree(md);
    15203         return false;
    15204     }
    15205     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
    15206         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
    15207         psFree(md);
    15208         return false;
    15209     }
    15210     if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, object->p3_version)) {
    15211         psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
    15212         psFree(md);
    15213         return false;
    15214     }
    15215     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
    15216         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    15217         psFree(md);
    15218         return false;
    15219     }
    15220     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg", PS_DATA_F64, NULL, object->bg)) {
    15221         psError(PS_ERR_UNKNOWN, false, "failed to add item bg");
    15222         psFree(md);
    15223         return false;
    15224     }
    15225     if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_mean_stdev", PS_DATA_F64, NULL, object->bg_mean_stdev)) {
    15226         psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev");
    15227         psFree(md);
    15228         return false;
    15229     }
    15230 
    15231 
    15232     return md;
    15233 }
    15234 
    15235 p4DiffScfileRow *p4DiffScfileObjectFromMetadata(psMetadata *md)
    15236 {
    15237 
    15238 bool status = false;
    15239     psS32 p4b_id = psMetadataLookupS32(&status, md, "p4b_id");
    15240     if (!status) {
    15241         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4b_id");
    15242         return false;
    15243     }
    15244     char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id");
    15245     if (!status) {
    15246         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id");
    15247         return false;
    15248     }
    15249     char* tess_id = psMetadataLookupPtr(&status, md, "tess_id");
    15250     if (!status) {
    15251         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id");
    15252         return false;
    15253     }
    15254     char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
    15255     if (!status) {
    15256         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
    15257         return false;
    15258     }
    15259     psS32 p3_version = psMetadataLookupS32(&status, md, "p3_version");
    15260     if (!status) {
    15261         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p3_version");
    15262         return false;
    15263     }
    15264     char* uri = psMetadataLookupPtr(&status, md, "uri");
    15265     if (!status) {
    15266         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
    15267         return false;
    15268     }
    15269     psF64 bg = psMetadataLookupF64(&status, md, "bg");
    15270     if (!status) {
    15271         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bg");
    15272         return false;
    15273     }
    15274     psF64 bg_mean_stdev = psMetadataLookupF64(&status, md, "bg_mean_stdev");
    15275     if (!status) {
    15276         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bg_mean_stdev");
    15277         return false;
    15278     }
    15279 
    15280     return p4DiffScfileRowAlloc(p4b_id, skycell_id, tess_id, exp_tag, p3_version, uri, bg, bg_mean_stdev);
    15281 }
    15282 psArray *p4DiffScfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    15283 {
    15284     psArray         *rowSet;
    15285     psArray         *returnSet;
    15286     psU64           i;
    15287 
    15288     rowSet = psDBSelectRows(dbh, P4DIFFSCFILE_TABLE_NAME, where, limit);
    15289     if (!rowSet) {
    15290         return NULL;
    15291     }
    15292 
    15293     // convert psMetadata rows to row objects
    15294 
    15295     returnSet = psArrayAllocEmpty(rowSet->n);
    15296 
    15297     for (i = 0; i < rowSet->n; i++) {
    15298         p4DiffScfileRow *object = p4DiffScfileObjectFromMetadata(rowSet->data[i]);
    15299         psArrayAdd(returnSet, 0, object);
    15300         psFree(object);
    15301     }
    15302 
    15303     psFree(rowSet);
    15304 
    15305     return returnSet;
    15306 }
    15307 bool p4DiffScfileDeleteObject(psDB *dbh, const p4DiffScfileRow *object)
    15308 {
    15309     psMetadata *where = p4DiffScfileMetadataFromObject(object);
    15310     long long count = psDBDeleteRows(dbh, P4DIFFSCFILE_TABLE_NAME, where, 0);
    15311     psFree(where);
    15312     if (count < 0) {
    15313         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4DiffScfile");
    15314         return false;
    15315     }
    15316     if (count > 1) {
    15317         // XXX should this be a psAbort() instead?  It is possible that
    15318         // having an object match multiple rows was by design.
    15319         psError(PS_ERR_UNKNOWN, true, "p4DiffScfileRow object matched more then one row.  Check your database schema");
    15320         return false;
    15321     }
    15322 
    15323     return true;
    15324 }
    15325 long long p4DiffScfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    15326 {
    15327     long long       deleted = 0;
    15328 
    15329     for (long long i = 0; i < objects->n; i++) {
    15330         p4DiffScfileRow *object = objects->data[i];
    15331         psMetadata *where = p4DiffScfileMetadataFromObject(object);
    15332         long long count = psDBDeleteRows(dbh, P4DIFFSCFILE_TABLE_NAME, where, limit);
    15333         psFree(where);
    15334         if (count < 0) {
    15335             psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4DiffScfile");
    15336             return count;
    15337         }
    15338 
    15339         deleted += count;
    15340     }
    15341 
    15342     return deleted;
    15343 }
    15344 bool p4DiffScfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
    15345 {
    15346     PS_ASSERT_PTR_NON_NULL(objects, false);
    15347 
    15348     psMetadata *output = psMetadataAlloc();
    15349     for (long i = 0; i < psArrayLength(objects); i++) {
    15350         psMetadata *md = p4DiffScfileMetadataFromObject(objects->data[i]);
    15351         if (!psMetadataAddMetadata(
    15352             output,
    15353             PS_LIST_TAIL,
    15354             P4DIFFSCFILE_TABLE_NAME,
    15355             PS_META_DUPLICATE_OK,
    15356             NULL,
    15357             md
    15358         )) {
    15359             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    15360             psFree(md);
    15361             psFree(output);
    15362             return false;
    15363         }
    15364         psFree(md);
    15365     }
    15366 
    15367     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    15368         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    15369         psFree(output);
    15370     }
    15371     psFree(output);
    15372 
    15373     return true;
    15374 }
    15375 bool p4DiffScfilePrintObject(FILE *stream, p4DiffScfileRow *object, bool mdcf)
    15376 {
    15377     PS_ASSERT_PTR_NON_NULL(object, false);
    15378 
    15379     psMetadata *md = p4DiffScfileMetadataFromObject(object);
    15380 
    15381     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    15382         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    15383         psFree(md);
    15384     }
    15385 
    15386     psFree(md);
    15387 
    15388     return true;
    15389 }
    15390 static void p4MagicMaskImfileRowFree(p4MagicMaskImfileRow *object);
    15391 
    15392 p4MagicMaskImfileRow *p4MagicMaskImfileRowAlloc(psS32 p4c_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri)
    15393 {
    15394     p4MagicMaskImfileRow *_object;
    15395 
    15396     _object = psAlloc(sizeof(p4MagicMaskImfileRow));
    15397     psMemSetDeallocator(_object, (psFreeFunc)p4MagicMaskImfileRowFree);
    15398 
    15399     _object->p4c_id = p4c_id;
    15400     _object->exp_tag = psStringCopy(exp_tag);
    15401     _object->p3_version = p3_version;
    15402     _object->class_id = psStringCopy(class_id);
    15403     _object->uri = psStringCopy(uri);
    15404 
    15405     return _object;
    15406 }
    15407 
    15408 static void p4MagicMaskImfileRowFree(p4MagicMaskImfileRow *object)
    15409 {
    15410     psFree(object->exp_tag);
    15411     psFree(object->class_id);
    15412     psFree(object->uri);
    15413 }
    15414 
    15415 bool p4MagicMaskImfileCreateTable(psDB *dbh)
    15416 {
    15417     psMetadata *md = psMetadataAlloc();
    15418     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4c_id", PS_DATA_S32, "Primary Key", 0)) {
    15419         psError(PS_ERR_UNKNOWN, false, "failed to add item p4c_id");
    15420         psFree(md);
    15421         return false;
    15422     }
    15423     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
    15424         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
    15425         psFree(md);
    15426         return false;
    15427     }
    15428     if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, "Primary Key", 0)) {
    15429         psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
    15430         psFree(md);
    15431         return false;
    15432     }
    15433     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
    15434         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    15435         psFree(md);
    15436         return false;
    15437     }
    15438     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
    15439         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    15440         psFree(md);
    15441         return false;
    15442     }
    15443 
    15444     bool status = psDBCreateTable(dbh, P4MAGICMASKIMFILE_TABLE_NAME, md);
    15445 
    15446     psFree(md);
    15447 
    15448     return status;
    15449 }
    15450 
    15451 bool p4MagicMaskImfileDropTable(psDB *dbh)
    15452 {
    15453     return psDBDropTable(dbh, P4MAGICMASKIMFILE_TABLE_NAME);
    15454 }
    15455 
    15456 bool p4MagicMaskImfileInsert(psDB * dbh, psS32 p4c_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri)
    15457 {
    15458     psMetadata *md = psMetadataAlloc();
    15459     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4c_id", PS_DATA_S32, NULL, p4c_id)) {
    15460         psError(PS_ERR_UNKNOWN, false, "failed to add item p4c_id");
    15461         psFree(md);
    15462         return false;
    15463     }
    15464     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
    15465         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
    15466         psFree(md);
    15467         return false;
    15468     }
    15469     if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, p3_version)) {
    15470         psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
    15471         psFree(md);
    15472         return false;
    15473     }
    15474     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
    15475         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    15476         psFree(md);
    15477         return false;
    15478     }
    15479     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
    15480         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    15481         psFree(md);
    15482         return false;
    15483     }
    15484 
    15485     bool status = psDBInsertOneRow(dbh, P4MAGICMASKIMFILE_TABLE_NAME, md);
    15486     psFree(md);
    15487 
    15488     return status;
    15489 }
    15490 
    15491 long long p4MagicMaskImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    15492 {
    15493     long long       deleted = 0;
    15494 
    15495     long long count = psDBDeleteRows(dbh, P4MAGICMASKIMFILE_TABLE_NAME, where, limit);
    15496     if (count < 0) {
    15497         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4MagicMaskImfile");
    15498         return count;
    15499 
    15500         deleted += count;
    15501     }
    15502 
    15503     return deleted;
    15504 }
    15505 bool p4MagicMaskImfileInsertObject(psDB *dbh, p4MagicMaskImfileRow *object)
    15506 {
    15507     return p4MagicMaskImfileInsert(dbh, object->p4c_id, object->exp_tag, object->p3_version, object->class_id, object->uri);
    15508 }
    15509 
    15510 bool p4MagicMaskImfileInsertObjects(psDB *dbh, psArray *objects)
    15511 {
    15512     for (long i = 0; i < psArrayLength(objects); i++) {
    15513         if (!p4MagicMaskImfileInsertObject(dbh, objects->data[i])) {
    15514             return false;
    15515         }
    15516     }
    15517 
    15518     return true;
    15519 }
    15520 
    15521 bool p4MagicMaskImfileInsertFits(psDB *dbh, const psFits *fits)
    15522 {
    15523     psArray         *rowSet;
    15524 
    15525     // move to (the first?) extension named  P4MAGICMASKIMFILE_TABLE_NAME
    15526     if (!psFitsMoveExtName(fits, P4MAGICMASKIMFILE_TABLE_NAME)) {
    15527         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4MAGICMASKIMFILE_TABLE_NAME);
    15528         return false;
    15529     }
    15530 
    15531     // check HDU type
    15532     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    15533         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    15534         return false;
    15535     }
    15536 
    15537     // read fits table
    15538     rowSet = psFitsReadTable(fits);
    15539     if (!rowSet) {
    15540         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    15541         psFree(rowSet);
    15542         return false;
    15543     }
    15544 
    15545     if (!psDBInsertRows(dbh, P4MAGICMASKIMFILE_TABLE_NAME, rowSet)) {
    15546         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    15547         psFree(rowSet);
    15548         return false;
    15549     }
    15550 
    15551     psFree(rowSet);
    15552 
    15553     return true;
    15554 }
    15555 
    15556 bool p4MagicMaskImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    15557 {
    15558     psArray         *rowSet;
    15559 
    15560     rowSet = psDBSelectRows(dbh, P4MAGICMASKIMFILE_TABLE_NAME, where, limit);
    15561     if (!rowSet) {
    15562         return false;
    15563     }
    15564 
    15565     // output to fits
    15566     if (!psFitsWriteTable(fits, NULL, rowSet, P4MAGICMASKIMFILE_TABLE_NAME)) {
    15567         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    15568         psFree(rowSet);
    15569         return false;
    15570     }
    15571 
    15572     psFree(rowSet);
    15573 
    15574     return true;
    15575 }
    15576 
    15577 psMetadata *p4MagicMaskImfileMetadataFromObject(const p4MagicMaskImfileRow *object)
    15578 {
    15579     psMetadata *md = psMetadataAlloc();
    15580     if (!psMetadataAdd(md, PS_LIST_TAIL, "p4c_id", PS_DATA_S32, NULL, object->p4c_id)) {
    15581         psError(PS_ERR_UNKNOWN, false, "failed to add item p4c_id");
    15582         psFree(md);
    15583         return false;
    15584     }
    15585     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
    15586         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
    15587         psFree(md);
    15588         return false;
    15589     }
    15590     if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, object->p3_version)) {
    15591         psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
    15592         psFree(md);
    15593         return false;
    15594     }
    15595     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) {
    15596         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    15597         psFree(md);
    15598         return false;
    15599     }
    15600     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
    15601         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    15602         psFree(md);
    15603         return false;
    15604     }
    15605 
    15606 
    15607     return md;
    15608 }
    15609 
    15610 p4MagicMaskImfileRow *p4MagicMaskImfileObjectFromMetadata(psMetadata *md)
    15611 {
    15612 
    15613 bool status = false;
    15614     psS32 p4c_id = psMetadataLookupS32(&status, md, "p4c_id");
    15615     if (!status) {
    15616         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4c_id");
    15617         return false;
    15618     }
    15619     char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
    15620     if (!status) {
    15621         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
    15622         return false;
    15623     }
    15624     psS32 p3_version = psMetadataLookupS32(&status, md, "p3_version");
    15625     if (!status) {
    15626         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p3_version");
    15627         return false;
    15628     }
    15629     char* class_id = psMetadataLookupPtr(&status, md, "class_id");
    15630     if (!status) {
    15631         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id");
    15632         return false;
    15633     }
    15634     char* uri = psMetadataLookupPtr(&status, md, "uri");
    15635     if (!status) {
    15636         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
    15637         return false;
    15638     }
    15639 
    15640     return p4MagicMaskImfileRowAlloc(p4c_id, exp_tag, p3_version, class_id, uri);
    15641 }
    15642 psArray *p4MagicMaskImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    15643 {
    15644     psArray         *rowSet;
    15645     psArray         *returnSet;
    15646     psU64           i;
    15647 
    15648     rowSet = psDBSelectRows(dbh, P4MAGICMASKIMFILE_TABLE_NAME, where, limit);
    15649     if (!rowSet) {
    15650         return NULL;
    15651     }
    15652 
    15653     // convert psMetadata rows to row objects
    15654 
    15655     returnSet = psArrayAllocEmpty(rowSet->n);
    15656 
    15657     for (i = 0; i < rowSet->n; i++) {
    15658         p4MagicMaskImfileRow *object = p4MagicMaskImfileObjectFromMetadata(rowSet->data[i]);
    15659         psArrayAdd(returnSet, 0, object);
    15660         psFree(object);
    15661     }
    15662 
    15663     psFree(rowSet);
    15664 
    15665     return returnSet;
    15666 }
    15667 bool p4MagicMaskImfileDeleteObject(psDB *dbh, const p4MagicMaskImfileRow *object)
    15668 {
    15669     psMetadata *where = p4MagicMaskImfileMetadataFromObject(object);
    15670     long long count = psDBDeleteRows(dbh, P4MAGICMASKIMFILE_TABLE_NAME, where, 0);
    15671     psFree(where);
    15672     if (count < 0) {
    15673         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4MagicMaskImfile");
    15674         return false;
    15675     }
    15676     if (count > 1) {
    15677         // XXX should this be a psAbort() instead?  It is possible that
    15678         // having an object match multiple rows was by design.
    15679         psError(PS_ERR_UNKNOWN, true, "p4MagicMaskImfileRow object matched more then one row.  Check your database schema");
    15680         return false;
    15681     }
    15682 
    15683     return true;
    15684 }
    15685 long long p4MagicMaskImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    15686 {
    15687     long long       deleted = 0;
    15688 
    15689     for (long long i = 0; i < objects->n; i++) {
    15690         p4MagicMaskImfileRow *object = objects->data[i];
    15691         psMetadata *where = p4MagicMaskImfileMetadataFromObject(object);
    15692         long long count = psDBDeleteRows(dbh, P4MAGICMASKIMFILE_TABLE_NAME, where, limit);
    15693         psFree(where);
    15694         if (count < 0) {
    15695             psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4MagicMaskImfile");
    15696             return count;
    15697         }
    15698 
    15699         deleted += count;
    15700     }
    15701 
    15702     return deleted;
    15703 }
    15704 bool p4MagicMaskImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
    15705 {
    15706     PS_ASSERT_PTR_NON_NULL(objects, false);
    15707 
    15708     psMetadata *output = psMetadataAlloc();
    15709     for (long i = 0; i < psArrayLength(objects); i++) {
    15710         psMetadata *md = p4MagicMaskImfileMetadataFromObject(objects->data[i]);
    15711         if (!psMetadataAddMetadata(
    15712             output,
    15713             PS_LIST_TAIL,
    15714             P4MAGICMASKIMFILE_TABLE_NAME,
    15715             PS_META_DUPLICATE_OK,
    15716             NULL,
    15717             md
    15718         )) {
    15719             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    15720             psFree(md);
    15721             psFree(output);
    15722             return false;
    15723         }
    15724         psFree(md);
    15725     }
    15726 
    15727     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    15728         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    15729         psFree(output);
    15730     }
    15731     psFree(output);
    15732 
    15733     return true;
    15734 }
    15735 bool p4MagicMaskImfilePrintObject(FILE *stream, p4MagicMaskImfileRow *object, bool mdcf)
    15736 {
    15737     PS_ASSERT_PTR_NON_NULL(object, false);
    15738 
    15739     psMetadata *md = p4MagicMaskImfileMetadataFromObject(object);
    15740 
    15741     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    15742         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    15743         psFree(md);
    15744     }
    15745 
    15746     psFree(md);
    15747 
    15748     return true;
    15749 }
    15750 static void skyCellRowFree(skyCellRow *object);
    15751 
    15752 skyCellRow *skyCellRowAlloc(const char *skycell_id, const char *tess_id, psF64 ra1, psF64 decl1, psF64 ra2, psF64 decl2, psF64 ra3, psF64 decl3, psF64 ra4, psF64 decl4)
    15753 {
    15754     skyCellRow      *_object;
    15755 
    15756     _object = psAlloc(sizeof(skyCellRow));
    15757     psMemSetDeallocator(_object, (psFreeFunc)skyCellRowFree);
    15758 
    15759     _object->skycell_id = psStringCopy(skycell_id);
    15760     _object->tess_id = psStringCopy(tess_id);
    15761     _object->ra1 = ra1;
    15762     _object->decl1 = decl1;
    15763     _object->ra2 = ra2;
    15764     _object->decl2 = decl2;
    15765     _object->ra3 = ra3;
    15766     _object->decl3 = decl3;
    15767     _object->ra4 = ra4;
    15768     _object->decl4 = decl4;
    15769 
    15770     return _object;
    15771 }
    15772 
    15773 static void skyCellRowFree(skyCellRow *object)
    15774 {
    15775     psFree(object->skycell_id);
    15776     psFree(object->tess_id);
    15777 }
    15778 
    15779 bool skyCellCreateTable(psDB *dbh)
    15780 {
    15781     psMetadata *md = psMetadataAlloc();
    15782     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, "Primary Key", "64")) {
    15783         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    15784         psFree(md);
    15785         return false;
    15786     }
    15787     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, "Primary Key", "64")) {
    15788         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    15789         psFree(md);
    15790         return false;
    15791     }
    15792     if (!psMetadataAdd(md, PS_LIST_TAIL, "ra1", PS_DATA_F64, NULL, 0.0)) {
    15793         psError(PS_ERR_UNKNOWN, false, "failed to add item ra1");
    15794         psFree(md);
    15795         return false;
    15796     }
    15797     if (!psMetadataAdd(md, PS_LIST_TAIL, "decl1", PS_DATA_F64, NULL, 0.0)) {
    15798         psError(PS_ERR_UNKNOWN, false, "failed to add item decl1");
    15799         psFree(md);
    15800         return false;
    15801     }
    15802     if (!psMetadataAdd(md, PS_LIST_TAIL, "ra2", PS_DATA_F64, NULL, 0.0)) {
    15803         psError(PS_ERR_UNKNOWN, false, "failed to add item ra2");
    15804         psFree(md);
    15805         return false;
    15806     }
    15807     if (!psMetadataAdd(md, PS_LIST_TAIL, "decl2", PS_DATA_F64, NULL, 0.0)) {
    15808         psError(PS_ERR_UNKNOWN, false, "failed to add item decl2");
    15809         psFree(md);
    15810         return false;
    15811     }
    15812     if (!psMetadataAdd(md, PS_LIST_TAIL, "ra3", PS_DATA_F64, NULL, 0.0)) {
    15813         psError(PS_ERR_UNKNOWN, false, "failed to add item ra3");
    15814         psFree(md);
    15815         return false;
    15816     }
    15817     if (!psMetadataAdd(md, PS_LIST_TAIL, "decl3", PS_DATA_F64, NULL, 0.0)) {
    15818         psError(PS_ERR_UNKNOWN, false, "failed to add item decl3");
    15819         psFree(md);
    15820         return false;
    15821     }
    15822     if (!psMetadataAdd(md, PS_LIST_TAIL, "ra4", PS_DATA_F64, NULL, 0.0)) {
    15823         psError(PS_ERR_UNKNOWN, false, "failed to add item ra4");
    15824         psFree(md);
    15825         return false;
    15826     }
    15827     if (!psMetadataAdd(md, PS_LIST_TAIL, "decl4", PS_DATA_F64, NULL, 0.0)) {
    15828         psError(PS_ERR_UNKNOWN, false, "failed to add item decl4");
    15829         psFree(md);
    15830         return false;
    15831     }
    15832 
    15833     bool status = psDBCreateTable(dbh, SKYCELL_TABLE_NAME, md);
    15834 
    15835     psFree(md);
    15836 
    15837     return status;
    15838 }
    15839 
    15840 bool skyCellDropTable(psDB *dbh)
    15841 {
    15842     return psDBDropTable(dbh, SKYCELL_TABLE_NAME);
    15843 }
    15844 
    15845 bool skyCellInsert(psDB * dbh, const char *skycell_id, const char *tess_id, psF64 ra1, psF64 decl1, psF64 ra2, psF64 decl2, psF64 ra3, psF64 decl3, psF64 ra4, psF64 decl4)
    15846 {
    15847     psMetadata *md = psMetadataAlloc();
    15848     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) {
    15849         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    15850         psFree(md);
    15851         return false;
    15852     }
    15853     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) {
    15854         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    15855         psFree(md);
    15856         return false;
    15857     }
    15858     if (!psMetadataAdd(md, PS_LIST_TAIL, "ra1", PS_DATA_F64, NULL, ra1)) {
    15859         psError(PS_ERR_UNKNOWN, false, "failed to add item ra1");
    15860         psFree(md);
    15861         return false;
    15862     }
    15863     if (!psMetadataAdd(md, PS_LIST_TAIL, "decl1", PS_DATA_F64, NULL, decl1)) {
    15864         psError(PS_ERR_UNKNOWN, false, "failed to add item decl1");
    15865         psFree(md);
    15866         return false;
    15867     }
    15868     if (!psMetadataAdd(md, PS_LIST_TAIL, "ra2", PS_DATA_F64, NULL, ra2)) {
    15869         psError(PS_ERR_UNKNOWN, false, "failed to add item ra2");
    15870         psFree(md);
    15871         return false;
    15872     }
    15873     if (!psMetadataAdd(md, PS_LIST_TAIL, "decl2", PS_DATA_F64, NULL, decl2)) {
    15874         psError(PS_ERR_UNKNOWN, false, "failed to add item decl2");
    15875         psFree(md);
    15876         return false;
    15877     }
    15878     if (!psMetadataAdd(md, PS_LIST_TAIL, "ra3", PS_DATA_F64, NULL, ra3)) {
    15879         psError(PS_ERR_UNKNOWN, false, "failed to add item ra3");
    15880         psFree(md);
    15881         return false;
    15882     }
    15883     if (!psMetadataAdd(md, PS_LIST_TAIL, "decl3", PS_DATA_F64, NULL, decl3)) {
    15884         psError(PS_ERR_UNKNOWN, false, "failed to add item decl3");
    15885         psFree(md);
    15886         return false;
    15887     }
    15888     if (!psMetadataAdd(md, PS_LIST_TAIL, "ra4", PS_DATA_F64, NULL, ra4)) {
    15889         psError(PS_ERR_UNKNOWN, false, "failed to add item ra4");
    15890         psFree(md);
    15891         return false;
    15892     }
    15893     if (!psMetadataAdd(md, PS_LIST_TAIL, "decl4", PS_DATA_F64, NULL, decl4)) {
    15894         psError(PS_ERR_UNKNOWN, false, "failed to add item decl4");
    15895         psFree(md);
    15896         return false;
    15897     }
    15898 
    15899     bool status = psDBInsertOneRow(dbh, SKYCELL_TABLE_NAME, md);
    15900     psFree(md);
    15901 
    15902     return status;
    15903 }
    15904 
    15905 long long skyCellDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    15906 {
    15907     long long       deleted = 0;
    15908 
    15909     long long count = psDBDeleteRows(dbh, SKYCELL_TABLE_NAME, where, limit);
    15910     if (count < 0) {
    15911         psError(PS_ERR_UNKNOWN, true, "failed to delete row from skyCell");
    15912         return count;
    15913 
    15914         deleted += count;
    15915     }
    15916 
    15917     return deleted;
    15918 }
    15919 bool skyCellInsertObject(psDB *dbh, skyCellRow *object)
    15920 {
    15921     return skyCellInsert(dbh, object->skycell_id, object->tess_id, object->ra1, object->decl1, object->ra2, object->decl2, object->ra3, object->decl3, object->ra4, object->decl4);
    15922 }
    15923 
    15924 bool skyCellInsertObjects(psDB *dbh, psArray *objects)
    15925 {
    15926     for (long i = 0; i < psArrayLength(objects); i++) {
    15927         if (!skyCellInsertObject(dbh, objects->data[i])) {
    15928             return false;
    15929         }
    15930     }
    15931 
    15932     return true;
    15933 }
    15934 
    15935 bool skyCellInsertFits(psDB *dbh, const psFits *fits)
    15936 {
    15937     psArray         *rowSet;
    15938 
    15939     // move to (the first?) extension named  SKYCELL_TABLE_NAME
    15940     if (!psFitsMoveExtName(fits, SKYCELL_TABLE_NAME)) {
    15941         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", SKYCELL_TABLE_NAME);
    15942         return false;
    15943     }
    15944 
    15945     // check HDU type
    15946     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    15947         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    15948         return false;
    15949     }
    15950 
    15951     // read fits table
    15952     rowSet = psFitsReadTable(fits);
    15953     if (!rowSet) {
    15954         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    15955         psFree(rowSet);
    15956         return false;
    15957     }
    15958 
    15959     if (!psDBInsertRows(dbh, SKYCELL_TABLE_NAME, rowSet)) {
    15960         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    15961         psFree(rowSet);
    15962         return false;
    15963     }
    15964 
    15965     psFree(rowSet);
    15966 
    15967     return true;
    15968 }
    15969 
    15970 bool skyCellSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    15971 {
    15972     psArray         *rowSet;
    15973 
    15974     rowSet = psDBSelectRows(dbh, SKYCELL_TABLE_NAME, where, limit);
    15975     if (!rowSet) {
    15976         return false;
    15977     }
    15978 
    15979     // output to fits
    15980     if (!psFitsWriteTable(fits, NULL, rowSet, SKYCELL_TABLE_NAME)) {
    15981         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    15982         psFree(rowSet);
    15983         return false;
    15984     }
    15985 
    15986     psFree(rowSet);
    15987 
    15988     return true;
    15989 }
    15990 
    15991 psMetadata *skyCellMetadataFromObject(const skyCellRow *object)
    15992 {
    15993     psMetadata *md = psMetadataAlloc();
    15994     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) {
    15995         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    15996         psFree(md);
    15997         return false;
    15998     }
    15999     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) {
    16000         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    16001         psFree(md);
    16002         return false;
    16003     }
    16004     if (!psMetadataAdd(md, PS_LIST_TAIL, "ra1", PS_DATA_F64, NULL, object->ra1)) {
    16005         psError(PS_ERR_UNKNOWN, false, "failed to add item ra1");
    16006         psFree(md);
    16007         return false;
    16008     }
    16009     if (!psMetadataAdd(md, PS_LIST_TAIL, "decl1", PS_DATA_F64, NULL, object->decl1)) {
    16010         psError(PS_ERR_UNKNOWN, false, "failed to add item decl1");
    16011         psFree(md);
    16012         return false;
    16013     }
    16014     if (!psMetadataAdd(md, PS_LIST_TAIL, "ra2", PS_DATA_F64, NULL, object->ra2)) {
    16015         psError(PS_ERR_UNKNOWN, false, "failed to add item ra2");
    16016         psFree(md);
    16017         return false;
    16018     }
    16019     if (!psMetadataAdd(md, PS_LIST_TAIL, "decl2", PS_DATA_F64, NULL, object->decl2)) {
    16020         psError(PS_ERR_UNKNOWN, false, "failed to add item decl2");
    16021         psFree(md);
    16022         return false;
    16023     }
    16024     if (!psMetadataAdd(md, PS_LIST_TAIL, "ra3", PS_DATA_F64, NULL, object->ra3)) {
    16025         psError(PS_ERR_UNKNOWN, false, "failed to add item ra3");
    16026         psFree(md);
    16027         return false;
    16028     }
    16029     if (!psMetadataAdd(md, PS_LIST_TAIL, "decl3", PS_DATA_F64, NULL, object->decl3)) {
    16030         psError(PS_ERR_UNKNOWN, false, "failed to add item decl3");
    16031         psFree(md);
    16032         return false;
    16033     }
    16034     if (!psMetadataAdd(md, PS_LIST_TAIL, "ra4", PS_DATA_F64, NULL, object->ra4)) {
    16035         psError(PS_ERR_UNKNOWN, false, "failed to add item ra4");
    16036         psFree(md);
    16037         return false;
    16038     }
    16039     if (!psMetadataAdd(md, PS_LIST_TAIL, "decl4", PS_DATA_F64, NULL, object->decl4)) {
    16040         psError(PS_ERR_UNKNOWN, false, "failed to add item decl4");
    16041         psFree(md);
    16042         return false;
    16043     }
    16044 
    16045 
    16046     return md;
    16047 }
    16048 
    16049 skyCellRow *skyCellObjectFromMetadata(psMetadata *md)
    16050 {
    16051 
    16052 bool status = false;
    16053     char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id");
    16054     if (!status) {
    16055         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id");
    16056         return false;
    16057     }
    16058     char* tess_id = psMetadataLookupPtr(&status, md, "tess_id");
    16059     if (!status) {
    16060         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id");
    16061         return false;
    16062     }
    16063     psF64 ra1 = psMetadataLookupF64(&status, md, "ra1");
    16064     if (!status) {
    16065         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ra1");
    16066         return false;
    16067     }
    16068     psF64 decl1 = psMetadataLookupF64(&status, md, "decl1");
    16069     if (!status) {
    16070         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item decl1");
    16071         return false;
    16072     }
    16073     psF64 ra2 = psMetadataLookupF64(&status, md, "ra2");
    16074     if (!status) {
    16075         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ra2");
    16076         return false;
    16077     }
    16078     psF64 decl2 = psMetadataLookupF64(&status, md, "decl2");
    16079     if (!status) {
    16080         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item decl2");
    16081         return false;
    16082     }
    16083     psF64 ra3 = psMetadataLookupF64(&status, md, "ra3");
    16084     if (!status) {
    16085         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ra3");
    16086         return false;
    16087     }
    16088     psF64 decl3 = psMetadataLookupF64(&status, md, "decl3");
    16089     if (!status) {
    16090         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item decl3");
    16091         return false;
    16092     }
    16093     psF64 ra4 = psMetadataLookupF64(&status, md, "ra4");
    16094     if (!status) {
    16095         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ra4");
    16096         return false;
    16097     }
    16098     psF64 decl4 = psMetadataLookupF64(&status, md, "decl4");
    16099     if (!status) {
    16100         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item decl4");
    16101         return false;
    16102     }
    16103 
    16104     return skyCellRowAlloc(skycell_id, tess_id, ra1, decl1, ra2, decl2, ra3, decl3, ra4, decl4);
    16105 }
    16106 psArray *skyCellSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    16107 {
    16108     psArray         *rowSet;
    16109     psArray         *returnSet;
    16110     psU64           i;
    16111 
    16112     rowSet = psDBSelectRows(dbh, SKYCELL_TABLE_NAME, where, limit);
    16113     if (!rowSet) {
    16114         return NULL;
    16115     }
    16116 
    16117     // convert psMetadata rows to row objects
    16118 
    16119     returnSet = psArrayAllocEmpty(rowSet->n);
    16120 
    16121     for (i = 0; i < rowSet->n; i++) {
    16122         skyCellRow *object = skyCellObjectFromMetadata(rowSet->data[i]);
    16123         psArrayAdd(returnSet, 0, object);
    16124         psFree(object);
    16125     }
    16126 
    16127     psFree(rowSet);
    16128 
    16129     return returnSet;
    16130 }
    16131 bool skyCellDeleteObject(psDB *dbh, const skyCellRow *object)
    16132 {
    16133     psMetadata *where = skyCellMetadataFromObject(object);
    16134     long long count = psDBDeleteRows(dbh, SKYCELL_TABLE_NAME, where, 0);
    16135     psFree(where);
    16136     if (count < 0) {
    16137         psError(PS_ERR_UNKNOWN, true, "failed to delete row from skyCell");
    16138         return false;
    16139     }
    16140     if (count > 1) {
    16141         // XXX should this be a psAbort() instead?  It is possible that
    16142         // having an object match multiple rows was by design.
    16143         psError(PS_ERR_UNKNOWN, true, "skyCellRow object matched more then one row.  Check your database schema");
    16144         return false;
    16145     }
    16146 
    16147     return true;
    16148 }
    16149 long long skyCellDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    16150 {
    16151     long long       deleted = 0;
    16152 
    16153     for (long long i = 0; i < objects->n; i++) {
    16154         skyCellRow *object = objects->data[i];
    16155         psMetadata *where = skyCellMetadataFromObject(object);
    16156         long long count = psDBDeleteRows(dbh, SKYCELL_TABLE_NAME, where, limit);
    16157         psFree(where);
    16158         if (count < 0) {
    16159             psError(PS_ERR_UNKNOWN, true, "failed to delete row from skyCell");
    16160             return count;
    16161         }
    16162 
    16163         deleted += count;
    16164     }
    16165 
    16166     return deleted;
    16167 }
    16168 bool skyCellPrintObjects(FILE *stream, psArray *objects, bool mdcf)
    16169 {
    16170     PS_ASSERT_PTR_NON_NULL(objects, false);
    16171 
    16172     psMetadata *output = psMetadataAlloc();
    16173     for (long i = 0; i < psArrayLength(objects); i++) {
    16174         psMetadata *md = skyCellMetadataFromObject(objects->data[i]);
    16175         if (!psMetadataAddMetadata(
    16176             output,
    16177             PS_LIST_TAIL,
    16178             SKYCELL_TABLE_NAME,
    16179             PS_META_DUPLICATE_OK,
    16180             NULL,
    16181             md
    16182         )) {
    16183             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    16184             psFree(md);
    16185             psFree(output);
    16186             return false;
    16187         }
    16188         psFree(md);
    16189     }
    16190 
    16191     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    16192         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    16193         psFree(output);
    16194     }
    16195     psFree(output);
    16196 
    16197     return true;
    16198 }
    16199 bool skyCellPrintObject(FILE *stream, skyCellRow *object, bool mdcf)
    16200 {
    16201     PS_ASSERT_PTR_NON_NULL(object, false);
    16202 
    16203     psMetadata *md = skyCellMetadataFromObject(object);
    16204 
    16205     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    16206         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    16207         psFree(md);
    16208     }
    16209 
    16210     psFree(md);
    16211 
    16212     return true;
    16213 }
    16214 static void skyCellMapRowFree(skyCellMapRow *object);
    16215 
    16216 skyCellMapRow *skyCellMapRowAlloc(const char *skycell_id, const char *tess_id, const char *exp_tag, const char *class_id)
    16217 {
    16218     skyCellMapRow   *_object;
    16219 
    16220     _object = psAlloc(sizeof(skyCellMapRow));
    16221     psMemSetDeallocator(_object, (psFreeFunc)skyCellMapRowFree);
    16222 
    16223     _object->skycell_id = psStringCopy(skycell_id);
    16224     _object->tess_id = psStringCopy(tess_id);
    16225     _object->exp_tag = psStringCopy(exp_tag);
    16226     _object->class_id = psStringCopy(class_id);
    16227 
    16228     return _object;
    16229 }
    16230 
    16231 static void skyCellMapRowFree(skyCellMapRow *object)
    16232 {
    16233     psFree(object->skycell_id);
    16234     psFree(object->tess_id);
    16235     psFree(object->exp_tag);
    16236     psFree(object->class_id);
    16237 }
    16238 
    16239 bool skyCellMapCreateTable(psDB *dbh)
    16240 {
    16241     psMetadata *md = psMetadataAlloc();
    16242     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, "Primary Key", "64")) {
    16243         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    16244         psFree(md);
    16245         return false;
    16246     }
    16247     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, "Primary Key", "64")) {
    16248         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    16249         psFree(md);
    16250         return false;
    16251     }
    16252     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
    16253         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
    16254         psFree(md);
    16255         return false;
    16256     }
    16257     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
    16258         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    16259         psFree(md);
    16260         return false;
    16261     }
    16262 
    16263     bool status = psDBCreateTable(dbh, SKYCELLMAP_TABLE_NAME, md);
    16264 
    16265     psFree(md);
    16266 
    16267     return status;
    16268 }
    16269 
    16270 bool skyCellMapDropTable(psDB *dbh)
    16271 {
    16272     return psDBDropTable(dbh, SKYCELLMAP_TABLE_NAME);
    16273 }
    16274 
    16275 bool skyCellMapInsert(psDB * dbh, const char *skycell_id, const char *tess_id, const char *exp_tag, const char *class_id)
    16276 {
    16277     psMetadata *md = psMetadataAlloc();
    16278     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) {
    16279         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    16280         psFree(md);
    16281         return false;
    16282     }
    16283     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) {
    16284         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    16285         psFree(md);
    16286         return false;
    16287     }
    16288     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
    16289         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
    16290         psFree(md);
    16291         return false;
    16292     }
    16293     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
    16294         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    16295         psFree(md);
    16296         return false;
    16297     }
    16298 
    16299     bool status = psDBInsertOneRow(dbh, SKYCELLMAP_TABLE_NAME, md);
    16300     psFree(md);
    16301 
    16302     return status;
    16303 }
    16304 
    16305 long long skyCellMapDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    16306 {
    16307     long long       deleted = 0;
    16308 
    16309     long long count = psDBDeleteRows(dbh, SKYCELLMAP_TABLE_NAME, where, limit);
    16310     if (count < 0) {
    16311         psError(PS_ERR_UNKNOWN, true, "failed to delete row from skyCellMap");
    16312         return count;
    16313 
    16314         deleted += count;
    16315     }
    16316 
    16317     return deleted;
    16318 }
    16319 bool skyCellMapInsertObject(psDB *dbh, skyCellMapRow *object)
    16320 {
    16321     return skyCellMapInsert(dbh, object->skycell_id, object->tess_id, object->exp_tag, object->class_id);
    16322 }
    16323 
    16324 bool skyCellMapInsertObjects(psDB *dbh, psArray *objects)
    16325 {
    16326     for (long i = 0; i < psArrayLength(objects); i++) {
    16327         if (!skyCellMapInsertObject(dbh, objects->data[i])) {
    16328             return false;
    16329         }
    16330     }
    16331 
    16332     return true;
    16333 }
    16334 
    16335 bool skyCellMapInsertFits(psDB *dbh, const psFits *fits)
    16336 {
    16337     psArray         *rowSet;
    16338 
    16339     // move to (the first?) extension named  SKYCELLMAP_TABLE_NAME
    16340     if (!psFitsMoveExtName(fits, SKYCELLMAP_TABLE_NAME)) {
    16341         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", SKYCELLMAP_TABLE_NAME);
    16342         return false;
    16343     }
    16344 
    16345     // check HDU type
    16346     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    16347         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    16348         return false;
    16349     }
    16350 
    16351     // read fits table
    16352     rowSet = psFitsReadTable(fits);
    16353     if (!rowSet) {
    16354         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    16355         psFree(rowSet);
    16356         return false;
    16357     }
    16358 
    16359     if (!psDBInsertRows(dbh, SKYCELLMAP_TABLE_NAME, rowSet)) {
    16360         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    16361         psFree(rowSet);
    16362         return false;
    16363     }
    16364 
    16365     psFree(rowSet);
    16366 
    16367     return true;
    16368 }
    16369 
    16370 bool skyCellMapSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    16371 {
    16372     psArray         *rowSet;
    16373 
    16374     rowSet = psDBSelectRows(dbh, SKYCELLMAP_TABLE_NAME, where, limit);
    16375     if (!rowSet) {
    16376         return false;
    16377     }
    16378 
    16379     // output to fits
    16380     if (!psFitsWriteTable(fits, NULL, rowSet, SKYCELLMAP_TABLE_NAME)) {
    16381         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    16382         psFree(rowSet);
    16383         return false;
    16384     }
    16385 
    16386     psFree(rowSet);
    16387 
    16388     return true;
    16389 }
    16390 
    16391 psMetadata *skyCellMapMetadataFromObject(const skyCellMapRow *object)
    16392 {
    16393     psMetadata *md = psMetadataAlloc();
    16394     if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) {
    16395         psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
    16396         psFree(md);
    16397         return false;
    16398     }
    16399     if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) {
    16400         psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
    16401         psFree(md);
    16402         return false;
    16403     }
    16404     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
    16405         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
    16406         psFree(md);
    16407         return false;
    16408     }
    16409     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) {
    16410         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    16411         psFree(md);
    16412         return false;
    16413     }
    16414 
    16415 
    16416     return md;
    16417 }
    16418 
    16419 skyCellMapRow *skyCellMapObjectFromMetadata(psMetadata *md)
    16420 {
    16421 
    16422 bool status = false;
    16423     char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id");
    16424     if (!status) {
    16425         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id");
    16426         return false;
    16427     }
    16428     char* tess_id = psMetadataLookupPtr(&status, md, "tess_id");
    16429     if (!status) {
    16430         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id");
    16431         return false;
    16432     }
    16433     char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
    16434     if (!status) {
    16435         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
    16436         return false;
    16437     }
    16438     char* class_id = psMetadataLookupPtr(&status, md, "class_id");
    16439     if (!status) {
    16440         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id");
    16441         return false;
    16442     }
    16443 
    16444     return skyCellMapRowAlloc(skycell_id, tess_id, exp_tag, class_id);
    16445 }
    16446 psArray *skyCellMapSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    16447 {
    16448     psArray         *rowSet;
    16449     psArray         *returnSet;
    16450     psU64           i;
    16451 
    16452     rowSet = psDBSelectRows(dbh, SKYCELLMAP_TABLE_NAME, where, limit);
    16453     if (!rowSet) {
    16454         return NULL;
    16455     }
    16456 
    16457     // convert psMetadata rows to row objects
    16458 
    16459     returnSet = psArrayAllocEmpty(rowSet->n);
    16460 
    16461     for (i = 0; i < rowSet->n; i++) {
    16462         skyCellMapRow *object = skyCellMapObjectFromMetadata(rowSet->data[i]);
    16463         psArrayAdd(returnSet, 0, object);
    16464         psFree(object);
    16465     }
    16466 
    16467     psFree(rowSet);
    16468 
    16469     return returnSet;
    16470 }
    16471 bool skyCellMapDeleteObject(psDB *dbh, const skyCellMapRow *object)
    16472 {
    16473     psMetadata *where = skyCellMapMetadataFromObject(object);
    16474     long long count = psDBDeleteRows(dbh, SKYCELLMAP_TABLE_NAME, where, 0);
    16475     psFree(where);
    16476     if (count < 0) {
    16477         psError(PS_ERR_UNKNOWN, true, "failed to delete row from skyCellMap");
    16478         return false;
    16479     }
    16480     if (count > 1) {
    16481         // XXX should this be a psAbort() instead?  It is possible that
    16482         // having an object match multiple rows was by design.
    16483         psError(PS_ERR_UNKNOWN, true, "skyCellMapRow object matched more then one row.  Check your database schema");
    16484         return false;
    16485     }
    16486 
    16487     return true;
    16488 }
    16489 long long skyCellMapDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    16490 {
    16491     long long       deleted = 0;
    16492 
    16493     for (long long i = 0; i < objects->n; i++) {
    16494         skyCellMapRow *object = objects->data[i];
    16495         psMetadata *where = skyCellMapMetadataFromObject(object);
    16496         long long count = psDBDeleteRows(dbh, SKYCELLMAP_TABLE_NAME, where, limit);
    16497         psFree(where);
    16498         if (count < 0) {
    16499             psError(PS_ERR_UNKNOWN, true, "failed to delete row from skyCellMap");
    16500             return count;
    16501         }
    16502 
    16503         deleted += count;
    16504     }
    16505 
    16506     return deleted;
    16507 }
    16508 bool skyCellMapPrintObjects(FILE *stream, psArray *objects, bool mdcf)
    16509 {
    16510     PS_ASSERT_PTR_NON_NULL(objects, false);
    16511 
    16512     psMetadata *output = psMetadataAlloc();
    16513     for (long i = 0; i < psArrayLength(objects); i++) {
    16514         psMetadata *md = skyCellMapMetadataFromObject(objects->data[i]);
    16515         if (!psMetadataAddMetadata(
    16516             output,
    16517             PS_LIST_TAIL,
    16518             SKYCELLMAP_TABLE_NAME,
    16519             PS_META_DUPLICATE_OK,
    16520             NULL,
    16521             md
    16522         )) {
    16523             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    16524             psFree(md);
    16525             psFree(output);
    16526             return false;
    16527         }
    16528         psFree(md);
    16529     }
    16530 
    16531     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    16532         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    16533         psFree(output);
    16534     }
    16535     psFree(output);
    16536 
    16537     return true;
    16538 }
    16539 bool skyCellMapPrintObject(FILE *stream, skyCellMapRow *object, bool mdcf)
    16540 {
    16541     PS_ASSERT_PTR_NON_NULL(object, false);
    16542 
    16543     psMetadata *md = skyCellMapMetadataFromObject(object);
    16544 
    16545     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    16546         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    16547         psFree(md);
    16548     }
    16549 
    16550     psFree(md);
    16551 
    16552     return true;
    16553 }
Note: See TracChangeset for help on using the changeset viewer.