IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 21, 2008, 6:09:25 PM (18 years ago)
Author:
jhoblitt
Message:

update

File:
1 edited

Legend:

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

    r16177 r16587  
    3434#define SUMMITEXP_TABLE_NAME "summitExp"
    3535#define SUMMITIMFILE_TABLE_NAME "summitImfile"
    36 #define PZPENDINGEXP_TABLE_NAME "pzPendingExp"
    37 #define PZPENDINGIMFILE_TABLE_NAME "pzPendingImfile"
    38 #define PZDONEEXP_TABLE_NAME "pzDoneExp"
    39 #define PZDONEIMFILE_TABLE_NAME "pzDoneImfile"
     36#define PZDOWNLOADEXP_TABLE_NAME "pzDownloadExp"
     37#define PZDOWNLOADIMFILE_TABLE_NAME "pzDownloadImfile"
    4038#define NEWEXP_TABLE_NAME "newExp"
    4139#define NEWIMFILE_TABLE_NAME "newImfile"
     
    8381#define FLATCORRRUN_TABLE_NAME "flatcorrRun"
    8482#define FLATCORREXP_TABLE_NAME "flatcorrExp"
     83#define PSTAMPDATASTORE_TABLE_NAME "pstampDataStore"
     84#define PSTAMPREQUEST_TABLE_NAME "pstampRequest"
     85#define PSTAMPJOB_TABLE_NAME "pstampJob"
    8586#define MAX_STRING_LENGTH 1024
    8687
     
    10311032{
    10321033    psMetadata *md = psMetadataAlloc();
    1033     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, "Primary Key", "64")) {
     1034    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, "Primary Key fkey(exp_name, camera, telescope) ref summitExp(exp_name, camera, telescope)", "64")) {
    10341035        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
    10351036        psFree(md);
     
    14491450    return true;
    14501451}
    1451 static void pzPendingExpRowFree(pzPendingExpRow *object);
    1452 
    1453 pzPendingExpRow *pzPendingExpRowAlloc(const char *exp_name, const char *camera, const char *telescope)
    1454 {
    1455     pzPendingExpRow *_object;
    1456 
    1457     _object = psAlloc(sizeof(pzPendingExpRow));
    1458     psMemSetDeallocator(_object, (psFreeFunc)pzPendingExpRowFree);
     1452static void pzDownloadExpRowFree(pzDownloadExpRow *object);
     1453
     1454pzDownloadExpRow *pzDownloadExpRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *state)
     1455{
     1456    pzDownloadExpRow *_object;
     1457
     1458    _object = psAlloc(sizeof(pzDownloadExpRow));
     1459    psMemSetDeallocator(_object, (psFreeFunc)pzDownloadExpRowFree);
    14591460
    14601461    _object->exp_name = psStringCopy(exp_name);
    14611462    _object->camera = psStringCopy(camera);
    14621463    _object->telescope = psStringCopy(telescope);
     1464    _object->state = psStringCopy(state);
    14631465
    14641466    return _object;
    14651467}
    14661468
    1467 static void pzPendingExpRowFree(pzPendingExpRow *object)
     1469static void pzDownloadExpRowFree(pzDownloadExpRow *object)
    14681470{
    14691471    psFree(object->exp_name);
    14701472    psFree(object->camera);
    14711473    psFree(object->telescope);
    1472 }
    1473 
    1474 bool pzPendingExpCreateTable(psDB *dbh)
     1474    psFree(object->state);
     1475}
     1476
     1477bool pzDownloadExpCreateTable(psDB *dbh)
    14751478{
    14761479    psMetadata *md = psMetadataAlloc();
    1477     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, "Primary Key", "64")) {
     1480    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, "Primary Key fkey(exp_name, camera, telescope) ref summitExp(exp_name, camera, telescope)", "64")) {
    14781481        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
    14791482        psFree(md);
     
    14901493        return false;
    14911494    }
    1492 
    1493     bool status = psDBCreateTable(dbh, PZPENDINGEXP_TABLE_NAME, md);
     1495    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, "Key", "64")) {
     1496        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     1497        psFree(md);
     1498        return false;
     1499    }
     1500
     1501    bool status = psDBCreateTable(dbh, PZDOWNLOADEXP_TABLE_NAME, md);
    14941502
    14951503    psFree(md);
     
    14981506}
    14991507
    1500 bool pzPendingExpDropTable(psDB *dbh)
    1501 {
    1502     return psDBDropTable(dbh, PZPENDINGEXP_TABLE_NAME);
    1503 }
    1504 
    1505 bool pzPendingExpInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope)
     1508bool pzDownloadExpDropTable(psDB *dbh)
     1509{
     1510    return psDBDropTable(dbh, PZDOWNLOADEXP_TABLE_NAME);
     1511}
     1512
     1513bool pzDownloadExpInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *state)
    15061514{
    15071515    psMetadata *md = psMetadataAlloc();
     
    15211529        return false;
    15221530    }
    1523 
    1524     bool status = psDBInsertOneRow(dbh, PZPENDINGEXP_TABLE_NAME, md);
     1531    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, state)) {
     1532        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     1533        psFree(md);
     1534        return false;
     1535    }
     1536
     1537    bool status = psDBInsertOneRow(dbh, PZDOWNLOADEXP_TABLE_NAME, md);
    15251538    psFree(md);
    15261539
     
    15281541}
    15291542
    1530 long long pzPendingExpDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
     1543long long pzDownloadExpDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    15311544{
    15321545    long long       deleted = 0;
    15331546
    1534     long long count = psDBDeleteRows(dbh, PZPENDINGEXP_TABLE_NAME, where, limit);
     1547    long long count = psDBDeleteRows(dbh, PZDOWNLOADEXP_TABLE_NAME, where, limit);
    15351548    if (count < 0) {
    1536         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingExp");
     1549        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDownloadExp");
    15371550        return count;
    15381551
     
    15421555    return deleted;
    15431556}
    1544 bool pzPendingExpInsertObject(psDB *dbh, pzPendingExpRow *object)
    1545 {
    1546     return pzPendingExpInsert(dbh, object->exp_name, object->camera, object->telescope);
    1547 }
    1548 
    1549 bool pzPendingExpInsertObjects(psDB *dbh, psArray *objects)
     1557bool pzDownloadExpInsertObject(psDB *dbh, pzDownloadExpRow *object)
     1558{
     1559    return pzDownloadExpInsert(dbh, object->exp_name, object->camera, object->telescope, object->state);
     1560}
     1561
     1562bool pzDownloadExpInsertObjects(psDB *dbh, psArray *objects)
    15501563{
    15511564    for (long i = 0; i < psArrayLength(objects); i++) {
    1552         if (!pzPendingExpInsertObject(dbh, objects->data[i])) {
     1565        if (!pzDownloadExpInsertObject(dbh, objects->data[i])) {
    15531566            return false;
    15541567        }
     
    15581571}
    15591572
    1560 bool pzPendingExpInsertFits(psDB *dbh, const psFits *fits)
     1573bool pzDownloadExpInsertFits(psDB *dbh, const psFits *fits)
    15611574{
    15621575    psArray         *rowSet;
    15631576
    1564     // move to (the first?) extension named  PZPENDINGEXP_TABLE_NAME
    1565     if (!psFitsMoveExtName(fits, PZPENDINGEXP_TABLE_NAME)) {
    1566         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PZPENDINGEXP_TABLE_NAME);
     1577    // move to (the first?) extension named  PZDOWNLOADEXP_TABLE_NAME
     1578    if (!psFitsMoveExtName(fits, PZDOWNLOADEXP_TABLE_NAME)) {
     1579        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PZDOWNLOADEXP_TABLE_NAME);
    15671580        return false;
    15681581    }
     
    15821595    }
    15831596
    1584     if (!psDBInsertRows(dbh, PZPENDINGEXP_TABLE_NAME, rowSet)) {
     1597    if (!psDBInsertRows(dbh, PZDOWNLOADEXP_TABLE_NAME, rowSet)) {
    15851598        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    15861599        psFree(rowSet);
     
    15931606}
    15941607
    1595 bool pzPendingExpSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
     1608bool pzDownloadExpSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    15961609{
    15971610    psArray         *rowSet;
    15981611
    1599     rowSet = psDBSelectRows(dbh, PZPENDINGEXP_TABLE_NAME, where, limit);
     1612    rowSet = psDBSelectRows(dbh, PZDOWNLOADEXP_TABLE_NAME, where, limit);
    16001613    if (!rowSet) {
    16011614        return false;
     
    16031616
    16041617    // output to fits
    1605     if (!psFitsWriteTable(fits, NULL, rowSet, PZPENDINGEXP_TABLE_NAME)) {
     1618    if (!psFitsWriteTable(fits, NULL, rowSet, PZDOWNLOADEXP_TABLE_NAME)) {
    16061619        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    16071620        psFree(rowSet);
     
    16141627}
    16151628
    1616 psMetadata *pzPendingExpMetadataFromObject(const pzPendingExpRow *object)
     1629psMetadata *pzDownloadExpMetadataFromObject(const pzDownloadExpRow *object)
    16171630{
    16181631    psMetadata *md = psMetadataAlloc();
     
    16321645        return false;
    16331646    }
     1647    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
     1648        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     1649        psFree(md);
     1650        return false;
     1651    }
    16341652
    16351653
     
    16371655}
    16381656
    1639 pzPendingExpRow *pzPendingExpObjectFromMetadata(psMetadata *md)
     1657pzDownloadExpRow *pzDownloadExpObjectFromMetadata(psMetadata *md)
    16401658{
    16411659
     
    16561674        return false;
    16571675    }
    1658 
    1659     return pzPendingExpRowAlloc(exp_name, camera, telescope);
    1660 }
    1661 psArray *pzPendingExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     1676    char* state = psMetadataLookupPtr(&status, md, "state");
     1677    if (!status) {
     1678        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
     1679        return false;
     1680    }
     1681
     1682    return pzDownloadExpRowAlloc(exp_name, camera, telescope, state);
     1683}
     1684psArray *pzDownloadExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    16621685{
    16631686    psArray         *rowSet;
     
    16651688    psU64           i;
    16661689
    1667     rowSet = psDBSelectRows(dbh, PZPENDINGEXP_TABLE_NAME, where, limit);
     1690    rowSet = psDBSelectRows(dbh, PZDOWNLOADEXP_TABLE_NAME, where, limit);
    16681691    if (!rowSet) {
    16691692        return NULL;
     
    16751698
    16761699    for (i = 0; i < rowSet->n; i++) {
    1677         pzPendingExpRow *object = pzPendingExpObjectFromMetadata(rowSet->data[i]);
     1700        pzDownloadExpRow *object = pzDownloadExpObjectFromMetadata(rowSet->data[i]);
    16781701        if (!object) {
    16791702            psFree(object);
     
    16901713    return returnSet;
    16911714}
    1692 bool pzPendingExpDeleteObject(psDB *dbh, const pzPendingExpRow *object)
    1693 {
    1694     psMetadata *where = pzPendingExpMetadataFromObject(object);
    1695     long long count = psDBDeleteRows(dbh, PZPENDINGEXP_TABLE_NAME, where, 0);
     1715bool pzDownloadExpDeleteObject(psDB *dbh, const pzDownloadExpRow *object)
     1716{
     1717    psMetadata *where = pzDownloadExpMetadataFromObject(object);
     1718    long long count = psDBDeleteRows(dbh, PZDOWNLOADEXP_TABLE_NAME, where, 0);
    16961719    psFree(where);
    16971720    if (count < 0) {
    1698         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingExp");
     1721        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDownloadExp");
    16991722        return false;
    17001723    }
     
    17021725        // XXX should this be a psAbort() instead?  It is possible that
    17031726        // having an object match multiple rows was by design.
    1704         psError(PS_ERR_UNKNOWN, true, "pzPendingExpRow object matched more then one row.  Check your database schema");
    1705         return false;
    1706     }
    1707 
    1708     return true;
    1709 }
    1710 long long pzPendingExpDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
     1727        psError(PS_ERR_UNKNOWN, true, "pzDownloadExpRow object matched more then one row.  Check your database schema");
     1728        return false;
     1729    }
     1730
     1731    return true;
     1732}
     1733long long pzDownloadExpDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    17111734{
    17121735    long long       deleted = 0;
    17131736
    17141737    for (long long i = 0; i < objects->n; i++) {
    1715         pzPendingExpRow *object = objects->data[i];
    1716         psMetadata *where = pzPendingExpMetadataFromObject(object);
    1717         long long count = psDBDeleteRows(dbh, PZPENDINGEXP_TABLE_NAME, where, limit);
     1738        pzDownloadExpRow *object = objects->data[i];
     1739        psMetadata *where = pzDownloadExpMetadataFromObject(object);
     1740        long long count = psDBDeleteRows(dbh, PZDOWNLOADEXP_TABLE_NAME, where, limit);
    17181741        psFree(where);
    17191742        if (count < 0) {
    1720             psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingExp");
     1743            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDownloadExp");
    17211744            return count;
    17221745        }
     
    17271750    return deleted;
    17281751}
    1729 bool pzPendingExpPrintObjects(FILE *stream, psArray *objects, bool mdcf)
     1752bool pzDownloadExpPrintObjects(FILE *stream, psArray *objects, bool mdcf)
    17301753{
    17311754    PS_ASSERT_PTR_NON_NULL(objects, false);
     
    17331756    psMetadata *output = psMetadataAlloc();
    17341757    for (long i = 0; i < psArrayLength(objects); i++) {
    1735         psMetadata *md = pzPendingExpMetadataFromObject(objects->data[i]);
     1758        psMetadata *md = pzDownloadExpMetadataFromObject(objects->data[i]);
    17361759        if (!psMetadataAddMetadata(
    17371760            output,
    17381761            PS_LIST_TAIL,
    1739             PZPENDINGEXP_TABLE_NAME,
     1762            PZDOWNLOADEXP_TABLE_NAME,
    17401763            PS_META_DUPLICATE_OK,
    17411764            NULL,
     
    17581781    return true;
    17591782}
    1760 bool pzPendingExpPrintObject(FILE *stream, pzPendingExpRow *object, bool mdcf)
     1783bool pzDownloadExpPrintObject(FILE *stream, pzDownloadExpRow *object, bool mdcf)
    17611784{
    17621785    PS_ASSERT_PTR_NON_NULL(object, false);
    17631786
    1764     psMetadata *md = pzPendingExpMetadataFromObject(object);
     1787    psMetadata *md = pzDownloadExpMetadataFromObject(object);
    17651788
    17661789    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
     
    17731796    return true;
    17741797}
    1775 static void pzPendingImfileRowFree(pzPendingImfileRow *object);
    1776 
    1777 pzPendingImfileRow *pzPendingImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id)
    1778 {
    1779     pzPendingImfileRow *_object;
    1780 
    1781     _object = psAlloc(sizeof(pzPendingImfileRow));
    1782     psMemSetDeallocator(_object, (psFreeFunc)pzPendingImfileRowFree);
     1798static void pzDownloadImfileRowFree(pzDownloadImfileRow *object);
     1799
     1800pzDownloadImfileRow *pzDownloadImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, const char *uri, psS16 fault)
     1801{
     1802    pzDownloadImfileRow *_object;
     1803
     1804    _object = psAlloc(sizeof(pzDownloadImfileRow));
     1805    psMemSetDeallocator(_object, (psFreeFunc)pzDownloadImfileRowFree);
    17831806
    17841807    _object->exp_name = psStringCopy(exp_name);
     
    17871810    _object->class = psStringCopy(class);
    17881811    _object->class_id = psStringCopy(class_id);
     1812    _object->uri = psStringCopy(uri);
     1813    _object->fault = fault;
    17891814
    17901815    return _object;
    17911816}
    17921817
    1793 static void pzPendingImfileRowFree(pzPendingImfileRow *object)
     1818static void pzDownloadImfileRowFree(pzDownloadImfileRow *object)
    17941819{
    17951820    psFree(object->exp_name);
     
    17981823    psFree(object->class);
    17991824    psFree(object->class_id);
    1800 }
    1801 
    1802 bool pzPendingImfileCreateTable(psDB *dbh)
     1825    psFree(object->uri);
     1826}
     1827
     1828bool pzDownloadImfileCreateTable(psDB *dbh)
    18031829{
    18041830    psMetadata *md = psMetadataAlloc();
    1805     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, "Primary Key", "64")) {
     1831    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, "Primary Key fkey(exp_name, camera, telescope) ref pzDownloadExp(exp_name, camera, telescope)", "64")) {
    18061832        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
    18071833        psFree(md);
    18081834        return false;
    18091835    }
    1810     if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, "Primary Key", "64")) {
     1836    if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, "Primary Key fkey(exp_name, camera, telescope, class, class_id) ref summitImfile(exp_name, camera, telescope, class, class_id)", "64")) {
    18111837        psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
    18121838        psFree(md);
     
    18281854        return false;
    18291855    }
    1830 
    1831     bool status = psDBCreateTable(dbh, PZPENDINGIMFILE_TABLE_NAME, md);
     1856    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
     1857        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     1858        psFree(md);
     1859        return false;
     1860    }
     1861    if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, "Key NOT NULL", 0)) {
     1862        psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
     1863        psFree(md);
     1864        return false;
     1865    }
     1866
     1867    bool status = psDBCreateTable(dbh, PZDOWNLOADIMFILE_TABLE_NAME, md);
    18321868
    18331869    psFree(md);
     
    18361872}
    18371873
    1838 bool pzPendingImfileDropTable(psDB *dbh)
    1839 {
    1840     return psDBDropTable(dbh, PZPENDINGIMFILE_TABLE_NAME);
    1841 }
    1842 
    1843 bool pzPendingImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id)
     1874bool pzDownloadImfileDropTable(psDB *dbh)
     1875{
     1876    return psDBDropTable(dbh, PZDOWNLOADIMFILE_TABLE_NAME);
     1877}
     1878
     1879bool pzDownloadImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, const char *uri, psS16 fault)
    18441880{
    18451881    psMetadata *md = psMetadataAlloc();
     
    18691905        return false;
    18701906    }
    1871 
    1872     bool status = psDBInsertOneRow(dbh, PZPENDINGIMFILE_TABLE_NAME, md);
     1907    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
     1908        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     1909        psFree(md);
     1910        return false;
     1911    }
     1912    if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, fault)) {
     1913        psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
     1914        psFree(md);
     1915        return false;
     1916    }
     1917
     1918    bool status = psDBInsertOneRow(dbh, PZDOWNLOADIMFILE_TABLE_NAME, md);
    18731919    psFree(md);
    18741920
     
    18761922}
    18771923
    1878 long long pzPendingImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
     1924long long pzDownloadImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    18791925{
    18801926    long long       deleted = 0;
    18811927
    1882     long long count = psDBDeleteRows(dbh, PZPENDINGIMFILE_TABLE_NAME, where, limit);
     1928    long long count = psDBDeleteRows(dbh, PZDOWNLOADIMFILE_TABLE_NAME, where, limit);
    18831929    if (count < 0) {
    1884         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingImfile");
     1930        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDownloadImfile");
    18851931        return count;
    18861932
     
    18901936    return deleted;
    18911937}
    1892 bool pzPendingImfileInsertObject(psDB *dbh, pzPendingImfileRow *object)
    1893 {
    1894     return pzPendingImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id);
    1895 }
    1896 
    1897 bool pzPendingImfileInsertObjects(psDB *dbh, psArray *objects)
     1938bool pzDownloadImfileInsertObject(psDB *dbh, pzDownloadImfileRow *object)
     1939{
     1940    return pzDownloadImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id, object->uri, object->fault);
     1941}
     1942
     1943bool pzDownloadImfileInsertObjects(psDB *dbh, psArray *objects)
    18981944{
    18991945    for (long i = 0; i < psArrayLength(objects); i++) {
    1900         if (!pzPendingImfileInsertObject(dbh, objects->data[i])) {
     1946        if (!pzDownloadImfileInsertObject(dbh, objects->data[i])) {
    19011947            return false;
    19021948        }
     
    19061952}
    19071953
    1908 bool pzPendingImfileInsertFits(psDB *dbh, const psFits *fits)
     1954bool pzDownloadImfileInsertFits(psDB *dbh, const psFits *fits)
    19091955{
    19101956    psArray         *rowSet;
    19111957
    1912     // move to (the first?) extension named  PZPENDINGIMFILE_TABLE_NAME
    1913     if (!psFitsMoveExtName(fits, PZPENDINGIMFILE_TABLE_NAME)) {
    1914         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PZPENDINGIMFILE_TABLE_NAME);
     1958    // move to (the first?) extension named  PZDOWNLOADIMFILE_TABLE_NAME
     1959    if (!psFitsMoveExtName(fits, PZDOWNLOADIMFILE_TABLE_NAME)) {
     1960        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PZDOWNLOADIMFILE_TABLE_NAME);
    19151961        return false;
    19161962    }
     
    19301976    }
    19311977
    1932     if (!psDBInsertRows(dbh, PZPENDINGIMFILE_TABLE_NAME, rowSet)) {
     1978    if (!psDBInsertRows(dbh, PZDOWNLOADIMFILE_TABLE_NAME, rowSet)) {
    19331979        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    19341980        psFree(rowSet);
     
    19411987}
    19421988
    1943 bool pzPendingImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
     1989bool pzDownloadImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    19441990{
    19451991    psArray         *rowSet;
    19461992
    1947     rowSet = psDBSelectRows(dbh, PZPENDINGIMFILE_TABLE_NAME, where, limit);
     1993    rowSet = psDBSelectRows(dbh, PZDOWNLOADIMFILE_TABLE_NAME, where, limit);
    19481994    if (!rowSet) {
    19491995        return false;
     
    19511997
    19521998    // output to fits
    1953     if (!psFitsWriteTable(fits, NULL, rowSet, PZPENDINGIMFILE_TABLE_NAME)) {
     1999    if (!psFitsWriteTable(fits, NULL, rowSet, PZDOWNLOADIMFILE_TABLE_NAME)) {
    19542000        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    19552001        psFree(rowSet);
     
    19622008}
    19632009
    1964 psMetadata *pzPendingImfileMetadataFromObject(const pzPendingImfileRow *object)
     2010psMetadata *pzDownloadImfileMetadataFromObject(const pzDownloadImfileRow *object)
    19652011{
    19662012    psMetadata *md = psMetadataAlloc();
     
    19902036        return false;
    19912037    }
     2038    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
     2039        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     2040        psFree(md);
     2041        return false;
     2042    }
     2043    if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, object->fault)) {
     2044        psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
     2045        psFree(md);
     2046        return false;
     2047    }
    19922048
    19932049
     
    19952051}
    19962052
    1997 pzPendingImfileRow *pzPendingImfileObjectFromMetadata(psMetadata *md)
     2053pzDownloadImfileRow *pzDownloadImfileObjectFromMetadata(psMetadata *md)
    19982054{
    19992055
     
    20242080        return false;
    20252081    }
    2026 
    2027     return pzPendingImfileRowAlloc(exp_name, camera, telescope, class, class_id);
    2028 }
    2029 psArray *pzPendingImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     2082    char* uri = psMetadataLookupPtr(&status, md, "uri");
     2083    if (!status) {
     2084        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
     2085        return false;
     2086    }
     2087    psS16 fault = psMetadataLookupS16(&status, md, "fault");
     2088    if (!status) {
     2089        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fault");
     2090        return false;
     2091    }
     2092
     2093    return pzDownloadImfileRowAlloc(exp_name, camera, telescope, class, class_id, uri, fault);
     2094}
     2095psArray *pzDownloadImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    20302096{
    20312097    psArray         *rowSet;
     
    20332099    psU64           i;
    20342100
    2035     rowSet = psDBSelectRows(dbh, PZPENDINGIMFILE_TABLE_NAME, where, limit);
     2101    rowSet = psDBSelectRows(dbh, PZDOWNLOADIMFILE_TABLE_NAME, where, limit);
    20362102    if (!rowSet) {
    20372103        return NULL;
     
    20432109
    20442110    for (i = 0; i < rowSet->n; i++) {
    2045         pzPendingImfileRow *object = pzPendingImfileObjectFromMetadata(rowSet->data[i]);
     2111        pzDownloadImfileRow *object = pzDownloadImfileObjectFromMetadata(rowSet->data[i]);
    20462112        if (!object) {
    20472113            psFree(object);
     
    20582124    return returnSet;
    20592125}
    2060 bool pzPendingImfileDeleteObject(psDB *dbh, const pzPendingImfileRow *object)
    2061 {
    2062     psMetadata *where = pzPendingImfileMetadataFromObject(object);
    2063     long long count = psDBDeleteRows(dbh, PZPENDINGIMFILE_TABLE_NAME, where, 0);
     2126bool pzDownloadImfileDeleteObject(psDB *dbh, const pzDownloadImfileRow *object)
     2127{
     2128    psMetadata *where = pzDownloadImfileMetadataFromObject(object);
     2129    long long count = psDBDeleteRows(dbh, PZDOWNLOADIMFILE_TABLE_NAME, where, 0);
    20642130    psFree(where);
    20652131    if (count < 0) {
    2066         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingImfile");
     2132        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDownloadImfile");
    20672133        return false;
    20682134    }
     
    20702136        // XXX should this be a psAbort() instead?  It is possible that
    20712137        // having an object match multiple rows was by design.
    2072         psError(PS_ERR_UNKNOWN, true, "pzPendingImfileRow object matched more then one row.  Check your database schema");
    2073         return false;
    2074     }
    2075 
    2076     return true;
    2077 }
    2078 long long pzPendingImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
     2138        psError(PS_ERR_UNKNOWN, true, "pzDownloadImfileRow object matched more then one row.  Check your database schema");
     2139        return false;
     2140    }
     2141
     2142    return true;
     2143}
     2144long long pzDownloadImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    20792145{
    20802146    long long       deleted = 0;
    20812147
    20822148    for (long long i = 0; i < objects->n; i++) {
    2083         pzPendingImfileRow *object = objects->data[i];
    2084         psMetadata *where = pzPendingImfileMetadataFromObject(object);
    2085         long long count = psDBDeleteRows(dbh, PZPENDINGIMFILE_TABLE_NAME, where, limit);
     2149        pzDownloadImfileRow *object = objects->data[i];
     2150        psMetadata *where = pzDownloadImfileMetadataFromObject(object);
     2151        long long count = psDBDeleteRows(dbh, PZDOWNLOADIMFILE_TABLE_NAME, where, limit);
    20862152        psFree(where);
    20872153        if (count < 0) {
    2088             psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingImfile");
     2154            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDownloadImfile");
    20892155            return count;
    20902156        }
     
    20952161    return deleted;
    20962162}
    2097 bool pzPendingImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
     2163bool pzDownloadImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
    20982164{
    20992165    PS_ASSERT_PTR_NON_NULL(objects, false);
     
    21012167    psMetadata *output = psMetadataAlloc();
    21022168    for (long i = 0; i < psArrayLength(objects); i++) {
    2103         psMetadata *md = pzPendingImfileMetadataFromObject(objects->data[i]);
     2169        psMetadata *md = pzDownloadImfileMetadataFromObject(objects->data[i]);
    21042170        if (!psMetadataAddMetadata(
    21052171            output,
    21062172            PS_LIST_TAIL,
    2107             PZPENDINGIMFILE_TABLE_NAME,
     2173            PZDOWNLOADIMFILE_TABLE_NAME,
    21082174            PS_META_DUPLICATE_OK,
    21092175            NULL,
     
    21262192    return true;
    21272193}
    2128 bool pzPendingImfilePrintObject(FILE *stream, pzPendingImfileRow *object, bool mdcf)
     2194bool pzDownloadImfilePrintObject(FILE *stream, pzDownloadImfileRow *object, bool mdcf)
    21292195{
    21302196    PS_ASSERT_PTR_NON_NULL(object, false);
    21312197
    2132     psMetadata *md = pzPendingImfileMetadataFromObject(object);
     2198    psMetadata *md = pzDownloadImfileMetadataFromObject(object);
    21332199
    21342200    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
     
    21412207    return true;
    21422208}
    2143 static void pzDoneExpRowFree(pzDoneExpRow *object);
    2144 
    2145 pzDoneExpRow *pzDoneExpRowAlloc(const char *exp_name, const char *camera, const char *telescope)
    2146 {
    2147     pzDoneExpRow    *_object;
    2148 
    2149     _object = psAlloc(sizeof(pzDoneExpRow));
    2150     psMemSetDeallocator(_object, (psFreeFunc)pzDoneExpRowFree);
    2151 
    2152     _object->exp_name = psStringCopy(exp_name);
    2153     _object->camera = psStringCopy(camera);
    2154     _object->telescope = psStringCopy(telescope);
    2155 
    2156     return _object;
    2157 }
    2158 
    2159 static void pzDoneExpRowFree(pzDoneExpRow *object)
    2160 {
    2161     psFree(object->exp_name);
    2162     psFree(object->camera);
    2163     psFree(object->telescope);
    2164 }
    2165 
    2166 bool pzDoneExpCreateTable(psDB *dbh)
    2167 {
    2168     psMetadata *md = psMetadataAlloc();
    2169     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, "Primary Key", "64")) {
    2170         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
    2171         psFree(md);
    2172         return false;
    2173     }
    2174     if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, "Primary Key", "64")) {
    2175         psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
    2176         psFree(md);
    2177         return false;
    2178     }
    2179     if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, "Primary Key", "64")) {
    2180         psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
    2181         psFree(md);
    2182         return false;
    2183     }
    2184 
    2185     bool status = psDBCreateTable(dbh, PZDONEEXP_TABLE_NAME, md);
    2186 
    2187     psFree(md);
    2188 
    2189     return status;
    2190 }
    2191 
    2192 bool pzDoneExpDropTable(psDB *dbh)
    2193 {
    2194     return psDBDropTable(dbh, PZDONEEXP_TABLE_NAME);
    2195 }
    2196 
    2197 bool pzDoneExpInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope)
    2198 {
    2199     psMetadata *md = psMetadataAlloc();
    2200     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, NULL, exp_name)) {
    2201         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
    2202         psFree(md);
    2203         return false;
    2204     }
    2205     if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, NULL, camera)) {
    2206         psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
    2207         psFree(md);
    2208         return false;
    2209     }
    2210     if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, NULL, telescope)) {
    2211         psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
    2212         psFree(md);
    2213         return false;
    2214     }
    2215 
    2216     bool status = psDBInsertOneRow(dbh, PZDONEEXP_TABLE_NAME, md);
    2217     psFree(md);
    2218 
    2219     return status;
    2220 }
    2221 
    2222 long long pzDoneExpDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    2223 {
    2224     long long       deleted = 0;
    2225 
    2226     long long count = psDBDeleteRows(dbh, PZDONEEXP_TABLE_NAME, where, limit);
    2227     if (count < 0) {
    2228         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneExp");
    2229         return count;
    2230 
    2231         deleted += count;
    2232     }
    2233 
    2234     return deleted;
    2235 }
    2236 bool pzDoneExpInsertObject(psDB *dbh, pzDoneExpRow *object)
    2237 {
    2238     return pzDoneExpInsert(dbh, object->exp_name, object->camera, object->telescope);
    2239 }
    2240 
    2241 bool pzDoneExpInsertObjects(psDB *dbh, psArray *objects)
    2242 {
    2243     for (long i = 0; i < psArrayLength(objects); i++) {
    2244         if (!pzDoneExpInsertObject(dbh, objects->data[i])) {
    2245             return false;
    2246         }
    2247     }
    2248 
    2249     return true;
    2250 }
    2251 
    2252 bool pzDoneExpInsertFits(psDB *dbh, const psFits *fits)
    2253 {
    2254     psArray         *rowSet;
    2255 
    2256     // move to (the first?) extension named  PZDONEEXP_TABLE_NAME
    2257     if (!psFitsMoveExtName(fits, PZDONEEXP_TABLE_NAME)) {
    2258         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PZDONEEXP_TABLE_NAME);
    2259         return false;
    2260     }
    2261 
    2262     // check HDU type
    2263     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    2264         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    2265         return false;
    2266     }
    2267 
    2268     // read fits table
    2269     rowSet = psFitsReadTable(fits);
    2270     if (!rowSet) {
    2271         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    2272         psFree(rowSet);
    2273         return false;
    2274     }
    2275 
    2276     if (!psDBInsertRows(dbh, PZDONEEXP_TABLE_NAME, rowSet)) {
    2277         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    2278         psFree(rowSet);
    2279         return false;
    2280     }
    2281 
    2282     psFree(rowSet);
    2283 
    2284     return true;
    2285 }
    2286 
    2287 bool pzDoneExpSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    2288 {
    2289     psArray         *rowSet;
    2290 
    2291     rowSet = psDBSelectRows(dbh, PZDONEEXP_TABLE_NAME, where, limit);
    2292     if (!rowSet) {
    2293         return false;
    2294     }
    2295 
    2296     // output to fits
    2297     if (!psFitsWriteTable(fits, NULL, rowSet, PZDONEEXP_TABLE_NAME)) {
    2298         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    2299         psFree(rowSet);
    2300         return false;
    2301     }
    2302 
    2303     psFree(rowSet);
    2304 
    2305     return true;
    2306 }
    2307 
    2308 psMetadata *pzDoneExpMetadataFromObject(const pzDoneExpRow *object)
    2309 {
    2310     psMetadata *md = psMetadataAlloc();
    2311     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, NULL, object->exp_name)) {
    2312         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
    2313         psFree(md);
    2314         return false;
    2315     }
    2316     if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, NULL, object->camera)) {
    2317         psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
    2318         psFree(md);
    2319         return false;
    2320     }
    2321     if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, NULL, object->telescope)) {
    2322         psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
    2323         psFree(md);
    2324         return false;
    2325     }
    2326 
    2327 
    2328     return md;
    2329 }
    2330 
    2331 pzDoneExpRow *pzDoneExpObjectFromMetadata(psMetadata *md)
    2332 {
    2333 
    2334 bool status = false;
    2335     char* exp_name = psMetadataLookupPtr(&status, md, "exp_name");
    2336     if (!status) {
    2337         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_name");
    2338         return false;
    2339     }
    2340     char* camera = psMetadataLookupPtr(&status, md, "camera");
    2341     if (!status) {
    2342         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item camera");
    2343         return false;
    2344     }
    2345     char* telescope = psMetadataLookupPtr(&status, md, "telescope");
    2346     if (!status) {
    2347         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item telescope");
    2348         return false;
    2349     }
    2350 
    2351     return pzDoneExpRowAlloc(exp_name, camera, telescope);
    2352 }
    2353 psArray *pzDoneExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    2354 {
    2355     psArray         *rowSet;
    2356     psArray         *returnSet;
    2357     psU64           i;
    2358 
    2359     rowSet = psDBSelectRows(dbh, PZDONEEXP_TABLE_NAME, where, limit);
    2360     if (!rowSet) {
    2361         return NULL;
    2362     }
    2363 
    2364     // convert psMetadata rows to row objects
    2365 
    2366     returnSet = psArrayAllocEmpty(rowSet->n);
    2367 
    2368     for (i = 0; i < rowSet->n; i++) {
    2369         pzDoneExpRow *object = pzDoneExpObjectFromMetadata(rowSet->data[i]);
    2370         if (!object) {
    2371             psFree(object);
    2372             psFree(returnSet);
    2373             psError(PS_ERR_UNKNOWN, false, "database error");
    2374             return NULL;
    2375         }
    2376         psArrayAdd(returnSet, 0, object);
    2377         psFree(object);
    2378     }
    2379 
    2380     psFree(rowSet);
    2381 
    2382     return returnSet;
    2383 }
    2384 bool pzDoneExpDeleteObject(psDB *dbh, const pzDoneExpRow *object)
    2385 {
    2386     psMetadata *where = pzDoneExpMetadataFromObject(object);
    2387     long long count = psDBDeleteRows(dbh, PZDONEEXP_TABLE_NAME, where, 0);
    2388     psFree(where);
    2389     if (count < 0) {
    2390         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneExp");
    2391         return false;
    2392     }
    2393     if (count > 1) {
    2394         // XXX should this be a psAbort() instead?  It is possible that
    2395         // having an object match multiple rows was by design.
    2396         psError(PS_ERR_UNKNOWN, true, "pzDoneExpRow object matched more then one row.  Check your database schema");
    2397         return false;
    2398     }
    2399 
    2400     return true;
    2401 }
    2402 long long pzDoneExpDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    2403 {
    2404     long long       deleted = 0;
    2405 
    2406     for (long long i = 0; i < objects->n; i++) {
    2407         pzDoneExpRow *object = objects->data[i];
    2408         psMetadata *where = pzDoneExpMetadataFromObject(object);
    2409         long long count = psDBDeleteRows(dbh, PZDONEEXP_TABLE_NAME, where, limit);
    2410         psFree(where);
    2411         if (count < 0) {
    2412             psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneExp");
    2413             return count;
    2414         }
    2415 
    2416         deleted += count;
    2417     }
    2418 
    2419     return deleted;
    2420 }
    2421 bool pzDoneExpPrintObjects(FILE *stream, psArray *objects, bool mdcf)
    2422 {
    2423     PS_ASSERT_PTR_NON_NULL(objects, false);
    2424 
    2425     psMetadata *output = psMetadataAlloc();
    2426     for (long i = 0; i < psArrayLength(objects); i++) {
    2427         psMetadata *md = pzDoneExpMetadataFromObject(objects->data[i]);
    2428         if (!psMetadataAddMetadata(
    2429             output,
    2430             PS_LIST_TAIL,
    2431             PZDONEEXP_TABLE_NAME,
    2432             PS_META_DUPLICATE_OK,
    2433             NULL,
    2434             md
    2435         )) {
    2436             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    2437             psFree(md);
    2438             psFree(output);
    2439             return false;
    2440         }
    2441         psFree(md);
    2442     }
    2443 
    2444     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    2445         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    2446         psFree(output);
    2447     }
    2448     psFree(output);
    2449 
    2450     return true;
    2451 }
    2452 bool pzDoneExpPrintObject(FILE *stream, pzDoneExpRow *object, bool mdcf)
    2453 {
    2454     PS_ASSERT_PTR_NON_NULL(object, false);
    2455 
    2456     psMetadata *md = pzDoneExpMetadataFromObject(object);
    2457 
    2458     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    2459         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    2460         psFree(md);
    2461     }
    2462 
    2463     psFree(md);
    2464 
    2465     return true;
    2466 }
    2467 static void pzDoneImfileRowFree(pzDoneImfileRow *object);
    2468 
    2469 pzDoneImfileRow *pzDoneImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, const char *uri)
    2470 {
    2471     pzDoneImfileRow *_object;
    2472 
    2473     _object = psAlloc(sizeof(pzDoneImfileRow));
    2474     psMemSetDeallocator(_object, (psFreeFunc)pzDoneImfileRowFree);
    2475 
    2476     _object->exp_name = psStringCopy(exp_name);
    2477     _object->camera = psStringCopy(camera);
    2478     _object->telescope = psStringCopy(telescope);
    2479     _object->class = psStringCopy(class);
    2480     _object->class_id = psStringCopy(class_id);
    2481     _object->uri = psStringCopy(uri);
    2482 
    2483     return _object;
    2484 }
    2485 
    2486 static void pzDoneImfileRowFree(pzDoneImfileRow *object)
    2487 {
    2488     psFree(object->exp_name);
    2489     psFree(object->camera);
    2490     psFree(object->telescope);
    2491     psFree(object->class);
    2492     psFree(object->class_id);
    2493     psFree(object->uri);
    2494 }
    2495 
    2496 bool pzDoneImfileCreateTable(psDB *dbh)
    2497 {
    2498     psMetadata *md = psMetadataAlloc();
    2499     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, "Primary Key", "64")) {
    2500         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
    2501         psFree(md);
    2502         return false;
    2503     }
    2504     if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, "Primary Key", "64")) {
    2505         psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
    2506         psFree(md);
    2507         return false;
    2508     }
    2509     if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, "Primary Key", "64")) {
    2510         psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
    2511         psFree(md);
    2512         return false;
    2513     }
    2514     if (!psMetadataAdd(md, PS_LIST_TAIL, "class", PS_DATA_STRING, "Primary Key", "64")) {
    2515         psError(PS_ERR_UNKNOWN, false, "failed to add item class");
    2516         psFree(md);
    2517         return false;
    2518     }
    2519     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
    2520         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    2521         psFree(md);
    2522         return false;
    2523     }
    2524     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
    2525         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    2526         psFree(md);
    2527         return false;
    2528     }
    2529 
    2530     bool status = psDBCreateTable(dbh, PZDONEIMFILE_TABLE_NAME, md);
    2531 
    2532     psFree(md);
    2533 
    2534     return status;
    2535 }
    2536 
    2537 bool pzDoneImfileDropTable(psDB *dbh)
    2538 {
    2539     return psDBDropTable(dbh, PZDONEIMFILE_TABLE_NAME);
    2540 }
    2541 
    2542 bool pzDoneImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, const char *uri)
    2543 {
    2544     psMetadata *md = psMetadataAlloc();
    2545     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, NULL, exp_name)) {
    2546         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
    2547         psFree(md);
    2548         return false;
    2549     }
    2550     if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, NULL, camera)) {
    2551         psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
    2552         psFree(md);
    2553         return false;
    2554     }
    2555     if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, NULL, telescope)) {
    2556         psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
    2557         psFree(md);
    2558         return false;
    2559     }
    2560     if (!psMetadataAdd(md, PS_LIST_TAIL, "class", PS_DATA_STRING, NULL, class)) {
    2561         psError(PS_ERR_UNKNOWN, false, "failed to add item class");
    2562         psFree(md);
    2563         return false;
    2564     }
    2565     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
    2566         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    2567         psFree(md);
    2568         return false;
    2569     }
    2570     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
    2571         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    2572         psFree(md);
    2573         return false;
    2574     }
    2575 
    2576     bool status = psDBInsertOneRow(dbh, PZDONEIMFILE_TABLE_NAME, md);
    2577     psFree(md);
    2578 
    2579     return status;
    2580 }
    2581 
    2582 long long pzDoneImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
    2583 {
    2584     long long       deleted = 0;
    2585 
    2586     long long count = psDBDeleteRows(dbh, PZDONEIMFILE_TABLE_NAME, where, limit);
    2587     if (count < 0) {
    2588         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneImfile");
    2589         return count;
    2590 
    2591         deleted += count;
    2592     }
    2593 
    2594     return deleted;
    2595 }
    2596 bool pzDoneImfileInsertObject(psDB *dbh, pzDoneImfileRow *object)
    2597 {
    2598     return pzDoneImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id, object->uri);
    2599 }
    2600 
    2601 bool pzDoneImfileInsertObjects(psDB *dbh, psArray *objects)
    2602 {
    2603     for (long i = 0; i < psArrayLength(objects); i++) {
    2604         if (!pzDoneImfileInsertObject(dbh, objects->data[i])) {
    2605             return false;
    2606         }
    2607     }
    2608 
    2609     return true;
    2610 }
    2611 
    2612 bool pzDoneImfileInsertFits(psDB *dbh, const psFits *fits)
    2613 {
    2614     psArray         *rowSet;
    2615 
    2616     // move to (the first?) extension named  PZDONEIMFILE_TABLE_NAME
    2617     if (!psFitsMoveExtName(fits, PZDONEIMFILE_TABLE_NAME)) {
    2618         psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PZDONEIMFILE_TABLE_NAME);
    2619         return false;
    2620     }
    2621 
    2622     // check HDU type
    2623     if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
    2624         psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
    2625         return false;
    2626     }
    2627 
    2628     // read fits table
    2629     rowSet = psFitsReadTable(fits);
    2630     if (!rowSet) {
    2631         psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
    2632         psFree(rowSet);
    2633         return false;
    2634     }
    2635 
    2636     if (!psDBInsertRows(dbh, PZDONEIMFILE_TABLE_NAME, rowSet)) {
    2637         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
    2638         psFree(rowSet);
    2639         return false;
    2640     }
    2641 
    2642     psFree(rowSet);
    2643 
    2644     return true;
    2645 }
    2646 
    2647 bool pzDoneImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
    2648 {
    2649     psArray         *rowSet;
    2650 
    2651     rowSet = psDBSelectRows(dbh, PZDONEIMFILE_TABLE_NAME, where, limit);
    2652     if (!rowSet) {
    2653         return false;
    2654     }
    2655 
    2656     // output to fits
    2657     if (!psFitsWriteTable(fits, NULL, rowSet, PZDONEIMFILE_TABLE_NAME)) {
    2658         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
    2659         psFree(rowSet);
    2660         return false;
    2661     }
    2662 
    2663     psFree(rowSet);
    2664 
    2665     return true;
    2666 }
    2667 
    2668 psMetadata *pzDoneImfileMetadataFromObject(const pzDoneImfileRow *object)
    2669 {
    2670     psMetadata *md = psMetadataAlloc();
    2671     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, NULL, object->exp_name)) {
    2672         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
    2673         psFree(md);
    2674         return false;
    2675     }
    2676     if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, NULL, object->camera)) {
    2677         psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
    2678         psFree(md);
    2679         return false;
    2680     }
    2681     if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, NULL, object->telescope)) {
    2682         psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
    2683         psFree(md);
    2684         return false;
    2685     }
    2686     if (!psMetadataAdd(md, PS_LIST_TAIL, "class", PS_DATA_STRING, NULL, object->class)) {
    2687         psError(PS_ERR_UNKNOWN, false, "failed to add item class");
    2688         psFree(md);
    2689         return false;
    2690     }
    2691     if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) {
    2692         psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
    2693         psFree(md);
    2694         return false;
    2695     }
    2696     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
    2697         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
    2698         psFree(md);
    2699         return false;
    2700     }
    2701 
    2702 
    2703     return md;
    2704 }
    2705 
    2706 pzDoneImfileRow *pzDoneImfileObjectFromMetadata(psMetadata *md)
    2707 {
    2708 
    2709 bool status = false;
    2710     char* exp_name = psMetadataLookupPtr(&status, md, "exp_name");
    2711     if (!status) {
    2712         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_name");
    2713         return false;
    2714     }
    2715     char* camera = psMetadataLookupPtr(&status, md, "camera");
    2716     if (!status) {
    2717         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item camera");
    2718         return false;
    2719     }
    2720     char* telescope = psMetadataLookupPtr(&status, md, "telescope");
    2721     if (!status) {
    2722         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item telescope");
    2723         return false;
    2724     }
    2725     char* class = psMetadataLookupPtr(&status, md, "class");
    2726     if (!status) {
    2727         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class");
    2728         return false;
    2729     }
    2730     char* class_id = psMetadataLookupPtr(&status, md, "class_id");
    2731     if (!status) {
    2732         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id");
    2733         return false;
    2734     }
    2735     char* uri = psMetadataLookupPtr(&status, md, "uri");
    2736     if (!status) {
    2737         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
    2738         return false;
    2739     }
    2740 
    2741     return pzDoneImfileRowAlloc(exp_name, camera, telescope, class, class_id, uri);
    2742 }
    2743 psArray *pzDoneImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
    2744 {
    2745     psArray         *rowSet;
    2746     psArray         *returnSet;
    2747     psU64           i;
    2748 
    2749     rowSet = psDBSelectRows(dbh, PZDONEIMFILE_TABLE_NAME, where, limit);
    2750     if (!rowSet) {
    2751         return NULL;
    2752     }
    2753 
    2754     // convert psMetadata rows to row objects
    2755 
    2756     returnSet = psArrayAllocEmpty(rowSet->n);
    2757 
    2758     for (i = 0; i < rowSet->n; i++) {
    2759         pzDoneImfileRow *object = pzDoneImfileObjectFromMetadata(rowSet->data[i]);
    2760         if (!object) {
    2761             psFree(object);
    2762             psFree(returnSet);
    2763             psError(PS_ERR_UNKNOWN, false, "database error");
    2764             return NULL;
    2765         }
    2766         psArrayAdd(returnSet, 0, object);
    2767         psFree(object);
    2768     }
    2769 
    2770     psFree(rowSet);
    2771 
    2772     return returnSet;
    2773 }
    2774 bool pzDoneImfileDeleteObject(psDB *dbh, const pzDoneImfileRow *object)
    2775 {
    2776     psMetadata *where = pzDoneImfileMetadataFromObject(object);
    2777     long long count = psDBDeleteRows(dbh, PZDONEIMFILE_TABLE_NAME, where, 0);
    2778     psFree(where);
    2779     if (count < 0) {
    2780         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneImfile");
    2781         return false;
    2782     }
    2783     if (count > 1) {
    2784         // XXX should this be a psAbort() instead?  It is possible that
    2785         // having an object match multiple rows was by design.
    2786         psError(PS_ERR_UNKNOWN, true, "pzDoneImfileRow object matched more then one row.  Check your database schema");
    2787         return false;
    2788     }
    2789 
    2790     return true;
    2791 }
    2792 long long pzDoneImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
    2793 {
    2794     long long       deleted = 0;
    2795 
    2796     for (long long i = 0; i < objects->n; i++) {
    2797         pzDoneImfileRow *object = objects->data[i];
    2798         psMetadata *where = pzDoneImfileMetadataFromObject(object);
    2799         long long count = psDBDeleteRows(dbh, PZDONEIMFILE_TABLE_NAME, where, limit);
    2800         psFree(where);
    2801         if (count < 0) {
    2802             psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneImfile");
    2803             return count;
    2804         }
    2805 
    2806         deleted += count;
    2807     }
    2808 
    2809     return deleted;
    2810 }
    2811 bool pzDoneImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
    2812 {
    2813     PS_ASSERT_PTR_NON_NULL(objects, false);
    2814 
    2815     psMetadata *output = psMetadataAlloc();
    2816     for (long i = 0; i < psArrayLength(objects); i++) {
    2817         psMetadata *md = pzDoneImfileMetadataFromObject(objects->data[i]);
    2818         if (!psMetadataAddMetadata(
    2819             output,
    2820             PS_LIST_TAIL,
    2821             PZDONEIMFILE_TABLE_NAME,
    2822             PS_META_DUPLICATE_OK,
    2823             NULL,
    2824             md
    2825         )) {
    2826             psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
    2827             psFree(md);
    2828             psFree(output);
    2829             return false;
    2830         }
    2831         psFree(md);
    2832     }
    2833 
    2834     if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
    2835         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    2836         psFree(output);
    2837     }
    2838     psFree(output);
    2839 
    2840     return true;
    2841 }
    2842 bool pzDoneImfilePrintObject(FILE *stream, pzDoneImfileRow *object, bool mdcf)
    2843 {
    2844     PS_ASSERT_PTR_NON_NULL(object, false);
    2845 
    2846     psMetadata *md = pzDoneImfileMetadataFromObject(object);
    2847 
    2848     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
    2849         psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
    2850         psFree(md);
    2851     }
    2852 
    2853     psFree(md);
    2854 
    2855     return true;
    2856 }
    28572209static void newExpRowFree(newExpRow *object);
    28582210
    2859 newExpRow *newExpRowAlloc(psS64 exp_id, const char *tmp_exp_name, const char *tmp_camera, const char *tmp_telescope, const char *state, const char *workdir, const char *workdir_state, const char *reduction, const char *dvodb, const char *tess_id, const char *end_stage)
     2211newExpRow *newExpRowAlloc(psS64 exp_id, const char *tmp_exp_name, const char *tmp_camera, const char *tmp_telescope, const char *state, const char *workdir, const char *workdir_state, const char *reduction, const char *dvodb, const char *tess_id, const char *end_stage, const char *label)
    28602212{
    28612213    newExpRow       *_object;
     
    28752227    _object->tess_id = psStringCopy(tess_id);
    28762228    _object->end_stage = psStringCopy(end_stage);
     2229    _object->label = psStringCopy(label);
    28772230
    28782231    return _object;
     
    28912244    psFree(object->tess_id);
    28922245    psFree(object->end_stage);
     2246    psFree(object->label);
    28932247}
    28942248
     
    29512305        return false;
    29522306    }
     2307    if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, "Key", "64")) {
     2308        psError(PS_ERR_UNKNOWN, false, "failed to add item label");
     2309        psFree(md);
     2310        return false;
     2311    }
    29532312
    29542313    bool status = psDBCreateTable(dbh, NEWEXP_TABLE_NAME, md);
     
    29642323}
    29652324
    2966 bool newExpInsert(psDB * dbh, psS64 exp_id, const char *tmp_exp_name, const char *tmp_camera, const char *tmp_telescope, const char *state, const char *workdir, const char *workdir_state, const char *reduction, const char *dvodb, const char *tess_id, const char *end_stage)
     2325bool newExpInsert(psDB * dbh, psS64 exp_id, const char *tmp_exp_name, const char *tmp_camera, const char *tmp_telescope, const char *state, const char *workdir, const char *workdir_state, const char *reduction, const char *dvodb, const char *tess_id, const char *end_stage, const char *label)
    29672326{
    29682327    psMetadata *md = psMetadataAlloc();
     
    30192378    if (!psMetadataAdd(md, PS_LIST_TAIL, "end_stage", PS_DATA_STRING, NULL, end_stage)) {
    30202379        psError(PS_ERR_UNKNOWN, false, "failed to add item end_stage");
     2380        psFree(md);
     2381        return false;
     2382    }
     2383    if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, NULL, label)) {
     2384        psError(PS_ERR_UNKNOWN, false, "failed to add item label");
    30212385        psFree(md);
    30222386        return false;
     
    30452409bool newExpInsertObject(psDB *dbh, newExpRow *object)
    30462410{
    3047     return newExpInsert(dbh, object->exp_id, object->tmp_exp_name, object->tmp_camera, object->tmp_telescope, object->state, object->workdir, object->workdir_state, object->reduction, object->dvodb, object->tess_id, object->end_stage);
     2411    return newExpInsert(dbh, object->exp_id, object->tmp_exp_name, object->tmp_camera, object->tmp_telescope, object->state, object->workdir, object->workdir_state, object->reduction, object->dvodb, object->tess_id, object->end_stage, object->label);
    30482412}
    30492413
     
    31732537        return false;
    31742538    }
     2539    if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, NULL, object->label)) {
     2540        psError(PS_ERR_UNKNOWN, false, "failed to add item label");
     2541        psFree(md);
     2542        return false;
     2543    }
    31752544
    31762545
     
    32372606        return false;
    32382607    }
    3239 
    3240     return newExpRowAlloc(exp_id, tmp_exp_name, tmp_camera, tmp_telescope, state, workdir, workdir_state, reduction, dvodb, tess_id, end_stage);
     2608    char* label = psMetadataLookupPtr(&status, md, "label");
     2609    if (!status) {
     2610        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item label");
     2611        return false;
     2612    }
     2613
     2614    return newExpRowAlloc(exp_id, tmp_exp_name, tmp_camera, tmp_telescope, state, workdir, workdir_state, reduction, dvodb, tess_id, end_stage, label);
    32412615}
    32422616psArray *newExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    73106684static void chipProcessedImfileRowFree(chipProcessedImfileRow *object);
    73116685
    7312 chipProcessedImfileRow *chipProcessedImfileRowAlloc(psS64 chip_id, psS64 exp_id, const char *class_id, const char *uri, psF32 bg, psF32 bg_stdev, psF32 bg_mean_stdev, psF32 bias, psF32 bias_stdev, psF32 fringe_0, psF32 fringe_1, psF32 fringe_2, psF32 sigma_ra, psF32 sigma_dec, psF32 ap_resid, psF32 ap_resid_stdev, psF32 fwhm, psF32 fwhm_range, psS32 n_stars, psS32 n_extended, psS32 n_cr, psS32 n_astrom, const char *path_base, psS16 fault)
     6686chipProcessedImfileRow *chipProcessedImfileRowAlloc(psS64 chip_id, psS64 exp_id, const char *class_id, const char *uri, psF32 bg, psF32 bg_stdev, psF32 bg_mean_stdev, psF32 bias, psF32 bias_stdev, psF32 fringe_0, psF32 fringe_1, psF32 fringe_2, psF32 sigma_ra, psF32 sigma_dec, psF32 ap_resid, psF32 ap_resid_stdev, psF32 zp_mean, psF32 zp_stdev, psF32 fwhm_major, psF32 fwhm_minor, psF32 dtime_detrend, psF32 dtime_photom, psF32 dtime_astrom, const char *hostname, psS32 n_stars, psS32 n_extended, psS32 n_cr, psS32 n_astrom, const char *path_base, psS16 fault)
    73136687{
    73146688    chipProcessedImfileRow *_object;
     
    73336707    _object->ap_resid = ap_resid;
    73346708    _object->ap_resid_stdev = ap_resid_stdev;
    7335     _object->fwhm = fwhm;
    7336     _object->fwhm_range = fwhm_range;
     6709    _object->zp_mean = zp_mean;
     6710    _object->zp_stdev = zp_stdev;
     6711    _object->fwhm_major = fwhm_major;
     6712    _object->fwhm_minor = fwhm_minor;
     6713    _object->dtime_detrend = dtime_detrend;
     6714    _object->dtime_photom = dtime_photom;
     6715    _object->dtime_astrom = dtime_astrom;
     6716    _object->hostname = psStringCopy(hostname);
    73376717    _object->n_stars = n_stars;
    73386718    _object->n_extended = n_extended;
     
    73496729    psFree(object->class_id);
    73506730    psFree(object->uri);
     6731    psFree(object->hostname);
    73516732    psFree(object->path_base);
    73526733}
     
    74356816        return false;
    74366817    }
    7437     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, "# replace this with fwhm_major", 0.0)) {
    7438         psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm");
    7439         psFree(md);
    7440         return false;
    7441     }
    7442     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, "# replace this with fwhm_minor", 0.0)) {
    7443         psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_range");
     6818    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_mean", PS_DATA_F32, NULL, 0.0)) {
     6819        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_mean");
     6820        psFree(md);
     6821        return false;
     6822    }
     6823    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_stdev", PS_DATA_F32, NULL, 0.0)) {
     6824        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_stdev");
     6825        psFree(md);
     6826        return false;
     6827    }
     6828    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_major", PS_DATA_F32, NULL, 0.0)) {
     6829        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_major");
     6830        psFree(md);
     6831        return false;
     6832    }
     6833    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_minor", PS_DATA_F32, NULL, 0.0)) {
     6834        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_minor");
     6835        psFree(md);
     6836        return false;
     6837    }
     6838    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_detrend", PS_DATA_F32, NULL, 0.0)) {
     6839        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_detrend");
     6840        psFree(md);
     6841        return false;
     6842    }
     6843    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_photom", PS_DATA_F32, NULL, 0.0)) {
     6844        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_photom");
     6845        psFree(md);
     6846        return false;
     6847    }
     6848    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_astrom", PS_DATA_F32, NULL, 0.0)) {
     6849        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_astrom");
     6850        psFree(md);
     6851        return false;
     6852    }
     6853    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, "64")) {
     6854        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
    74446855        psFree(md);
    74456856        return false;
     
    74886899}
    74896900
    7490 bool chipProcessedImfileInsert(psDB * dbh, psS64 chip_id, psS64 exp_id, const char *class_id, const char *uri, psF32 bg, psF32 bg_stdev, psF32 bg_mean_stdev, psF32 bias, psF32 bias_stdev, psF32 fringe_0, psF32 fringe_1, psF32 fringe_2, psF32 sigma_ra, psF32 sigma_dec, psF32 ap_resid, psF32 ap_resid_stdev, psF32 fwhm, psF32 fwhm_range, psS32 n_stars, psS32 n_extended, psS32 n_cr, psS32 n_astrom, const char *path_base, psS16 fault)
     6901bool chipProcessedImfileInsert(psDB * dbh, psS64 chip_id, psS64 exp_id, const char *class_id, const char *uri, psF32 bg, psF32 bg_stdev, psF32 bg_mean_stdev, psF32 bias, psF32 bias_stdev, psF32 fringe_0, psF32 fringe_1, psF32 fringe_2, psF32 sigma_ra, psF32 sigma_dec, psF32 ap_resid, psF32 ap_resid_stdev, psF32 zp_mean, psF32 zp_stdev, psF32 fwhm_major, psF32 fwhm_minor, psF32 dtime_detrend, psF32 dtime_photom, psF32 dtime_astrom, const char *hostname, psS32 n_stars, psS32 n_extended, psS32 n_cr, psS32 n_astrom, const char *path_base, psS16 fault)
    74916902{
    74926903    psMetadata *md = psMetadataAlloc();
     
    75716982        return false;
    75726983    }
    7573     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, NULL, fwhm)) {
    7574         psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm");
    7575         psFree(md);
    7576         return false;
    7577     }
    7578     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, NULL, fwhm_range)) {
    7579         psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_range");
     6984    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_mean", PS_DATA_F32, NULL, zp_mean)) {
     6985        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_mean");
     6986        psFree(md);
     6987        return false;
     6988    }
     6989    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_stdev", PS_DATA_F32, NULL, zp_stdev)) {
     6990        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_stdev");
     6991        psFree(md);
     6992        return false;
     6993    }
     6994    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_major", PS_DATA_F32, NULL, fwhm_major)) {
     6995        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_major");
     6996        psFree(md);
     6997        return false;
     6998    }
     6999    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_minor", PS_DATA_F32, NULL, fwhm_minor)) {
     7000        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_minor");
     7001        psFree(md);
     7002        return false;
     7003    }
     7004    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_detrend", PS_DATA_F32, NULL, dtime_detrend)) {
     7005        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_detrend");
     7006        psFree(md);
     7007        return false;
     7008    }
     7009    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_photom", PS_DATA_F32, NULL, dtime_photom)) {
     7010        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_photom");
     7011        psFree(md);
     7012        return false;
     7013    }
     7014    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_astrom", PS_DATA_F32, NULL, dtime_astrom)) {
     7015        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_astrom");
     7016        psFree(md);
     7017        return false;
     7018    }
     7019    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, hostname)) {
     7020        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
    75807021        psFree(md);
    75817022        return false;
     
    76347075bool chipProcessedImfileInsertObject(psDB *dbh, chipProcessedImfileRow *object)
    76357076{
    7636     return chipProcessedImfileInsert(dbh, object->chip_id, object->exp_id, object->class_id, object->uri, object->bg, object->bg_stdev, object->bg_mean_stdev, object->bias, object->bias_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->sigma_ra, object->sigma_dec, object->ap_resid, object->ap_resid_stdev, object->fwhm, object->fwhm_range, object->n_stars, object->n_extended, object->n_cr, object->n_astrom, object->path_base, object->fault);
     7077    return chipProcessedImfileInsert(dbh, object->chip_id, object->exp_id, object->class_id, object->uri, object->bg, object->bg_stdev, object->bg_mean_stdev, object->bias, object->bias_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->sigma_ra, object->sigma_dec, object->ap_resid, object->ap_resid_stdev, object->zp_mean, object->zp_stdev, object->fwhm_major, object->fwhm_minor, object->dtime_detrend, object->dtime_photom, object->dtime_astrom, object->hostname, object->n_stars, object->n_extended, object->n_cr, object->n_astrom, object->path_base, object->fault);
    76377078}
    76387079
     
    77877228        return false;
    77887229    }
    7789     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, NULL, object->fwhm)) {
    7790         psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm");
    7791         psFree(md);
    7792         return false;
    7793     }
    7794     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, NULL, object->fwhm_range)) {
    7795         psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_range");
     7230    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_mean", PS_DATA_F32, NULL, object->zp_mean)) {
     7231        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_mean");
     7232        psFree(md);
     7233        return false;
     7234    }
     7235    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_stdev", PS_DATA_F32, NULL, object->zp_stdev)) {
     7236        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_stdev");
     7237        psFree(md);
     7238        return false;
     7239    }
     7240    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_major", PS_DATA_F32, NULL, object->fwhm_major)) {
     7241        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_major");
     7242        psFree(md);
     7243        return false;
     7244    }
     7245    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_minor", PS_DATA_F32, NULL, object->fwhm_minor)) {
     7246        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_minor");
     7247        psFree(md);
     7248        return false;
     7249    }
     7250    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_detrend", PS_DATA_F32, NULL, object->dtime_detrend)) {
     7251        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_detrend");
     7252        psFree(md);
     7253        return false;
     7254    }
     7255    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_photom", PS_DATA_F32, NULL, object->dtime_photom)) {
     7256        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_photom");
     7257        psFree(md);
     7258        return false;
     7259    }
     7260    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_astrom", PS_DATA_F32, NULL, object->dtime_astrom)) {
     7261        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_astrom");
     7262        psFree(md);
     7263        return false;
     7264    }
     7265    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, object->hostname)) {
     7266        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
    77967267        psFree(md);
    77977268        return false;
     
    79167387        return false;
    79177388    }
    7918     psF32 fwhm = psMetadataLookupF32(&status, md, "fwhm");
    7919     if (!status) {
    7920         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm");
    7921         return false;
    7922     }
    7923     psF32 fwhm_range = psMetadataLookupF32(&status, md, "fwhm_range");
    7924     if (!status) {
    7925         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm_range");
     7389    psF32 zp_mean = psMetadataLookupF32(&status, md, "zp_mean");
     7390    if (!status) {
     7391        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item zp_mean");
     7392        return false;
     7393    }
     7394    psF32 zp_stdev = psMetadataLookupF32(&status, md, "zp_stdev");
     7395    if (!status) {
     7396        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item zp_stdev");
     7397        return false;
     7398    }
     7399    psF32 fwhm_major = psMetadataLookupF32(&status, md, "fwhm_major");
     7400    if (!status) {
     7401        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm_major");
     7402        return false;
     7403    }
     7404    psF32 fwhm_minor = psMetadataLookupF32(&status, md, "fwhm_minor");
     7405    if (!status) {
     7406        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm_minor");
     7407        return false;
     7408    }
     7409    psF32 dtime_detrend = psMetadataLookupF32(&status, md, "dtime_detrend");
     7410    if (!status) {
     7411        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_detrend");
     7412        return false;
     7413    }
     7414    psF32 dtime_photom = psMetadataLookupF32(&status, md, "dtime_photom");
     7415    if (!status) {
     7416        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_photom");
     7417        return false;
     7418    }
     7419    psF32 dtime_astrom = psMetadataLookupF32(&status, md, "dtime_astrom");
     7420    if (!status) {
     7421        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_astrom");
     7422        return false;
     7423    }
     7424    char* hostname = psMetadataLookupPtr(&status, md, "hostname");
     7425    if (!status) {
     7426        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item hostname");
    79267427        return false;
    79277428    }
     
    79577458    }
    79587459
    7959     return chipProcessedImfileRowAlloc(chip_id, exp_id, class_id, uri, bg, bg_stdev, bg_mean_stdev, bias, bias_stdev, fringe_0, fringe_1, fringe_2, sigma_ra, sigma_dec, ap_resid, ap_resid_stdev, fwhm, fwhm_range, n_stars, n_extended, n_cr, n_astrom, path_base, fault);
     7460    return chipProcessedImfileRowAlloc(chip_id, exp_id, class_id, uri, bg, bg_stdev, bg_mean_stdev, bias, bias_stdev, fringe_0, fringe_1, fringe_2, sigma_ra, sigma_dec, ap_resid, ap_resid_stdev, zp_mean, zp_stdev, fwhm_major, fwhm_minor, dtime_detrend, dtime_photom, dtime_astrom, hostname, n_stars, n_extended, n_cr, n_astrom, path_base, fault);
    79607461}
    79617462psArray *chipProcessedImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    88538354static void camProcessedExpRowFree(camProcessedExpRow *object);
    88548355
    8855 camProcessedExpRow *camProcessedExpRowAlloc(psS64 cam_id, psS64 chip_id, const char *uri, psF32 bg, psF32 bg_stdev, psF32 bg_mean_stdev, psF32 sigma_ra, psF32 sigma_dec, psF32 zp_mean, psF32 zp_stdev, psF32 fwhm, psF32 fwhm_range, psS32 n_stars, psS32 n_extended, psS32 n_cr, psS32 n_astrom, const char *path_base, psS16 fault)
     8356camProcessedExpRow *camProcessedExpRowAlloc(psS64 cam_id, psS64 chip_id, const char *uri, psF32 bg, psF32 bg_stdev, psF32 bg_mean_stdev, psF32 bias, psF32 bias_stdev, psF32 fringe_0, psF32 fringe_1, psF32 fringe_2, psF32 sigma_ra, psF32 sigma_dec, psF32 ap_resid, psF32 ap_resid_stdev, psF32 zp_mean, psF32 zp_stdev, psF32 fwhm_major, psF32 fwhm_minor, psF32 dtime_detrend, psF32 dtime_photom, psF32 dtime_astrom, const char *hostname, psS32 n_stars, psS32 n_extended, psS32 n_cr, psS32 n_astrom, const char *path_base, psS16 fault)
    88568357{
    88578358    camProcessedExpRow *_object;
     
    88668367    _object->bg_stdev = bg_stdev;
    88678368    _object->bg_mean_stdev = bg_mean_stdev;
     8369    _object->bias = bias;
     8370    _object->bias_stdev = bias_stdev;
     8371    _object->fringe_0 = fringe_0;
     8372    _object->fringe_1 = fringe_1;
     8373    _object->fringe_2 = fringe_2;
    88688374    _object->sigma_ra = sigma_ra;
    88698375    _object->sigma_dec = sigma_dec;
     8376    _object->ap_resid = ap_resid;
     8377    _object->ap_resid_stdev = ap_resid_stdev;
    88708378    _object->zp_mean = zp_mean;
    88718379    _object->zp_stdev = zp_stdev;
    8872     _object->fwhm = fwhm;
    8873     _object->fwhm_range = fwhm_range;
     8380    _object->fwhm_major = fwhm_major;
     8381    _object->fwhm_minor = fwhm_minor;
     8382    _object->dtime_detrend = dtime_detrend;
     8383    _object->dtime_photom = dtime_photom;
     8384    _object->dtime_astrom = dtime_astrom;
     8385    _object->hostname = psStringCopy(hostname);
    88748386    _object->n_stars = n_stars;
    88758387    _object->n_extended = n_extended;
     
    88858397{
    88868398    psFree(object->uri);
     8399    psFree(object->hostname);
    88878400    psFree(object->path_base);
    88888401}
     
    89218434        return false;
    89228435    }
     8436    if (!psMetadataAdd(md, PS_LIST_TAIL, "bias", PS_DATA_F32, NULL, 0.0)) {
     8437        psError(PS_ERR_UNKNOWN, false, "failed to add item bias");
     8438        psFree(md);
     8439        return false;
     8440    }
     8441    if (!psMetadataAdd(md, PS_LIST_TAIL, "bias_stdev", PS_DATA_F32, NULL, 0.0)) {
     8442        psError(PS_ERR_UNKNOWN, false, "failed to add item bias_stdev");
     8443        psFree(md);
     8444        return false;
     8445    }
     8446    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_0", PS_DATA_F32, NULL, 0.0)) {
     8447        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_0");
     8448        psFree(md);
     8449        return false;
     8450    }
     8451    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_1", PS_DATA_F32, NULL, 0.0)) {
     8452        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_1");
     8453        psFree(md);
     8454        return false;
     8455    }
     8456    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_2", PS_DATA_F32, NULL, 0.0)) {
     8457        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_2");
     8458        psFree(md);
     8459        return false;
     8460    }
    89238461    if (!psMetadataAdd(md, PS_LIST_TAIL, "sigma_ra", PS_DATA_F32, NULL, 0.0)) {
    89248462        psError(PS_ERR_UNKNOWN, false, "failed to add item sigma_ra");
     
    89318469        return false;
    89328470    }
     8471    if (!psMetadataAdd(md, PS_LIST_TAIL, "ap_resid", PS_DATA_F32, NULL, 0.0)) {
     8472        psError(PS_ERR_UNKNOWN, false, "failed to add item ap_resid");
     8473        psFree(md);
     8474        return false;
     8475    }
     8476    if (!psMetadataAdd(md, PS_LIST_TAIL, "ap_resid_stdev", PS_DATA_F32, NULL, 0.0)) {
     8477        psError(PS_ERR_UNKNOWN, false, "failed to add item ap_resid_stdev");
     8478        psFree(md);
     8479        return false;
     8480    }
    89338481    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_mean", PS_DATA_F32, NULL, 0.0)) {
    89348482        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_mean");
     
    89418489        return false;
    89428490    }
    8943     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, NULL, 0.0)) {
    8944         psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm");
    8945         psFree(md);
    8946         return false;
    8947     }
    8948     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, NULL, 0.0)) {
    8949         psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_range");
     8491    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_major", PS_DATA_F32, NULL, 0.0)) {
     8492        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_major");
     8493        psFree(md);
     8494        return false;
     8495    }
     8496    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_minor", PS_DATA_F32, NULL, 0.0)) {
     8497        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_minor");
     8498        psFree(md);
     8499        return false;
     8500    }
     8501    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_detrend", PS_DATA_F32, NULL, 0.0)) {
     8502        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_detrend");
     8503        psFree(md);
     8504        return false;
     8505    }
     8506    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_photom", PS_DATA_F32, NULL, 0.0)) {
     8507        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_photom");
     8508        psFree(md);
     8509        return false;
     8510    }
     8511    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_astrom", PS_DATA_F32, NULL, 0.0)) {
     8512        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_astrom");
     8513        psFree(md);
     8514        return false;
     8515    }
     8516    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, "64")) {
     8517        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
    89508518        psFree(md);
    89518519        return false;
     
    89948562}
    89958563
    8996 bool camProcessedExpInsert(psDB * dbh, psS64 cam_id, psS64 chip_id, const char *uri, psF32 bg, psF32 bg_stdev, psF32 bg_mean_stdev, psF32 sigma_ra, psF32 sigma_dec, psF32 zp_mean, psF32 zp_stdev, psF32 fwhm, psF32 fwhm_range, psS32 n_stars, psS32 n_extended, psS32 n_cr, psS32 n_astrom, const char *path_base, psS16 fault)
     8564bool camProcessedExpInsert(psDB * dbh, psS64 cam_id, psS64 chip_id, const char *uri, psF32 bg, psF32 bg_stdev, psF32 bg_mean_stdev, psF32 bias, psF32 bias_stdev, psF32 fringe_0, psF32 fringe_1, psF32 fringe_2, psF32 sigma_ra, psF32 sigma_dec, psF32 ap_resid, psF32 ap_resid_stdev, psF32 zp_mean, psF32 zp_stdev, psF32 fwhm_major, psF32 fwhm_minor, psF32 dtime_detrend, psF32 dtime_photom, psF32 dtime_astrom, const char *hostname, psS32 n_stars, psS32 n_extended, psS32 n_cr, psS32 n_astrom, const char *path_base, psS16 fault)
    89978565{
    89988566    psMetadata *md = psMetadataAlloc();
     
    90278595        return false;
    90288596    }
     8597    if (!psMetadataAdd(md, PS_LIST_TAIL, "bias", PS_DATA_F32, NULL, bias)) {
     8598        psError(PS_ERR_UNKNOWN, false, "failed to add item bias");
     8599        psFree(md);
     8600        return false;
     8601    }
     8602    if (!psMetadataAdd(md, PS_LIST_TAIL, "bias_stdev", PS_DATA_F32, NULL, bias_stdev)) {
     8603        psError(PS_ERR_UNKNOWN, false, "failed to add item bias_stdev");
     8604        psFree(md);
     8605        return false;
     8606    }
     8607    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_0", PS_DATA_F32, NULL, fringe_0)) {
     8608        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_0");
     8609        psFree(md);
     8610        return false;
     8611    }
     8612    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_1", PS_DATA_F32, NULL, fringe_1)) {
     8613        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_1");
     8614        psFree(md);
     8615        return false;
     8616    }
     8617    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_2", PS_DATA_F32, NULL, fringe_2)) {
     8618        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_2");
     8619        psFree(md);
     8620        return false;
     8621    }
    90298622    if (!psMetadataAdd(md, PS_LIST_TAIL, "sigma_ra", PS_DATA_F32, NULL, sigma_ra)) {
    90308623        psError(PS_ERR_UNKNOWN, false, "failed to add item sigma_ra");
     
    90378630        return false;
    90388631    }
     8632    if (!psMetadataAdd(md, PS_LIST_TAIL, "ap_resid", PS_DATA_F32, NULL, ap_resid)) {
     8633        psError(PS_ERR_UNKNOWN, false, "failed to add item ap_resid");
     8634        psFree(md);
     8635        return false;
     8636    }
     8637    if (!psMetadataAdd(md, PS_LIST_TAIL, "ap_resid_stdev", PS_DATA_F32, NULL, ap_resid_stdev)) {
     8638        psError(PS_ERR_UNKNOWN, false, "failed to add item ap_resid_stdev");
     8639        psFree(md);
     8640        return false;
     8641    }
    90398642    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_mean", PS_DATA_F32, NULL, zp_mean)) {
    90408643        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_mean");
     
    90478650        return false;
    90488651    }
    9049     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, NULL, fwhm)) {
    9050         psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm");
    9051         psFree(md);
    9052         return false;
    9053     }
    9054     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, NULL, fwhm_range)) {
    9055         psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_range");
     8652    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_major", PS_DATA_F32, NULL, fwhm_major)) {
     8653        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_major");
     8654        psFree(md);
     8655        return false;
     8656    }
     8657    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_minor", PS_DATA_F32, NULL, fwhm_minor)) {
     8658        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_minor");
     8659        psFree(md);
     8660        return false;
     8661    }
     8662    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_detrend", PS_DATA_F32, NULL, dtime_detrend)) {
     8663        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_detrend");
     8664        psFree(md);
     8665        return false;
     8666    }
     8667    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_photom", PS_DATA_F32, NULL, dtime_photom)) {
     8668        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_photom");
     8669        psFree(md);
     8670        return false;
     8671    }
     8672    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_astrom", PS_DATA_F32, NULL, dtime_astrom)) {
     8673        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_astrom");
     8674        psFree(md);
     8675        return false;
     8676    }
     8677    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, hostname)) {
     8678        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
    90568679        psFree(md);
    90578680        return false;
     
    91108733bool camProcessedExpInsertObject(psDB *dbh, camProcessedExpRow *object)
    91118734{
    9112     return camProcessedExpInsert(dbh, object->cam_id, object->chip_id, object->uri, object->bg, object->bg_stdev, object->bg_mean_stdev, object->sigma_ra, object->sigma_dec, object->zp_mean, object->zp_stdev, object->fwhm, object->fwhm_range, object->n_stars, object->n_extended, object->n_cr, object->n_astrom, object->path_base, object->fault);
     8735    return camProcessedExpInsert(dbh, object->cam_id, object->chip_id, object->uri, object->bg, object->bg_stdev, object->bg_mean_stdev, object->bias, object->bias_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->sigma_ra, object->sigma_dec, object->ap_resid, object->ap_resid_stdev, object->zp_mean, object->zp_stdev, object->fwhm_major, object->fwhm_minor, object->dtime_detrend, object->dtime_photom, object->dtime_astrom, object->hostname, object->n_stars, object->n_extended, object->n_cr, object->n_astrom, object->path_base, object->fault);
    91138736}
    91148737
     
    92138836        return false;
    92148837    }
     8838    if (!psMetadataAdd(md, PS_LIST_TAIL, "bias", PS_DATA_F32, NULL, object->bias)) {
     8839        psError(PS_ERR_UNKNOWN, false, "failed to add item bias");
     8840        psFree(md);
     8841        return false;
     8842    }
     8843    if (!psMetadataAdd(md, PS_LIST_TAIL, "bias_stdev", PS_DATA_F32, NULL, object->bias_stdev)) {
     8844        psError(PS_ERR_UNKNOWN, false, "failed to add item bias_stdev");
     8845        psFree(md);
     8846        return false;
     8847    }
     8848    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_0", PS_DATA_F32, NULL, object->fringe_0)) {
     8849        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_0");
     8850        psFree(md);
     8851        return false;
     8852    }
     8853    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_1", PS_DATA_F32, NULL, object->fringe_1)) {
     8854        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_1");
     8855        psFree(md);
     8856        return false;
     8857    }
     8858    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_2", PS_DATA_F32, NULL, object->fringe_2)) {
     8859        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_2");
     8860        psFree(md);
     8861        return false;
     8862    }
    92158863    if (!psMetadataAdd(md, PS_LIST_TAIL, "sigma_ra", PS_DATA_F32, NULL, object->sigma_ra)) {
    92168864        psError(PS_ERR_UNKNOWN, false, "failed to add item sigma_ra");
     
    92238871        return false;
    92248872    }
     8873    if (!psMetadataAdd(md, PS_LIST_TAIL, "ap_resid", PS_DATA_F32, NULL, object->ap_resid)) {
     8874        psError(PS_ERR_UNKNOWN, false, "failed to add item ap_resid");
     8875        psFree(md);
     8876        return false;
     8877    }
     8878    if (!psMetadataAdd(md, PS_LIST_TAIL, "ap_resid_stdev", PS_DATA_F32, NULL, object->ap_resid_stdev)) {
     8879        psError(PS_ERR_UNKNOWN, false, "failed to add item ap_resid_stdev");
     8880        psFree(md);
     8881        return false;
     8882    }
    92258883    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_mean", PS_DATA_F32, NULL, object->zp_mean)) {
    92268884        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_mean");
     
    92338891        return false;
    92348892    }
    9235     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, NULL, object->fwhm)) {
    9236         psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm");
    9237         psFree(md);
    9238         return false;
    9239     }
    9240     if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, NULL, object->fwhm_range)) {
    9241         psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_range");
     8893    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_major", PS_DATA_F32, NULL, object->fwhm_major)) {
     8894        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_major");
     8895        psFree(md);
     8896        return false;
     8897    }
     8898    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_minor", PS_DATA_F32, NULL, object->fwhm_minor)) {
     8899        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_minor");
     8900        psFree(md);
     8901        return false;
     8902    }
     8903    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_detrend", PS_DATA_F32, NULL, object->dtime_detrend)) {
     8904        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_detrend");
     8905        psFree(md);
     8906        return false;
     8907    }
     8908    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_photom", PS_DATA_F32, NULL, object->dtime_photom)) {
     8909        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_photom");
     8910        psFree(md);
     8911        return false;
     8912    }
     8913    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_astrom", PS_DATA_F32, NULL, object->dtime_astrom)) {
     8914        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_astrom");
     8915        psFree(md);
     8916        return false;
     8917    }
     8918    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, object->hostname)) {
     8919        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
    92428920        psFree(md);
    92438921        return false;
     
    93128990        return false;
    93138991    }
     8992    psF32 bias = psMetadataLookupF32(&status, md, "bias");
     8993    if (!status) {
     8994        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bias");
     8995        return false;
     8996    }
     8997    psF32 bias_stdev = psMetadataLookupF32(&status, md, "bias_stdev");
     8998    if (!status) {
     8999        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bias_stdev");
     9000        return false;
     9001    }
     9002    psF32 fringe_0 = psMetadataLookupF32(&status, md, "fringe_0");
     9003    if (!status) {
     9004        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fringe_0");
     9005        return false;
     9006    }
     9007    psF32 fringe_1 = psMetadataLookupF32(&status, md, "fringe_1");
     9008    if (!status) {
     9009        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fringe_1");
     9010        return false;
     9011    }
     9012    psF32 fringe_2 = psMetadataLookupF32(&status, md, "fringe_2");
     9013    if (!status) {
     9014        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fringe_2");
     9015        return false;
     9016    }
    93149017    psF32 sigma_ra = psMetadataLookupF32(&status, md, "sigma_ra");
    93159018    if (!status) {
     
    93229025        return false;
    93239026    }
     9027    psF32 ap_resid = psMetadataLookupF32(&status, md, "ap_resid");
     9028    if (!status) {
     9029        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ap_resid");
     9030        return false;
     9031    }
     9032    psF32 ap_resid_stdev = psMetadataLookupF32(&status, md, "ap_resid_stdev");
     9033    if (!status) {
     9034        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ap_resid_stdev");
     9035        return false;
     9036    }
    93249037    psF32 zp_mean = psMetadataLookupF32(&status, md, "zp_mean");
    93259038    if (!status) {
     
    93329045        return false;
    93339046    }
    9334     psF32 fwhm = psMetadataLookupF32(&status, md, "fwhm");
    9335     if (!status) {
    9336         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm");
    9337         return false;
    9338     }
    9339     psF32 fwhm_range = psMetadataLookupF32(&status, md, "fwhm_range");
    9340     if (!status) {
    9341         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm_range");
     9047    psF32 fwhm_major = psMetadataLookupF32(&status, md, "fwhm_major");
     9048    if (!status) {
     9049        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm_major");
     9050        return false;
     9051    }
     9052    psF32 fwhm_minor = psMetadataLookupF32(&status, md, "fwhm_minor");
     9053    if (!status) {
     9054        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm_minor");
     9055        return false;
     9056    }
     9057    psF32 dtime_detrend = psMetadataLookupF32(&status, md, "dtime_detrend");
     9058    if (!status) {
     9059        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_detrend");
     9060        return false;
     9061    }
     9062    psF32 dtime_photom = psMetadataLookupF32(&status, md, "dtime_photom");
     9063    if (!status) {
     9064        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_photom");
     9065        return false;
     9066    }
     9067    psF32 dtime_astrom = psMetadataLookupF32(&status, md, "dtime_astrom");
     9068    if (!status) {
     9069        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_astrom");
     9070        return false;
     9071    }
     9072    char* hostname = psMetadataLookupPtr(&status, md, "hostname");
     9073    if (!status) {
     9074        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item hostname");
    93429075        return false;
    93439076    }
     
    93739106    }
    93749107
    9375     return camProcessedExpRowAlloc(cam_id, chip_id, uri, bg, bg_stdev, bg_mean_stdev, sigma_ra, sigma_dec, zp_mean, zp_stdev, fwhm, fwhm_range, n_stars, n_extended, n_cr, n_astrom, path_base, fault);
     9108    return camProcessedExpRowAlloc(cam_id, chip_id, uri, bg, bg_stdev, bg_mean_stdev, bias, bias_stdev, fringe_0, fringe_1, fringe_2, sigma_ra, sigma_dec, ap_resid, ap_resid_stdev, zp_mean, zp_stdev, fwhm_major, fwhm_minor, dtime_detrend, dtime_photom, dtime_astrom, hostname, n_stars, n_extended, n_cr, n_astrom, path_base, fault);
    93769109}
    93779110psArray *camProcessedExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    1093410667static void warpSkyfileRowFree(warpSkyfileRow *object);
    1093510668
    10936 warpSkyfileRow *warpSkyfileRowAlloc(psS64 warp_id, const char *skycell_id, const char *tess_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF64 good_frac, bool ignored, psS16 fault)
     10669warpSkyfileRow *warpSkyfileRowAlloc(psS64 warp_id, const char *skycell_id, const char *tess_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF32 dtime_warp, const char *hostname, psF32 good_frac, bool ignored, psS16 fault)
    1093710670{
    1093810671    warpSkyfileRow  *_object;
     
    1094810681    _object->bg = bg;
    1094910682    _object->bg_stdev = bg_stdev;
     10683    _object->dtime_warp = dtime_warp;
     10684    _object->hostname = psStringCopy(hostname);
    1095010685    _object->good_frac = good_frac;
    1095110686    _object->ignored = ignored;
     
    1096110696    psFree(object->uri);
    1096210697    psFree(object->path_base);
     10698    psFree(object->hostname);
    1096310699}
    1096410700
     
    1100110737        return false;
    1100210738    }
    11003     if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, "Key", 0.0)) {
     10739    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_warp", PS_DATA_F32, NULL, 0.0)) {
     10740        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_warp");
     10741        psFree(md);
     10742        return false;
     10743    }
     10744    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, "64")) {
     10745        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
     10746        psFree(md);
     10747        return false;
     10748    }
     10749    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, "Key", 0.0)) {
    1100410750        psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
    1100510751        psFree(md);
     
    1102910775}
    1103010776
    11031 bool warpSkyfileInsert(psDB * dbh, psS64 warp_id, const char *skycell_id, const char *tess_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF64 good_frac, bool ignored, psS16 fault)
     10777bool warpSkyfileInsert(psDB * dbh, psS64 warp_id, const char *skycell_id, const char *tess_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF32 dtime_warp, const char *hostname, psF32 good_frac, bool ignored, psS16 fault)
    1103210778{
    1103310779    psMetadata *md = psMetadataAlloc();
     
    1106710813        return false;
    1106810814    }
    11069     if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, NULL, good_frac)) {
     10815    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_warp", PS_DATA_F32, NULL, dtime_warp)) {
     10816        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_warp");
     10817        psFree(md);
     10818        return false;
     10819    }
     10820    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, hostname)) {
     10821        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
     10822        psFree(md);
     10823        return false;
     10824    }
     10825    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, NULL, good_frac)) {
    1107010826        psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
    1107110827        psFree(md);
     
    1110510861bool warpSkyfileInsertObject(psDB *dbh, warpSkyfileRow *object)
    1110610862{
    11107     return warpSkyfileInsert(dbh, object->warp_id, object->skycell_id, object->tess_id, object->uri, object->path_base, object->bg, object->bg_stdev, object->good_frac, object->ignored, object->fault);
     10863    return warpSkyfileInsert(dbh, object->warp_id, object->skycell_id, object->tess_id, object->uri, object->path_base, object->bg, object->bg_stdev, object->dtime_warp, object->hostname, object->good_frac, object->ignored, object->fault);
    1110810864}
    1110910865
     
    1121310969        return false;
    1121410970    }
    11215     if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, NULL, object->good_frac)) {
     10971    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_warp", PS_DATA_F32, NULL, object->dtime_warp)) {
     10972        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_warp");
     10973        psFree(md);
     10974        return false;
     10975    }
     10976    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, object->hostname)) {
     10977        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
     10978        psFree(md);
     10979        return false;
     10980    }
     10981    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, NULL, object->good_frac)) {
    1121610982        psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
    1121710983        psFree(md);
     
    1127211038        return false;
    1127311039    }
    11274     psF64 good_frac = psMetadataLookupF64(&status, md, "good_frac");
     11040    psF32 dtime_warp = psMetadataLookupF32(&status, md, "dtime_warp");
     11041    if (!status) {
     11042        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_warp");
     11043        return false;
     11044    }
     11045    char* hostname = psMetadataLookupPtr(&status, md, "hostname");
     11046    if (!status) {
     11047        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item hostname");
     11048        return false;
     11049    }
     11050    psF32 good_frac = psMetadataLookupF32(&status, md, "good_frac");
    1127511051    if (!status) {
    1127611052        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item good_frac");
     
    1128811064    }
    1128911065
    11290     return warpSkyfileRowAlloc(warp_id, skycell_id, tess_id, uri, path_base, bg, bg_stdev, good_frac, ignored, fault);
     11066    return warpSkyfileRowAlloc(warp_id, skycell_id, tess_id, uri, path_base, bg, bg_stdev, dtime_warp, hostname, good_frac, ignored, fault);
    1129111067}
    1129211068psArray *warpSkyfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    1222512001static void diffSkyfileRowFree(diffSkyfileRow *object);
    1222612002
    12227 diffSkyfileRow *diffSkyfileRowAlloc(psS64 diff_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF64 good_frac, psS16 fault)
     12003diffSkyfileRow *diffSkyfileRowAlloc(psS64 diff_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF32 dtime_diff, const char *hostname, psF32 good_frac, psS16 fault)
    1222812004{
    1222912005    diffSkyfileRow  *_object;
     
    1223712013    _object->bg = bg;
    1223812014    _object->bg_stdev = bg_stdev;
     12015    _object->dtime_diff = dtime_diff;
     12016    _object->hostname = psStringCopy(hostname);
    1223912017    _object->good_frac = good_frac;
    1224012018    _object->fault = fault;
     
    1224712025    psFree(object->uri);
    1224812026    psFree(object->path_base);
     12027    psFree(object->hostname);
    1224912028}
    1225012029
     
    1227712056        return false;
    1227812057    }
    12279     if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, "Key", 0.0)) {
     12058    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_diff", PS_DATA_F32, NULL, 0.0)) {
     12059        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_diff");
     12060        psFree(md);
     12061        return false;
     12062    }
     12063    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, "64")) {
     12064        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
     12065        psFree(md);
     12066        return false;
     12067    }
     12068    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, "Key", 0.0)) {
    1228012069        psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
    1228112070        psFree(md);
     
    1230012089}
    1230112090
    12302 bool diffSkyfileInsert(psDB * dbh, psS64 diff_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF64 good_frac, psS16 fault)
     12091bool diffSkyfileInsert(psDB * dbh, psS64 diff_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF32 dtime_diff, const char *hostname, psF32 good_frac, psS16 fault)
    1230312092{
    1230412093    psMetadata *md = psMetadataAlloc();
     
    1232812117        return false;
    1232912118    }
    12330     if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, NULL, good_frac)) {
     12119    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_diff", PS_DATA_F32, NULL, dtime_diff)) {
     12120        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_diff");
     12121        psFree(md);
     12122        return false;
     12123    }
     12124    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, hostname)) {
     12125        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
     12126        psFree(md);
     12127        return false;
     12128    }
     12129    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, NULL, good_frac)) {
    1233112130        psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
    1233212131        psFree(md);
     
    1236112160bool diffSkyfileInsertObject(psDB *dbh, diffSkyfileRow *object)
    1236212161{
    12363     return diffSkyfileInsert(dbh, object->diff_id, object->uri, object->path_base, object->bg, object->bg_stdev, object->good_frac, object->fault);
     12162    return diffSkyfileInsert(dbh, object->diff_id, object->uri, object->path_base, object->bg, object->bg_stdev, object->dtime_diff, object->hostname, object->good_frac, object->fault);
    1236412163}
    1236512164
     
    1245912258        return false;
    1246012259    }
    12461     if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, NULL, object->good_frac)) {
     12260    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_diff", PS_DATA_F32, NULL, object->dtime_diff)) {
     12261        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_diff");
     12262        psFree(md);
     12263        return false;
     12264    }
     12265    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, object->hostname)) {
     12266        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
     12267        psFree(md);
     12268        return false;
     12269    }
     12270    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, NULL, object->good_frac)) {
    1246212271        psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
    1246312272        psFree(md);
     
    1250312312        return false;
    1250412313    }
    12505     psF64 good_frac = psMetadataLookupF64(&status, md, "good_frac");
     12314    psF32 dtime_diff = psMetadataLookupF32(&status, md, "dtime_diff");
     12315    if (!status) {
     12316        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_diff");
     12317        return false;
     12318    }
     12319    char* hostname = psMetadataLookupPtr(&status, md, "hostname");
     12320    if (!status) {
     12321        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item hostname");
     12322        return false;
     12323    }
     12324    psF32 good_frac = psMetadataLookupF32(&status, md, "good_frac");
    1250612325    if (!status) {
    1250712326        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item good_frac");
     
    1251412333    }
    1251512334
    12516     return diffSkyfileRowAlloc(diff_id, uri, path_base, bg, bg_stdev, good_frac, fault);
     12335    return diffSkyfileRowAlloc(diff_id, uri, path_base, bg, bg_stdev, dtime_diff, hostname, good_frac, fault);
    1251712336}
    1251812337psArray *diffSkyfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    1334313162static void stackSumSkyfileRowFree(stackSumSkyfileRow *object);
    1334413163
    13345 stackSumSkyfileRow *stackSumSkyfileRowAlloc(psS64 stack_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF64 good_frac, psS16 fault)
     13164stackSumSkyfileRow *stackSumSkyfileRowAlloc(psS64 stack_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF32 dtime_stack, const char *hostname, psF32 good_frac, psS16 fault)
    1334613165{
    1334713166    stackSumSkyfileRow *_object;
     
    1335513174    _object->bg = bg;
    1335613175    _object->bg_stdev = bg_stdev;
     13176    _object->dtime_stack = dtime_stack;
     13177    _object->hostname = psStringCopy(hostname);
    1335713178    _object->good_frac = good_frac;
    1335813179    _object->fault = fault;
     
    1336513186    psFree(object->uri);
    1336613187    psFree(object->path_base);
     13188    psFree(object->hostname);
    1336713189}
    1336813190
     
    1339513217        return false;
    1339613218    }
    13397     if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, "Key", 0.0)) {
     13219    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_stack", PS_DATA_F32, "Key", 0.0)) {
     13220        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_stack");
     13221        psFree(md);
     13222        return false;
     13223    }
     13224    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, "64")) {
     13225        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
     13226        psFree(md);
     13227        return false;
     13228    }
     13229    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, "Key", 0.0)) {
    1339813230        psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
    1339913231        psFree(md);
     
    1341813250}
    1341913251
    13420 bool stackSumSkyfileInsert(psDB * dbh, psS64 stack_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF64 good_frac, psS16 fault)
     13252bool stackSumSkyfileInsert(psDB * dbh, psS64 stack_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF32 dtime_stack, const char *hostname, psF32 good_frac, psS16 fault)
    1342113253{
    1342213254    psMetadata *md = psMetadataAlloc();
     
    1344613278        return false;
    1344713279    }
    13448     if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, NULL, good_frac)) {
     13280    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_stack", PS_DATA_F32, NULL, dtime_stack)) {
     13281        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_stack");
     13282        psFree(md);
     13283        return false;
     13284    }
     13285    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, hostname)) {
     13286        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
     13287        psFree(md);
     13288        return false;
     13289    }
     13290    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, NULL, good_frac)) {
    1344913291        psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
    1345013292        psFree(md);
     
    1347913321bool stackSumSkyfileInsertObject(psDB *dbh, stackSumSkyfileRow *object)
    1348013322{
    13481     return stackSumSkyfileInsert(dbh, object->stack_id, object->uri, object->path_base, object->bg, object->bg_stdev, object->good_frac, object->fault);
     13323    return stackSumSkyfileInsert(dbh, object->stack_id, object->uri, object->path_base, object->bg, object->bg_stdev, object->dtime_stack, object->hostname, object->good_frac, object->fault);
    1348213324}
    1348313325
     
    1357713419        return false;
    1357813420    }
    13579     if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, NULL, object->good_frac)) {
     13421    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_stack", PS_DATA_F32, NULL, object->dtime_stack)) {
     13422        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_stack");
     13423        psFree(md);
     13424        return false;
     13425    }
     13426    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, object->hostname)) {
     13427        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
     13428        psFree(md);
     13429        return false;
     13430    }
     13431    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, NULL, object->good_frac)) {
    1358013432        psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
    1358113433        psFree(md);
     
    1362113473        return false;
    1362213474    }
    13623     psF64 good_frac = psMetadataLookupF64(&status, md, "good_frac");
     13475    psF32 dtime_stack = psMetadataLookupF32(&status, md, "dtime_stack");
     13476    if (!status) {
     13477        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_stack");
     13478        return false;
     13479    }
     13480    char* hostname = psMetadataLookupPtr(&status, md, "hostname");
     13481    if (!status) {
     13482        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item hostname");
     13483        return false;
     13484    }
     13485    psF32 good_frac = psMetadataLookupF32(&status, md, "good_frac");
    1362413486    if (!status) {
    1362513487        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item good_frac");
     
    1363213494    }
    1363313495
    13634     return stackSumSkyfileRowAlloc(stack_id, uri, path_base, bg, bg_stdev, good_frac, fault);
     13496    return stackSumSkyfileRowAlloc(stack_id, uri, path_base, bg, bg_stdev, dtime_stack, hostname, good_frac, fault);
    1363513497}
    1363613498psArray *stackSumSkyfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    2354823410static void calDBRowFree(calDBRow *object);
    2354923411
    23550 calDBRow *calDBRowAlloc(psS64 cal_id, const char *catdir, const char *state)
     23412calDBRow *calDBRowAlloc(psS64 cal_id, const char *dvodb, const char *state)
    2355123413{
    2355223414    calDBRow        *_object;
     
    2355623418
    2355723419    _object->cal_id = cal_id;
    23558     _object->catdir = psStringCopy(catdir);
     23420    _object->dvodb = psStringCopy(dvodb);
    2355923421    _object->state = psStringCopy(state);
    2356023422
     
    2356423426static void calDBRowFree(calDBRow *object)
    2356523427{
    23566     psFree(object->catdir);
     23428    psFree(object->dvodb);
    2356723429    psFree(object->state);
    2356823430}
     
    2357623438        return false;
    2357723439    }
    23578     if (!psMetadataAdd(md, PS_LIST_TAIL, "catdir", PS_DATA_STRING, NULL, "64")) {
    23579         psError(PS_ERR_UNKNOWN, false, "failed to add item catdir");
     23440    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, "64")) {
     23441        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
    2358023442        psFree(md);
    2358123443        return false;
     
    2359923461}
    2360023462
    23601 bool calDBInsert(psDB * dbh, psS64 cal_id, const char *catdir, const char *state)
     23463bool calDBInsert(psDB * dbh, psS64 cal_id, const char *dvodb, const char *state)
    2360223464{
    2360323465    psMetadata *md = psMetadataAlloc();
     
    2360723469        return false;
    2360823470    }
    23609     if (!psMetadataAdd(md, PS_LIST_TAIL, "catdir", PS_DATA_STRING, NULL, catdir)) {
    23610         psError(PS_ERR_UNKNOWN, false, "failed to add item catdir");
     23471    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, dvodb)) {
     23472        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
    2361123473        psFree(md);
    2361223474        return false;
     
    2364023502bool calDBInsertObject(psDB *dbh, calDBRow *object)
    2364123503{
    23642     return calDBInsert(dbh, object->cal_id, object->catdir, object->state);
     23504    return calDBInsert(dbh, object->cal_id, object->dvodb, object->state);
    2364323505}
    2364423506
     
    2371823580        return false;
    2371923581    }
    23720     if (!psMetadataAdd(md, PS_LIST_TAIL, "catdir", PS_DATA_STRING, NULL, object->catdir)) {
    23721         psError(PS_ERR_UNKNOWN, false, "failed to add item catdir");
     23582    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, object->dvodb)) {
     23583        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
    2372223584        psFree(md);
    2372323585        return false;
     
    2374223604        return false;
    2374323605    }
    23744     char* catdir = psMetadataLookupPtr(&status, md, "catdir");
    23745     if (!status) {
    23746         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item catdir");
     23606    char* dvodb = psMetadataLookupPtr(&status, md, "dvodb");
     23607    if (!status) {
     23608        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dvodb");
    2374723609        return false;
    2374823610    }
     
    2375323615    }
    2375423616
    23755     return calDBRowAlloc(cal_id, catdir, state);
     23617    return calDBRowAlloc(cal_id, dvodb, state);
    2375623618}
    2375723619psArray *calDBSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    2421624078static void flatcorrRunRowFree(flatcorrRunRow *object);
    2421724079
    24218 flatcorrRunRow *flatcorrRunRowAlloc(psS64 corr_id, const char *dvodb, const char *state, const char *workdir, const char *label, const char *stats)
     24080flatcorrRunRow *flatcorrRunRowAlloc(psS64 corr_id, const char *dvodb, const char *filter, const char *state, const char *workdir, const char *label, const char *stats)
    2421924081{
    2422024082    flatcorrRunRow  *_object;
     
    2422524087    _object->corr_id = corr_id;
    2422624088    _object->dvodb = psStringCopy(dvodb);
     24089    _object->filter = psStringCopy(filter);
    2422724090    _object->state = psStringCopy(state);
    2422824091    _object->workdir = psStringCopy(workdir);
     
    2423624099{
    2423724100    psFree(object->dvodb);
     24101    psFree(object->filter);
    2423824102    psFree(object->state);
    2423924103    psFree(object->workdir);
     
    2425524119        return false;
    2425624120    }
     24121    if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, "64")) {
     24122        psError(PS_ERR_UNKNOWN, false, "failed to add item filter");
     24123        psFree(md);
     24124        return false;
     24125    }
    2425724126    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, "64")) {
    2425824127        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     
    2428824157}
    2428924158
    24290 bool flatcorrRunInsert(psDB * dbh, psS64 corr_id, const char *dvodb, const char *state, const char *workdir, const char *label, const char *stats)
     24159bool flatcorrRunInsert(psDB * dbh, psS64 corr_id, const char *dvodb, const char *filter, const char *state, const char *workdir, const char *label, const char *stats)
    2429124160{
    2429224161    psMetadata *md = psMetadataAlloc();
     
    2429824167    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, dvodb)) {
    2429924168        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
     24169        psFree(md);
     24170        return false;
     24171    }
     24172    if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, filter)) {
     24173        psError(PS_ERR_UNKNOWN, false, "failed to add item filter");
    2430024174        psFree(md);
    2430124175        return false;
     
    2434424218bool flatcorrRunInsertObject(psDB *dbh, flatcorrRunRow *object)
    2434524219{
    24346     return flatcorrRunInsert(dbh, object->corr_id, object->dvodb, object->state, object->workdir, object->label, object->stats);
     24220    return flatcorrRunInsert(dbh, object->corr_id, object->dvodb, object->filter, object->state, object->workdir, object->label, object->stats);
    2434724221}
    2434824222
     
    2442724301        return false;
    2442824302    }
     24303    if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, object->filter)) {
     24304        psError(PS_ERR_UNKNOWN, false, "failed to add item filter");
     24305        psFree(md);
     24306        return false;
     24307    }
    2442924308    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
    2443024309        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     
    2446624345        return false;
    2446724346    }
     24347    char* filter = psMetadataLookupPtr(&status, md, "filter");
     24348    if (!status) {
     24349        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item filter");
     24350        return false;
     24351    }
    2446824352    char* state = psMetadataLookupPtr(&status, md, "state");
    2446924353    if (!status) {
     
    2448724371    }
    2448824372
    24489     return flatcorrRunRowAlloc(corr_id, dvodb, state, workdir, label, stats);
     24373    return flatcorrRunRowAlloc(corr_id, dvodb, filter, state, workdir, label, stats);
    2449024374}
    2449124375psArray *flatcorrRunSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     
    2490324787    return true;
    2490424788}
     24789static void pstampDataStoreRowFree(pstampDataStoreRow *object);
     24790
     24791pstampDataStoreRow *pstampDataStoreRowAlloc(psS64 ds_id, const char *uri, const char *lastFileset, const char *state)
     24792{
     24793    pstampDataStoreRow *_object;
     24794
     24795    _object = psAlloc(sizeof(pstampDataStoreRow));
     24796    psMemSetDeallocator(_object, (psFreeFunc)pstampDataStoreRowFree);
     24797
     24798    _object->ds_id = ds_id;
     24799    _object->uri = psStringCopy(uri);
     24800    _object->lastFileset = psStringCopy(lastFileset);
     24801    _object->state = psStringCopy(state);
     24802
     24803    return _object;
     24804}
     24805
     24806static void pstampDataStoreRowFree(pstampDataStoreRow *object)
     24807{
     24808    psFree(object->uri);
     24809    psFree(object->lastFileset);
     24810    psFree(object->state);
     24811}
     24812
     24813bool pstampDataStoreCreateTable(psDB *dbh)
     24814{
     24815    psMetadata *md = psMetadataAlloc();
     24816    if (!psMetadataAdd(md, PS_LIST_TAIL, "ds_id", PS_DATA_S64, "Primary Key AUTO_INCREMENT", 0)) {
     24817        psError(PS_ERR_UNKNOWN, false, "failed to add item ds_id");
     24818        psFree(md);
     24819        return false;
     24820    }
     24821    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
     24822        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     24823        psFree(md);
     24824        return false;
     24825    }
     24826    if (!psMetadataAdd(md, PS_LIST_TAIL, "lastFileset", PS_DATA_STRING, NULL, "64")) {
     24827        psError(PS_ERR_UNKNOWN, false, "failed to add item lastFileset");
     24828        psFree(md);
     24829        return false;
     24830    }
     24831    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, "64")) {
     24832        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     24833        psFree(md);
     24834        return false;
     24835    }
     24836
     24837    bool status = psDBCreateTable(dbh, PSTAMPDATASTORE_TABLE_NAME, md);
     24838
     24839    psFree(md);
     24840
     24841    return status;
     24842}
     24843
     24844bool pstampDataStoreDropTable(psDB *dbh)
     24845{
     24846    return psDBDropTable(dbh, PSTAMPDATASTORE_TABLE_NAME);
     24847}
     24848
     24849bool pstampDataStoreInsert(psDB * dbh, psS64 ds_id, const char *uri, const char *lastFileset, const char *state)
     24850{
     24851    psMetadata *md = psMetadataAlloc();
     24852    if (!psMetadataAdd(md, PS_LIST_TAIL, "ds_id", PS_DATA_S64, NULL, ds_id)) {
     24853        psError(PS_ERR_UNKNOWN, false, "failed to add item ds_id");
     24854        psFree(md);
     24855        return false;
     24856    }
     24857    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
     24858        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     24859        psFree(md);
     24860        return false;
     24861    }
     24862    if (!psMetadataAdd(md, PS_LIST_TAIL, "lastFileset", PS_DATA_STRING, NULL, lastFileset)) {
     24863        psError(PS_ERR_UNKNOWN, false, "failed to add item lastFileset");
     24864        psFree(md);
     24865        return false;
     24866    }
     24867    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, state)) {
     24868        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     24869        psFree(md);
     24870        return false;
     24871    }
     24872
     24873    bool status = psDBInsertOneRow(dbh, PSTAMPDATASTORE_TABLE_NAME, md);
     24874    psFree(md);
     24875
     24876    return status;
     24877}
     24878
     24879long long pstampDataStoreDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
     24880{
     24881    long long       deleted = 0;
     24882
     24883    long long count = psDBDeleteRows(dbh, PSTAMPDATASTORE_TABLE_NAME, where, limit);
     24884    if (count < 0) {
     24885        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampDataStore");
     24886        return count;
     24887
     24888        deleted += count;
     24889    }
     24890
     24891    return deleted;
     24892}
     24893bool pstampDataStoreInsertObject(psDB *dbh, pstampDataStoreRow *object)
     24894{
     24895    return pstampDataStoreInsert(dbh, object->ds_id, object->uri, object->lastFileset, object->state);
     24896}
     24897
     24898bool pstampDataStoreInsertObjects(psDB *dbh, psArray *objects)
     24899{
     24900    for (long i = 0; i < psArrayLength(objects); i++) {
     24901        if (!pstampDataStoreInsertObject(dbh, objects->data[i])) {
     24902            return false;
     24903        }
     24904    }
     24905
     24906    return true;
     24907}
     24908
     24909bool pstampDataStoreInsertFits(psDB *dbh, const psFits *fits)
     24910{
     24911    psArray         *rowSet;
     24912
     24913    // move to (the first?) extension named  PSTAMPDATASTORE_TABLE_NAME
     24914    if (!psFitsMoveExtName(fits, PSTAMPDATASTORE_TABLE_NAME)) {
     24915        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PSTAMPDATASTORE_TABLE_NAME);
     24916        return false;
     24917    }
     24918
     24919    // check HDU type
     24920    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
     24921        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
     24922        return false;
     24923    }
     24924
     24925    // read fits table
     24926    rowSet = psFitsReadTable(fits);
     24927    if (!rowSet) {
     24928        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
     24929        psFree(rowSet);
     24930        return false;
     24931    }
     24932
     24933    if (!psDBInsertRows(dbh, PSTAMPDATASTORE_TABLE_NAME, rowSet)) {
     24934        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
     24935        psFree(rowSet);
     24936        return false;
     24937    }
     24938
     24939    psFree(rowSet);
     24940
     24941    return true;
     24942}
     24943
     24944bool pstampDataStoreSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
     24945{
     24946    psArray         *rowSet;
     24947
     24948    rowSet = psDBSelectRows(dbh, PSTAMPDATASTORE_TABLE_NAME, where, limit);
     24949    if (!rowSet) {
     24950        return false;
     24951    }
     24952
     24953    // output to fits
     24954    if (!psFitsWriteTable(fits, NULL, rowSet, PSTAMPDATASTORE_TABLE_NAME)) {
     24955        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
     24956        psFree(rowSet);
     24957        return false;
     24958    }
     24959
     24960    psFree(rowSet);
     24961
     24962    return true;
     24963}
     24964
     24965psMetadata *pstampDataStoreMetadataFromObject(const pstampDataStoreRow *object)
     24966{
     24967    psMetadata *md = psMetadataAlloc();
     24968    if (!psMetadataAdd(md, PS_LIST_TAIL, "ds_id", PS_DATA_S64, NULL, object->ds_id)) {
     24969        psError(PS_ERR_UNKNOWN, false, "failed to add item ds_id");
     24970        psFree(md);
     24971        return false;
     24972    }
     24973    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
     24974        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     24975        psFree(md);
     24976        return false;
     24977    }
     24978    if (!psMetadataAdd(md, PS_LIST_TAIL, "lastFileset", PS_DATA_STRING, NULL, object->lastFileset)) {
     24979        psError(PS_ERR_UNKNOWN, false, "failed to add item lastFileset");
     24980        psFree(md);
     24981        return false;
     24982    }
     24983    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
     24984        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     24985        psFree(md);
     24986        return false;
     24987    }
     24988
     24989
     24990    return md;
     24991}
     24992
     24993pstampDataStoreRow *pstampDataStoreObjectFromMetadata(psMetadata *md)
     24994{
     24995
     24996bool status = false;
     24997    psS64 ds_id = psMetadataLookupS64(&status, md, "ds_id");
     24998    if (!status) {
     24999        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ds_id");
     25000        return false;
     25001    }
     25002    char* uri = psMetadataLookupPtr(&status, md, "uri");
     25003    if (!status) {
     25004        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
     25005        return false;
     25006    }
     25007    char* lastFileset = psMetadataLookupPtr(&status, md, "lastFileset");
     25008    if (!status) {
     25009        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item lastFileset");
     25010        return false;
     25011    }
     25012    char* state = psMetadataLookupPtr(&status, md, "state");
     25013    if (!status) {
     25014        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
     25015        return false;
     25016    }
     25017
     25018    return pstampDataStoreRowAlloc(ds_id, uri, lastFileset, state);
     25019}
     25020psArray *pstampDataStoreSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     25021{
     25022    psArray         *rowSet;
     25023    psArray         *returnSet;
     25024    psU64           i;
     25025
     25026    rowSet = psDBSelectRows(dbh, PSTAMPDATASTORE_TABLE_NAME, where, limit);
     25027    if (!rowSet) {
     25028        return NULL;
     25029    }
     25030
     25031    // convert psMetadata rows to row objects
     25032
     25033    returnSet = psArrayAllocEmpty(rowSet->n);
     25034
     25035    for (i = 0; i < rowSet->n; i++) {
     25036        pstampDataStoreRow *object = pstampDataStoreObjectFromMetadata(rowSet->data[i]);
     25037        if (!object) {
     25038            psFree(object);
     25039            psFree(returnSet);
     25040            psError(PS_ERR_UNKNOWN, false, "database error");
     25041            return NULL;
     25042        }
     25043        psArrayAdd(returnSet, 0, object);
     25044        psFree(object);
     25045    }
     25046
     25047    psFree(rowSet);
     25048
     25049    return returnSet;
     25050}
     25051bool pstampDataStoreDeleteObject(psDB *dbh, const pstampDataStoreRow *object)
     25052{
     25053    psMetadata *where = pstampDataStoreMetadataFromObject(object);
     25054    long long count = psDBDeleteRows(dbh, PSTAMPDATASTORE_TABLE_NAME, where, 0);
     25055    psFree(where);
     25056    if (count < 0) {
     25057        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampDataStore");
     25058        return false;
     25059    }
     25060    if (count > 1) {
     25061        // XXX should this be a psAbort() instead?  It is possible that
     25062        // having an object match multiple rows was by design.
     25063        psError(PS_ERR_UNKNOWN, true, "pstampDataStoreRow object matched more then one row.  Check your database schema");
     25064        return false;
     25065    }
     25066
     25067    return true;
     25068}
     25069long long pstampDataStoreDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
     25070{
     25071    long long       deleted = 0;
     25072
     25073    for (long long i = 0; i < objects->n; i++) {
     25074        pstampDataStoreRow *object = objects->data[i];
     25075        psMetadata *where = pstampDataStoreMetadataFromObject(object);
     25076        long long count = psDBDeleteRows(dbh, PSTAMPDATASTORE_TABLE_NAME, where, limit);
     25077        psFree(where);
     25078        if (count < 0) {
     25079            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampDataStore");
     25080            return count;
     25081        }
     25082
     25083        deleted += count;
     25084    }
     25085
     25086    return deleted;
     25087}
     25088bool pstampDataStorePrintObjects(FILE *stream, psArray *objects, bool mdcf)
     25089{
     25090    PS_ASSERT_PTR_NON_NULL(objects, false);
     25091
     25092    psMetadata *output = psMetadataAlloc();
     25093    for (long i = 0; i < psArrayLength(objects); i++) {
     25094        psMetadata *md = pstampDataStoreMetadataFromObject(objects->data[i]);
     25095        if (!psMetadataAddMetadata(
     25096            output,
     25097            PS_LIST_TAIL,
     25098            PSTAMPDATASTORE_TABLE_NAME,
     25099            PS_META_DUPLICATE_OK,
     25100            NULL,
     25101            md
     25102        )) {
     25103            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
     25104            psFree(md);
     25105            psFree(output);
     25106            return false;
     25107        }
     25108        psFree(md);
     25109    }
     25110
     25111    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
     25112        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     25113        psFree(output);
     25114    }
     25115    psFree(output);
     25116
     25117    return true;
     25118}
     25119bool pstampDataStorePrintObject(FILE *stream, pstampDataStoreRow *object, bool mdcf)
     25120{
     25121    PS_ASSERT_PTR_NON_NULL(object, false);
     25122
     25123    psMetadata *md = pstampDataStoreMetadataFromObject(object);
     25124
     25125    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
     25126        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     25127        psFree(md);
     25128    }
     25129
     25130    psFree(md);
     25131
     25132    return true;
     25133}
     25134static void pstampRequestRowFree(pstampRequestRow *object);
     25135
     25136pstampRequestRow *pstampRequestRowAlloc(psS64 req_id, psS64 ds_id, const char *state, const char *uri)
     25137{
     25138    pstampRequestRow *_object;
     25139
     25140    _object = psAlloc(sizeof(pstampRequestRow));
     25141    psMemSetDeallocator(_object, (psFreeFunc)pstampRequestRowFree);
     25142
     25143    _object->req_id = req_id;
     25144    _object->ds_id = ds_id;
     25145    _object->state = psStringCopy(state);
     25146    _object->uri = psStringCopy(uri);
     25147
     25148    return _object;
     25149}
     25150
     25151static void pstampRequestRowFree(pstampRequestRow *object)
     25152{
     25153    psFree(object->state);
     25154    psFree(object->uri);
     25155}
     25156
     25157bool pstampRequestCreateTable(psDB *dbh)
     25158{
     25159    psMetadata *md = psMetadataAlloc();
     25160    if (!psMetadataAdd(md, PS_LIST_TAIL, "req_id", PS_DATA_S64, "Primary Key AUTO_INCREMENT", 0)) {
     25161        psError(PS_ERR_UNKNOWN, false, "failed to add item req_id");
     25162        psFree(md);
     25163        return false;
     25164    }
     25165    if (!psMetadataAdd(md, PS_LIST_TAIL, "ds_id", PS_DATA_S64, NULL, 0)) {
     25166        psError(PS_ERR_UNKNOWN, false, "failed to add item ds_id");
     25167        psFree(md);
     25168        return false;
     25169    }
     25170    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, "64")) {
     25171        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     25172        psFree(md);
     25173        return false;
     25174    }
     25175    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
     25176        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     25177        psFree(md);
     25178        return false;
     25179    }
     25180
     25181    bool status = psDBCreateTable(dbh, PSTAMPREQUEST_TABLE_NAME, md);
     25182
     25183    psFree(md);
     25184
     25185    return status;
     25186}
     25187
     25188bool pstampRequestDropTable(psDB *dbh)
     25189{
     25190    return psDBDropTable(dbh, PSTAMPREQUEST_TABLE_NAME);
     25191}
     25192
     25193bool pstampRequestInsert(psDB * dbh, psS64 req_id, psS64 ds_id, const char *state, const char *uri)
     25194{
     25195    psMetadata *md = psMetadataAlloc();
     25196    if (!psMetadataAdd(md, PS_LIST_TAIL, "req_id", PS_DATA_S64, NULL, req_id)) {
     25197        psError(PS_ERR_UNKNOWN, false, "failed to add item req_id");
     25198        psFree(md);
     25199        return false;
     25200    }
     25201    if (!psMetadataAdd(md, PS_LIST_TAIL, "ds_id", PS_DATA_S64, NULL, ds_id)) {
     25202        psError(PS_ERR_UNKNOWN, false, "failed to add item ds_id");
     25203        psFree(md);
     25204        return false;
     25205    }
     25206    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, state)) {
     25207        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     25208        psFree(md);
     25209        return false;
     25210    }
     25211    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
     25212        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     25213        psFree(md);
     25214        return false;
     25215    }
     25216
     25217    bool status = psDBInsertOneRow(dbh, PSTAMPREQUEST_TABLE_NAME, md);
     25218    psFree(md);
     25219
     25220    return status;
     25221}
     25222
     25223long long pstampRequestDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
     25224{
     25225    long long       deleted = 0;
     25226
     25227    long long count = psDBDeleteRows(dbh, PSTAMPREQUEST_TABLE_NAME, where, limit);
     25228    if (count < 0) {
     25229        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampRequest");
     25230        return count;
     25231
     25232        deleted += count;
     25233    }
     25234
     25235    return deleted;
     25236}
     25237bool pstampRequestInsertObject(psDB *dbh, pstampRequestRow *object)
     25238{
     25239    return pstampRequestInsert(dbh, object->req_id, object->ds_id, object->state, object->uri);
     25240}
     25241
     25242bool pstampRequestInsertObjects(psDB *dbh, psArray *objects)
     25243{
     25244    for (long i = 0; i < psArrayLength(objects); i++) {
     25245        if (!pstampRequestInsertObject(dbh, objects->data[i])) {
     25246            return false;
     25247        }
     25248    }
     25249
     25250    return true;
     25251}
     25252
     25253bool pstampRequestInsertFits(psDB *dbh, const psFits *fits)
     25254{
     25255    psArray         *rowSet;
     25256
     25257    // move to (the first?) extension named  PSTAMPREQUEST_TABLE_NAME
     25258    if (!psFitsMoveExtName(fits, PSTAMPREQUEST_TABLE_NAME)) {
     25259        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PSTAMPREQUEST_TABLE_NAME);
     25260        return false;
     25261    }
     25262
     25263    // check HDU type
     25264    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
     25265        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
     25266        return false;
     25267    }
     25268
     25269    // read fits table
     25270    rowSet = psFitsReadTable(fits);
     25271    if (!rowSet) {
     25272        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
     25273        psFree(rowSet);
     25274        return false;
     25275    }
     25276
     25277    if (!psDBInsertRows(dbh, PSTAMPREQUEST_TABLE_NAME, rowSet)) {
     25278        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
     25279        psFree(rowSet);
     25280        return false;
     25281    }
     25282
     25283    psFree(rowSet);
     25284
     25285    return true;
     25286}
     25287
     25288bool pstampRequestSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
     25289{
     25290    psArray         *rowSet;
     25291
     25292    rowSet = psDBSelectRows(dbh, PSTAMPREQUEST_TABLE_NAME, where, limit);
     25293    if (!rowSet) {
     25294        return false;
     25295    }
     25296
     25297    // output to fits
     25298    if (!psFitsWriteTable(fits, NULL, rowSet, PSTAMPREQUEST_TABLE_NAME)) {
     25299        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
     25300        psFree(rowSet);
     25301        return false;
     25302    }
     25303
     25304    psFree(rowSet);
     25305
     25306    return true;
     25307}
     25308
     25309psMetadata *pstampRequestMetadataFromObject(const pstampRequestRow *object)
     25310{
     25311    psMetadata *md = psMetadataAlloc();
     25312    if (!psMetadataAdd(md, PS_LIST_TAIL, "req_id", PS_DATA_S64, NULL, object->req_id)) {
     25313        psError(PS_ERR_UNKNOWN, false, "failed to add item req_id");
     25314        psFree(md);
     25315        return false;
     25316    }
     25317    if (!psMetadataAdd(md, PS_LIST_TAIL, "ds_id", PS_DATA_S64, NULL, object->ds_id)) {
     25318        psError(PS_ERR_UNKNOWN, false, "failed to add item ds_id");
     25319        psFree(md);
     25320        return false;
     25321    }
     25322    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
     25323        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     25324        psFree(md);
     25325        return false;
     25326    }
     25327    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
     25328        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     25329        psFree(md);
     25330        return false;
     25331    }
     25332
     25333
     25334    return md;
     25335}
     25336
     25337pstampRequestRow *pstampRequestObjectFromMetadata(psMetadata *md)
     25338{
     25339
     25340bool status = false;
     25341    psS64 req_id = psMetadataLookupS64(&status, md, "req_id");
     25342    if (!status) {
     25343        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item req_id");
     25344        return false;
     25345    }
     25346    psS64 ds_id = psMetadataLookupS64(&status, md, "ds_id");
     25347    if (!status) {
     25348        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ds_id");
     25349        return false;
     25350    }
     25351    char* state = psMetadataLookupPtr(&status, md, "state");
     25352    if (!status) {
     25353        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
     25354        return false;
     25355    }
     25356    char* uri = psMetadataLookupPtr(&status, md, "uri");
     25357    if (!status) {
     25358        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
     25359        return false;
     25360    }
     25361
     25362    return pstampRequestRowAlloc(req_id, ds_id, state, uri);
     25363}
     25364psArray *pstampRequestSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     25365{
     25366    psArray         *rowSet;
     25367    psArray         *returnSet;
     25368    psU64           i;
     25369
     25370    rowSet = psDBSelectRows(dbh, PSTAMPREQUEST_TABLE_NAME, where, limit);
     25371    if (!rowSet) {
     25372        return NULL;
     25373    }
     25374
     25375    // convert psMetadata rows to row objects
     25376
     25377    returnSet = psArrayAllocEmpty(rowSet->n);
     25378
     25379    for (i = 0; i < rowSet->n; i++) {
     25380        pstampRequestRow *object = pstampRequestObjectFromMetadata(rowSet->data[i]);
     25381        if (!object) {
     25382            psFree(object);
     25383            psFree(returnSet);
     25384            psError(PS_ERR_UNKNOWN, false, "database error");
     25385            return NULL;
     25386        }
     25387        psArrayAdd(returnSet, 0, object);
     25388        psFree(object);
     25389    }
     25390
     25391    psFree(rowSet);
     25392
     25393    return returnSet;
     25394}
     25395bool pstampRequestDeleteObject(psDB *dbh, const pstampRequestRow *object)
     25396{
     25397    psMetadata *where = pstampRequestMetadataFromObject(object);
     25398    long long count = psDBDeleteRows(dbh, PSTAMPREQUEST_TABLE_NAME, where, 0);
     25399    psFree(where);
     25400    if (count < 0) {
     25401        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampRequest");
     25402        return false;
     25403    }
     25404    if (count > 1) {
     25405        // XXX should this be a psAbort() instead?  It is possible that
     25406        // having an object match multiple rows was by design.
     25407        psError(PS_ERR_UNKNOWN, true, "pstampRequestRow object matched more then one row.  Check your database schema");
     25408        return false;
     25409    }
     25410
     25411    return true;
     25412}
     25413long long pstampRequestDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
     25414{
     25415    long long       deleted = 0;
     25416
     25417    for (long long i = 0; i < objects->n; i++) {
     25418        pstampRequestRow *object = objects->data[i];
     25419        psMetadata *where = pstampRequestMetadataFromObject(object);
     25420        long long count = psDBDeleteRows(dbh, PSTAMPREQUEST_TABLE_NAME, where, limit);
     25421        psFree(where);
     25422        if (count < 0) {
     25423            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampRequest");
     25424            return count;
     25425        }
     25426
     25427        deleted += count;
     25428    }
     25429
     25430    return deleted;
     25431}
     25432bool pstampRequestPrintObjects(FILE *stream, psArray *objects, bool mdcf)
     25433{
     25434    PS_ASSERT_PTR_NON_NULL(objects, false);
     25435
     25436    psMetadata *output = psMetadataAlloc();
     25437    for (long i = 0; i < psArrayLength(objects); i++) {
     25438        psMetadata *md = pstampRequestMetadataFromObject(objects->data[i]);
     25439        if (!psMetadataAddMetadata(
     25440            output,
     25441            PS_LIST_TAIL,
     25442            PSTAMPREQUEST_TABLE_NAME,
     25443            PS_META_DUPLICATE_OK,
     25444            NULL,
     25445            md
     25446        )) {
     25447            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
     25448            psFree(md);
     25449            psFree(output);
     25450            return false;
     25451        }
     25452        psFree(md);
     25453    }
     25454
     25455    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
     25456        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     25457        psFree(output);
     25458    }
     25459    psFree(output);
     25460
     25461    return true;
     25462}
     25463bool pstampRequestPrintObject(FILE *stream, pstampRequestRow *object, bool mdcf)
     25464{
     25465    PS_ASSERT_PTR_NON_NULL(object, false);
     25466
     25467    psMetadata *md = pstampRequestMetadataFromObject(object);
     25468
     25469    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
     25470        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     25471        psFree(md);
     25472    }
     25473
     25474    psFree(md);
     25475
     25476    return true;
     25477}
     25478static void pstampJobRowFree(pstampJobRow *object);
     25479
     25480pstampJobRow *pstampJobRowAlloc(psS64 job_id, psS64 req_id, const char *state, psS32 result, const char *uri, const char *outputBase, const char *args)
     25481{
     25482    pstampJobRow    *_object;
     25483
     25484    _object = psAlloc(sizeof(pstampJobRow));
     25485    psMemSetDeallocator(_object, (psFreeFunc)pstampJobRowFree);
     25486
     25487    _object->job_id = job_id;
     25488    _object->req_id = req_id;
     25489    _object->state = psStringCopy(state);
     25490    _object->result = result;
     25491    _object->uri = psStringCopy(uri);
     25492    _object->outputBase = psStringCopy(outputBase);
     25493    _object->args = psStringCopy(args);
     25494
     25495    return _object;
     25496}
     25497
     25498static void pstampJobRowFree(pstampJobRow *object)
     25499{
     25500    psFree(object->state);
     25501    psFree(object->uri);
     25502    psFree(object->outputBase);
     25503    psFree(object->args);
     25504}
     25505
     25506bool pstampJobCreateTable(psDB *dbh)
     25507{
     25508    psMetadata *md = psMetadataAlloc();
     25509    if (!psMetadataAdd(md, PS_LIST_TAIL, "job_id", PS_DATA_S64, "Primary Key AUTO_INCREMENT", 0)) {
     25510        psError(PS_ERR_UNKNOWN, false, "failed to add item job_id");
     25511        psFree(md);
     25512        return false;
     25513    }
     25514    if (!psMetadataAdd(md, PS_LIST_TAIL, "req_id", PS_DATA_S64, "Primary Key fkey(req_id) ref pstampRequest(req_id)", 0)) {
     25515        psError(PS_ERR_UNKNOWN, false, "failed to add item req_id");
     25516        psFree(md);
     25517        return false;
     25518    }
     25519    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, "64")) {
     25520        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     25521        psFree(md);
     25522        return false;
     25523    }
     25524    if (!psMetadataAdd(md, PS_LIST_TAIL, "result", PS_DATA_S32, NULL, 0)) {
     25525        psError(PS_ERR_UNKNOWN, false, "failed to add item result");
     25526        psFree(md);
     25527        return false;
     25528    }
     25529    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
     25530        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     25531        psFree(md);
     25532        return false;
     25533    }
     25534    if (!psMetadataAdd(md, PS_LIST_TAIL, "outputBase", PS_DATA_STRING, NULL, "255")) {
     25535        psError(PS_ERR_UNKNOWN, false, "failed to add item outputBase");
     25536        psFree(md);
     25537        return false;
     25538    }
     25539    if (!psMetadataAdd(md, PS_LIST_TAIL, "args", PS_DATA_STRING, NULL, "511")) {
     25540        psError(PS_ERR_UNKNOWN, false, "failed to add item args");
     25541        psFree(md);
     25542        return false;
     25543    }
     25544
     25545    bool status = psDBCreateTable(dbh, PSTAMPJOB_TABLE_NAME, md);
     25546
     25547    psFree(md);
     25548
     25549    return status;
     25550}
     25551
     25552bool pstampJobDropTable(psDB *dbh)
     25553{
     25554    return psDBDropTable(dbh, PSTAMPJOB_TABLE_NAME);
     25555}
     25556
     25557bool pstampJobInsert(psDB * dbh, psS64 job_id, psS64 req_id, const char *state, psS32 result, const char *uri, const char *outputBase, const char *args)
     25558{
     25559    psMetadata *md = psMetadataAlloc();
     25560    if (!psMetadataAdd(md, PS_LIST_TAIL, "job_id", PS_DATA_S64, NULL, job_id)) {
     25561        psError(PS_ERR_UNKNOWN, false, "failed to add item job_id");
     25562        psFree(md);
     25563        return false;
     25564    }
     25565    if (!psMetadataAdd(md, PS_LIST_TAIL, "req_id", PS_DATA_S64, NULL, req_id)) {
     25566        psError(PS_ERR_UNKNOWN, false, "failed to add item req_id");
     25567        psFree(md);
     25568        return false;
     25569    }
     25570    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, state)) {
     25571        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     25572        psFree(md);
     25573        return false;
     25574    }
     25575    if (!psMetadataAdd(md, PS_LIST_TAIL, "result", PS_DATA_S32, NULL, result)) {
     25576        psError(PS_ERR_UNKNOWN, false, "failed to add item result");
     25577        psFree(md);
     25578        return false;
     25579    }
     25580    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
     25581        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     25582        psFree(md);
     25583        return false;
     25584    }
     25585    if (!psMetadataAdd(md, PS_LIST_TAIL, "outputBase", PS_DATA_STRING, NULL, outputBase)) {
     25586        psError(PS_ERR_UNKNOWN, false, "failed to add item outputBase");
     25587        psFree(md);
     25588        return false;
     25589    }
     25590    if (!psMetadataAdd(md, PS_LIST_TAIL, "args", PS_DATA_STRING, NULL, args)) {
     25591        psError(PS_ERR_UNKNOWN, false, "failed to add item args");
     25592        psFree(md);
     25593        return false;
     25594    }
     25595
     25596    bool status = psDBInsertOneRow(dbh, PSTAMPJOB_TABLE_NAME, md);
     25597    psFree(md);
     25598
     25599    return status;
     25600}
     25601
     25602long long pstampJobDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
     25603{
     25604    long long       deleted = 0;
     25605
     25606    long long count = psDBDeleteRows(dbh, PSTAMPJOB_TABLE_NAME, where, limit);
     25607    if (count < 0) {
     25608        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampJob");
     25609        return count;
     25610
     25611        deleted += count;
     25612    }
     25613
     25614    return deleted;
     25615}
     25616bool pstampJobInsertObject(psDB *dbh, pstampJobRow *object)
     25617{
     25618    return pstampJobInsert(dbh, object->job_id, object->req_id, object->state, object->result, object->uri, object->outputBase, object->args);
     25619}
     25620
     25621bool pstampJobInsertObjects(psDB *dbh, psArray *objects)
     25622{
     25623    for (long i = 0; i < psArrayLength(objects); i++) {
     25624        if (!pstampJobInsertObject(dbh, objects->data[i])) {
     25625            return false;
     25626        }
     25627    }
     25628
     25629    return true;
     25630}
     25631
     25632bool pstampJobInsertFits(psDB *dbh, const psFits *fits)
     25633{
     25634    psArray         *rowSet;
     25635
     25636    // move to (the first?) extension named  PSTAMPJOB_TABLE_NAME
     25637    if (!psFitsMoveExtName(fits, PSTAMPJOB_TABLE_NAME)) {
     25638        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PSTAMPJOB_TABLE_NAME);
     25639        return false;
     25640    }
     25641
     25642    // check HDU type
     25643    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
     25644        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
     25645        return false;
     25646    }
     25647
     25648    // read fits table
     25649    rowSet = psFitsReadTable(fits);
     25650    if (!rowSet) {
     25651        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
     25652        psFree(rowSet);
     25653        return false;
     25654    }
     25655
     25656    if (!psDBInsertRows(dbh, PSTAMPJOB_TABLE_NAME, rowSet)) {
     25657        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
     25658        psFree(rowSet);
     25659        return false;
     25660    }
     25661
     25662    psFree(rowSet);
     25663
     25664    return true;
     25665}
     25666
     25667bool pstampJobSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
     25668{
     25669    psArray         *rowSet;
     25670
     25671    rowSet = psDBSelectRows(dbh, PSTAMPJOB_TABLE_NAME, where, limit);
     25672    if (!rowSet) {
     25673        return false;
     25674    }
     25675
     25676    // output to fits
     25677    if (!psFitsWriteTable(fits, NULL, rowSet, PSTAMPJOB_TABLE_NAME)) {
     25678        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
     25679        psFree(rowSet);
     25680        return false;
     25681    }
     25682
     25683    psFree(rowSet);
     25684
     25685    return true;
     25686}
     25687
     25688psMetadata *pstampJobMetadataFromObject(const pstampJobRow *object)
     25689{
     25690    psMetadata *md = psMetadataAlloc();
     25691    if (!psMetadataAdd(md, PS_LIST_TAIL, "job_id", PS_DATA_S64, NULL, object->job_id)) {
     25692        psError(PS_ERR_UNKNOWN, false, "failed to add item job_id");
     25693        psFree(md);
     25694        return false;
     25695    }
     25696    if (!psMetadataAdd(md, PS_LIST_TAIL, "req_id", PS_DATA_S64, NULL, object->req_id)) {
     25697        psError(PS_ERR_UNKNOWN, false, "failed to add item req_id");
     25698        psFree(md);
     25699        return false;
     25700    }
     25701    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
     25702        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
     25703        psFree(md);
     25704        return false;
     25705    }
     25706    if (!psMetadataAdd(md, PS_LIST_TAIL, "result", PS_DATA_S32, NULL, object->result)) {
     25707        psError(PS_ERR_UNKNOWN, false, "failed to add item result");
     25708        psFree(md);
     25709        return false;
     25710    }
     25711    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
     25712        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
     25713        psFree(md);
     25714        return false;
     25715    }
     25716    if (!psMetadataAdd(md, PS_LIST_TAIL, "outputBase", PS_DATA_STRING, NULL, object->outputBase)) {
     25717        psError(PS_ERR_UNKNOWN, false, "failed to add item outputBase");
     25718        psFree(md);
     25719        return false;
     25720    }
     25721    if (!psMetadataAdd(md, PS_LIST_TAIL, "args", PS_DATA_STRING, NULL, object->args)) {
     25722        psError(PS_ERR_UNKNOWN, false, "failed to add item args");
     25723        psFree(md);
     25724        return false;
     25725    }
     25726
     25727
     25728    return md;
     25729}
     25730
     25731pstampJobRow *pstampJobObjectFromMetadata(psMetadata *md)
     25732{
     25733
     25734bool status = false;
     25735    psS64 job_id = psMetadataLookupS64(&status, md, "job_id");
     25736    if (!status) {
     25737        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item job_id");
     25738        return false;
     25739    }
     25740    psS64 req_id = psMetadataLookupS64(&status, md, "req_id");
     25741    if (!status) {
     25742        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item req_id");
     25743        return false;
     25744    }
     25745    char* state = psMetadataLookupPtr(&status, md, "state");
     25746    if (!status) {
     25747        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
     25748        return false;
     25749    }
     25750    psS32 result = psMetadataLookupS32(&status, md, "result");
     25751    if (!status) {
     25752        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item result");
     25753        return false;
     25754    }
     25755    char* uri = psMetadataLookupPtr(&status, md, "uri");
     25756    if (!status) {
     25757        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
     25758        return false;
     25759    }
     25760    char* outputBase = psMetadataLookupPtr(&status, md, "outputBase");
     25761    if (!status) {
     25762        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item outputBase");
     25763        return false;
     25764    }
     25765    char* args = psMetadataLookupPtr(&status, md, "args");
     25766    if (!status) {
     25767        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item args");
     25768        return false;
     25769    }
     25770
     25771    return pstampJobRowAlloc(job_id, req_id, state, result, uri, outputBase, args);
     25772}
     25773psArray *pstampJobSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
     25774{
     25775    psArray         *rowSet;
     25776    psArray         *returnSet;
     25777    psU64           i;
     25778
     25779    rowSet = psDBSelectRows(dbh, PSTAMPJOB_TABLE_NAME, where, limit);
     25780    if (!rowSet) {
     25781        return NULL;
     25782    }
     25783
     25784    // convert psMetadata rows to row objects
     25785
     25786    returnSet = psArrayAllocEmpty(rowSet->n);
     25787
     25788    for (i = 0; i < rowSet->n; i++) {
     25789        pstampJobRow *object = pstampJobObjectFromMetadata(rowSet->data[i]);
     25790        if (!object) {
     25791            psFree(object);
     25792            psFree(returnSet);
     25793            psError(PS_ERR_UNKNOWN, false, "database error");
     25794            return NULL;
     25795        }
     25796        psArrayAdd(returnSet, 0, object);
     25797        psFree(object);
     25798    }
     25799
     25800    psFree(rowSet);
     25801
     25802    return returnSet;
     25803}
     25804bool pstampJobDeleteObject(psDB *dbh, const pstampJobRow *object)
     25805{
     25806    psMetadata *where = pstampJobMetadataFromObject(object);
     25807    long long count = psDBDeleteRows(dbh, PSTAMPJOB_TABLE_NAME, where, 0);
     25808    psFree(where);
     25809    if (count < 0) {
     25810        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampJob");
     25811        return false;
     25812    }
     25813    if (count > 1) {
     25814        // XXX should this be a psAbort() instead?  It is possible that
     25815        // having an object match multiple rows was by design.
     25816        psError(PS_ERR_UNKNOWN, true, "pstampJobRow object matched more then one row.  Check your database schema");
     25817        return false;
     25818    }
     25819
     25820    return true;
     25821}
     25822long long pstampJobDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
     25823{
     25824    long long       deleted = 0;
     25825
     25826    for (long long i = 0; i < objects->n; i++) {
     25827        pstampJobRow *object = objects->data[i];
     25828        psMetadata *where = pstampJobMetadataFromObject(object);
     25829        long long count = psDBDeleteRows(dbh, PSTAMPJOB_TABLE_NAME, where, limit);
     25830        psFree(where);
     25831        if (count < 0) {
     25832            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampJob");
     25833            return count;
     25834        }
     25835
     25836        deleted += count;
     25837    }
     25838
     25839    return deleted;
     25840}
     25841bool pstampJobPrintObjects(FILE *stream, psArray *objects, bool mdcf)
     25842{
     25843    PS_ASSERT_PTR_NON_NULL(objects, false);
     25844
     25845    psMetadata *output = psMetadataAlloc();
     25846    for (long i = 0; i < psArrayLength(objects); i++) {
     25847        psMetadata *md = pstampJobMetadataFromObject(objects->data[i]);
     25848        if (!psMetadataAddMetadata(
     25849            output,
     25850            PS_LIST_TAIL,
     25851            PSTAMPJOB_TABLE_NAME,
     25852            PS_META_DUPLICATE_OK,
     25853            NULL,
     25854            md
     25855        )) {
     25856            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
     25857            psFree(md);
     25858            psFree(output);
     25859            return false;
     25860        }
     25861        psFree(md);
     25862    }
     25863
     25864    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
     25865        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     25866        psFree(output);
     25867    }
     25868    psFree(output);
     25869
     25870    return true;
     25871}
     25872bool pstampJobPrintObject(FILE *stream, pstampJobRow *object, bool mdcf)
     25873{
     25874    PS_ASSERT_PTR_NON_NULL(object, false);
     25875
     25876    psMetadata *md = pstampJobMetadataFromObject(object);
     25877
     25878    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
     25879        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
     25880        psFree(md);
     25881    }
     25882
     25883    psFree(md);
     25884
     25885    return true;
     25886}
Note: See TracChangeset for help on using the changeset viewer.