Index: trunk/ippdb/src/ippdb.c
===================================================================
--- trunk/ippdb/src/ippdb.c	(revision 16177)
+++ trunk/ippdb/src/ippdb.c	(revision 16587)
@@ -34,8 +34,6 @@
 #define SUMMITEXP_TABLE_NAME "summitExp"
 #define SUMMITIMFILE_TABLE_NAME "summitImfile"
-#define PZPENDINGEXP_TABLE_NAME "pzPendingExp"
-#define PZPENDINGIMFILE_TABLE_NAME "pzPendingImfile"
-#define PZDONEEXP_TABLE_NAME "pzDoneExp"
-#define PZDONEIMFILE_TABLE_NAME "pzDoneImfile"
+#define PZDOWNLOADEXP_TABLE_NAME "pzDownloadExp"
+#define PZDOWNLOADIMFILE_TABLE_NAME "pzDownloadImfile"
 #define NEWEXP_TABLE_NAME "newExp"
 #define NEWIMFILE_TABLE_NAME "newImfile"
@@ -83,4 +81,7 @@
 #define FLATCORRRUN_TABLE_NAME "flatcorrRun"
 #define FLATCORREXP_TABLE_NAME "flatcorrExp"
+#define PSTAMPDATASTORE_TABLE_NAME "pstampDataStore"
+#define PSTAMPREQUEST_TABLE_NAME "pstampRequest"
+#define PSTAMPJOB_TABLE_NAME "pstampJob"
 #define MAX_STRING_LENGTH 1024
 
@@ -1031,5 +1032,5 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, "Primary Key", "64")) {
+    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")) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
         psFree(md);
@@ -1449,31 +1450,33 @@
     return true;
 }
-static void pzPendingExpRowFree(pzPendingExpRow *object);
-
-pzPendingExpRow *pzPendingExpRowAlloc(const char *exp_name, const char *camera, const char *telescope)
-{
-    pzPendingExpRow *_object;
-
-    _object = psAlloc(sizeof(pzPendingExpRow));
-    psMemSetDeallocator(_object, (psFreeFunc)pzPendingExpRowFree);
+static void pzDownloadExpRowFree(pzDownloadExpRow *object);
+
+pzDownloadExpRow *pzDownloadExpRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *state)
+{
+    pzDownloadExpRow *_object;
+
+    _object = psAlloc(sizeof(pzDownloadExpRow));
+    psMemSetDeallocator(_object, (psFreeFunc)pzDownloadExpRowFree);
 
     _object->exp_name = psStringCopy(exp_name);
     _object->camera = psStringCopy(camera);
     _object->telescope = psStringCopy(telescope);
+    _object->state = psStringCopy(state);
 
     return _object;
 }
 
-static void pzPendingExpRowFree(pzPendingExpRow *object)
+static void pzDownloadExpRowFree(pzDownloadExpRow *object)
 {
     psFree(object->exp_name);
     psFree(object->camera);
     psFree(object->telescope);
-}
-
-bool pzPendingExpCreateTable(psDB *dbh)
+    psFree(object->state);
+}
+
+bool pzDownloadExpCreateTable(psDB *dbh)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, "Primary Key", "64")) {
+    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")) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
         psFree(md);
@@ -1490,6 +1493,11 @@
         return false;
     }
-
-    bool status = psDBCreateTable(dbh, PZPENDINGEXP_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, "Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, PZDOWNLOADEXP_TABLE_NAME, md);
 
     psFree(md);
@@ -1498,10 +1506,10 @@
 }
 
-bool pzPendingExpDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, PZPENDINGEXP_TABLE_NAME);
-}
-
-bool pzPendingExpInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope)
+bool pzDownloadExpDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, PZDOWNLOADEXP_TABLE_NAME);
+}
+
+bool pzDownloadExpInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *state)
 {
     psMetadata *md = psMetadataAlloc();
@@ -1521,6 +1529,11 @@
         return false;
     }
-
-    bool status = psDBInsertOneRow(dbh, PZPENDINGEXP_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, PZDOWNLOADEXP_TABLE_NAME, md);
     psFree(md);
 
@@ -1528,11 +1541,11 @@
 }
 
-long long pzPendingExpDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+long long pzDownloadExpDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     long long       deleted = 0;
 
-    long long count = psDBDeleteRows(dbh, PZPENDINGEXP_TABLE_NAME, where, limit);
+    long long count = psDBDeleteRows(dbh, PZDOWNLOADEXP_TABLE_NAME, where, limit);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingExp");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDownloadExp");
         return count;
 
@@ -1542,13 +1555,13 @@
     return deleted;
 }
-bool pzPendingExpInsertObject(psDB *dbh, pzPendingExpRow *object)
-{
-    return pzPendingExpInsert(dbh, object->exp_name, object->camera, object->telescope);
-}
-
-bool pzPendingExpInsertObjects(psDB *dbh, psArray *objects)
+bool pzDownloadExpInsertObject(psDB *dbh, pzDownloadExpRow *object)
+{
+    return pzDownloadExpInsert(dbh, object->exp_name, object->camera, object->telescope, object->state);
+}
+
+bool pzDownloadExpInsertObjects(psDB *dbh, psArray *objects)
 {
     for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!pzPendingExpInsertObject(dbh, objects->data[i])) {
+        if (!pzDownloadExpInsertObject(dbh, objects->data[i])) {
             return false;
         }
@@ -1558,11 +1571,11 @@
 }
 
-bool pzPendingExpInsertFits(psDB *dbh, const psFits *fits)
+bool pzDownloadExpInsertFits(psDB *dbh, const psFits *fits)
 {
     psArray         *rowSet;
 
-    // move to (the first?) extension named  PZPENDINGEXP_TABLE_NAME
-    if (!psFitsMoveExtName(fits, PZPENDINGEXP_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PZPENDINGEXP_TABLE_NAME);
+    // move to (the first?) extension named  PZDOWNLOADEXP_TABLE_NAME
+    if (!psFitsMoveExtName(fits, PZDOWNLOADEXP_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PZDOWNLOADEXP_TABLE_NAME);
         return false;
     }
@@ -1582,5 +1595,5 @@
     }
 
-    if (!psDBInsertRows(dbh, PZPENDINGEXP_TABLE_NAME, rowSet)) {
+    if (!psDBInsertRows(dbh, PZDOWNLOADEXP_TABLE_NAME, rowSet)) {
         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
         psFree(rowSet);
@@ -1593,9 +1606,9 @@
 }
 
-bool pzPendingExpSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+bool pzDownloadExpSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
 
-    rowSet = psDBSelectRows(dbh, PZPENDINGEXP_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, PZDOWNLOADEXP_TABLE_NAME, where, limit);
     if (!rowSet) {
         return false;
@@ -1603,5 +1616,5 @@
 
     // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, PZPENDINGEXP_TABLE_NAME)) {
+    if (!psFitsWriteTable(fits, NULL, rowSet, PZDOWNLOADEXP_TABLE_NAME)) {
         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
         psFree(rowSet);
@@ -1614,5 +1627,5 @@
 }
 
-psMetadata *pzPendingExpMetadataFromObject(const pzPendingExpRow *object)
+psMetadata *pzDownloadExpMetadataFromObject(const pzDownloadExpRow *object)
 {
     psMetadata *md = psMetadataAlloc();
@@ -1632,4 +1645,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
 
 
@@ -1637,5 +1655,5 @@
 }
 
-pzPendingExpRow *pzPendingExpObjectFromMetadata(psMetadata *md)
+pzDownloadExpRow *pzDownloadExpObjectFromMetadata(psMetadata *md)
 {
 
@@ -1656,8 +1674,13 @@
         return false;
     }
-
-    return pzPendingExpRowAlloc(exp_name, camera, telescope);
-}
-psArray *pzPendingExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+    char* state = psMetadataLookupPtr(&status, md, "state");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
+        return false;
+    }
+
+    return pzDownloadExpRowAlloc(exp_name, camera, telescope, state);
+}
+psArray *pzDownloadExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
@@ -1665,5 +1688,5 @@
     psU64           i;
 
-    rowSet = psDBSelectRows(dbh, PZPENDINGEXP_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, PZDOWNLOADEXP_TABLE_NAME, where, limit);
     if (!rowSet) {
         return NULL;
@@ -1675,5 +1698,5 @@
 
     for (i = 0; i < rowSet->n; i++) {
-        pzPendingExpRow *object = pzPendingExpObjectFromMetadata(rowSet->data[i]);
+        pzDownloadExpRow *object = pzDownloadExpObjectFromMetadata(rowSet->data[i]);
         if (!object) {
             psFree(object);
@@ -1690,11 +1713,11 @@
     return returnSet;
 }
-bool pzPendingExpDeleteObject(psDB *dbh, const pzPendingExpRow *object)
-{
-    psMetadata *where = pzPendingExpMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, PZPENDINGEXP_TABLE_NAME, where, 0);
+bool pzDownloadExpDeleteObject(psDB *dbh, const pzDownloadExpRow *object)
+{
+    psMetadata *where = pzDownloadExpMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, PZDOWNLOADEXP_TABLE_NAME, where, 0);
     psFree(where);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingExp");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDownloadExp");
         return false;
     }
@@ -1702,21 +1725,21 @@
         // XXX should this be a psAbort() instead?  It is possible that
         // having an object match multiple rows was by design.
-        psError(PS_ERR_UNKNOWN, true, "pzPendingExpRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long pzPendingExpDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+        psError(PS_ERR_UNKNOWN, true, "pzDownloadExpRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long pzDownloadExpDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
 {
     long long       deleted = 0;
 
     for (long long i = 0; i < objects->n; i++) {
-        pzPendingExpRow *object = objects->data[i];
-        psMetadata *where = pzPendingExpMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, PZPENDINGEXP_TABLE_NAME, where, limit);
+        pzDownloadExpRow *object = objects->data[i];
+        psMetadata *where = pzDownloadExpMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, PZDOWNLOADEXP_TABLE_NAME, where, limit);
         psFree(where);
         if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingExp");
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDownloadExp");
             return count;
         }
@@ -1727,5 +1750,5 @@
     return deleted;
 }
-bool pzPendingExpPrintObjects(FILE *stream, psArray *objects, bool mdcf)
+bool pzDownloadExpPrintObjects(FILE *stream, psArray *objects, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(objects, false);
@@ -1733,9 +1756,9 @@
     psMetadata *output = psMetadataAlloc();
     for (long i = 0; i < psArrayLength(objects); i++) {
-        psMetadata *md = pzPendingExpMetadataFromObject(objects->data[i]);
+        psMetadata *md = pzDownloadExpMetadataFromObject(objects->data[i]);
         if (!psMetadataAddMetadata(
             output,
             PS_LIST_TAIL,
-            PZPENDINGEXP_TABLE_NAME,
+            PZDOWNLOADEXP_TABLE_NAME,
             PS_META_DUPLICATE_OK,
             NULL,
@@ -1758,9 +1781,9 @@
     return true;
 }
-bool pzPendingExpPrintObject(FILE *stream, pzPendingExpRow *object, bool mdcf)
+bool pzDownloadExpPrintObject(FILE *stream, pzDownloadExpRow *object, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(object, false);
 
-    psMetadata *md = pzPendingExpMetadataFromObject(object);
+    psMetadata *md = pzDownloadExpMetadataFromObject(object);
 
     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
@@ -1773,12 +1796,12 @@
     return true;
 }
-static void pzPendingImfileRowFree(pzPendingImfileRow *object);
-
-pzPendingImfileRow *pzPendingImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id)
-{
-    pzPendingImfileRow *_object;
-
-    _object = psAlloc(sizeof(pzPendingImfileRow));
-    psMemSetDeallocator(_object, (psFreeFunc)pzPendingImfileRowFree);
+static void pzDownloadImfileRowFree(pzDownloadImfileRow *object);
+
+pzDownloadImfileRow *pzDownloadImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, const char *uri, psS16 fault)
+{
+    pzDownloadImfileRow *_object;
+
+    _object = psAlloc(sizeof(pzDownloadImfileRow));
+    psMemSetDeallocator(_object, (psFreeFunc)pzDownloadImfileRowFree);
 
     _object->exp_name = psStringCopy(exp_name);
@@ -1787,9 +1810,11 @@
     _object->class = psStringCopy(class);
     _object->class_id = psStringCopy(class_id);
+    _object->uri = psStringCopy(uri);
+    _object->fault = fault;
 
     return _object;
 }
 
-static void pzPendingImfileRowFree(pzPendingImfileRow *object)
+static void pzDownloadImfileRowFree(pzDownloadImfileRow *object)
 {
     psFree(object->exp_name);
@@ -1798,15 +1823,16 @@
     psFree(object->class);
     psFree(object->class_id);
-}
-
-bool pzPendingImfileCreateTable(psDB *dbh)
+    psFree(object->uri);
+}
+
+bool pzDownloadImfileCreateTable(psDB *dbh)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, "Primary Key", "64")) {
+    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")) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
         psFree(md);
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, "Primary Key", "64")) {
+    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")) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
         psFree(md);
@@ -1828,6 +1854,16 @@
         return false;
     }
-
-    bool status = psDBCreateTable(dbh, PZPENDINGIMFILE_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, "Key NOT NULL", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, PZDOWNLOADIMFILE_TABLE_NAME, md);
 
     psFree(md);
@@ -1836,10 +1872,10 @@
 }
 
-bool pzPendingImfileDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, PZPENDINGIMFILE_TABLE_NAME);
-}
-
-bool pzPendingImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id)
+bool pzDownloadImfileDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, PZDOWNLOADIMFILE_TABLE_NAME);
+}
+
+bool 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)
 {
     psMetadata *md = psMetadataAlloc();
@@ -1869,6 +1905,16 @@
         return false;
     }
-
-    bool status = psDBInsertOneRow(dbh, PZPENDINGIMFILE_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, fault)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, PZDOWNLOADIMFILE_TABLE_NAME, md);
     psFree(md);
 
@@ -1876,11 +1922,11 @@
 }
 
-long long pzPendingImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+long long pzDownloadImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     long long       deleted = 0;
 
-    long long count = psDBDeleteRows(dbh, PZPENDINGIMFILE_TABLE_NAME, where, limit);
+    long long count = psDBDeleteRows(dbh, PZDOWNLOADIMFILE_TABLE_NAME, where, limit);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingImfile");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDownloadImfile");
         return count;
 
@@ -1890,13 +1936,13 @@
     return deleted;
 }
-bool pzPendingImfileInsertObject(psDB *dbh, pzPendingImfileRow *object)
-{
-    return pzPendingImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id);
-}
-
-bool pzPendingImfileInsertObjects(psDB *dbh, psArray *objects)
+bool pzDownloadImfileInsertObject(psDB *dbh, pzDownloadImfileRow *object)
+{
+    return pzDownloadImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id, object->uri, object->fault);
+}
+
+bool pzDownloadImfileInsertObjects(psDB *dbh, psArray *objects)
 {
     for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!pzPendingImfileInsertObject(dbh, objects->data[i])) {
+        if (!pzDownloadImfileInsertObject(dbh, objects->data[i])) {
             return false;
         }
@@ -1906,11 +1952,11 @@
 }
 
-bool pzPendingImfileInsertFits(psDB *dbh, const psFits *fits)
+bool pzDownloadImfileInsertFits(psDB *dbh, const psFits *fits)
 {
     psArray         *rowSet;
 
-    // move to (the first?) extension named  PZPENDINGIMFILE_TABLE_NAME
-    if (!psFitsMoveExtName(fits, PZPENDINGIMFILE_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PZPENDINGIMFILE_TABLE_NAME);
+    // move to (the first?) extension named  PZDOWNLOADIMFILE_TABLE_NAME
+    if (!psFitsMoveExtName(fits, PZDOWNLOADIMFILE_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PZDOWNLOADIMFILE_TABLE_NAME);
         return false;
     }
@@ -1930,5 +1976,5 @@
     }
 
-    if (!psDBInsertRows(dbh, PZPENDINGIMFILE_TABLE_NAME, rowSet)) {
+    if (!psDBInsertRows(dbh, PZDOWNLOADIMFILE_TABLE_NAME, rowSet)) {
         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
         psFree(rowSet);
@@ -1941,9 +1987,9 @@
 }
 
-bool pzPendingImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+bool pzDownloadImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
 
-    rowSet = psDBSelectRows(dbh, PZPENDINGIMFILE_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, PZDOWNLOADIMFILE_TABLE_NAME, where, limit);
     if (!rowSet) {
         return false;
@@ -1951,5 +1997,5 @@
 
     // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, PZPENDINGIMFILE_TABLE_NAME)) {
+    if (!psFitsWriteTable(fits, NULL, rowSet, PZDOWNLOADIMFILE_TABLE_NAME)) {
         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
         psFree(rowSet);
@@ -1962,5 +2008,5 @@
 }
 
-psMetadata *pzPendingImfileMetadataFromObject(const pzPendingImfileRow *object)
+psMetadata *pzDownloadImfileMetadataFromObject(const pzDownloadImfileRow *object)
 {
     psMetadata *md = psMetadataAlloc();
@@ -1990,4 +2036,14 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fault", PS_DATA_S16, NULL, object->fault)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
+        psFree(md);
+        return false;
+    }
 
 
@@ -1995,5 +2051,5 @@
 }
 
-pzPendingImfileRow *pzPendingImfileObjectFromMetadata(psMetadata *md)
+pzDownloadImfileRow *pzDownloadImfileObjectFromMetadata(psMetadata *md)
 {
 
@@ -2024,8 +2080,18 @@
         return false;
     }
-
-    return pzPendingImfileRowAlloc(exp_name, camera, telescope, class, class_id);
-}
-psArray *pzPendingImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+    char* uri = psMetadataLookupPtr(&status, md, "uri");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
+        return false;
+    }
+    psS16 fault = psMetadataLookupS16(&status, md, "fault");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fault");
+        return false;
+    }
+
+    return pzDownloadImfileRowAlloc(exp_name, camera, telescope, class, class_id, uri, fault);
+}
+psArray *pzDownloadImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
@@ -2033,5 +2099,5 @@
     psU64           i;
 
-    rowSet = psDBSelectRows(dbh, PZPENDINGIMFILE_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, PZDOWNLOADIMFILE_TABLE_NAME, where, limit);
     if (!rowSet) {
         return NULL;
@@ -2043,5 +2109,5 @@
 
     for (i = 0; i < rowSet->n; i++) {
-        pzPendingImfileRow *object = pzPendingImfileObjectFromMetadata(rowSet->data[i]);
+        pzDownloadImfileRow *object = pzDownloadImfileObjectFromMetadata(rowSet->data[i]);
         if (!object) {
             psFree(object);
@@ -2058,11 +2124,11 @@
     return returnSet;
 }
-bool pzPendingImfileDeleteObject(psDB *dbh, const pzPendingImfileRow *object)
-{
-    psMetadata *where = pzPendingImfileMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, PZPENDINGIMFILE_TABLE_NAME, where, 0);
+bool pzDownloadImfileDeleteObject(psDB *dbh, const pzDownloadImfileRow *object)
+{
+    psMetadata *where = pzDownloadImfileMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, PZDOWNLOADIMFILE_TABLE_NAME, where, 0);
     psFree(where);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingImfile");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDownloadImfile");
         return false;
     }
@@ -2070,21 +2136,21 @@
         // XXX should this be a psAbort() instead?  It is possible that
         // having an object match multiple rows was by design.
-        psError(PS_ERR_UNKNOWN, true, "pzPendingImfileRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long pzPendingImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+        psError(PS_ERR_UNKNOWN, true, "pzDownloadImfileRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long pzDownloadImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
 {
     long long       deleted = 0;
 
     for (long long i = 0; i < objects->n; i++) {
-        pzPendingImfileRow *object = objects->data[i];
-        psMetadata *where = pzPendingImfileMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, PZPENDINGIMFILE_TABLE_NAME, where, limit);
+        pzDownloadImfileRow *object = objects->data[i];
+        psMetadata *where = pzDownloadImfileMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, PZDOWNLOADIMFILE_TABLE_NAME, where, limit);
         psFree(where);
         if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingImfile");
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDownloadImfile");
             return count;
         }
@@ -2095,5 +2161,5 @@
     return deleted;
 }
-bool pzPendingImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
+bool pzDownloadImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(objects, false);
@@ -2101,9 +2167,9 @@
     psMetadata *output = psMetadataAlloc();
     for (long i = 0; i < psArrayLength(objects); i++) {
-        psMetadata *md = pzPendingImfileMetadataFromObject(objects->data[i]);
+        psMetadata *md = pzDownloadImfileMetadataFromObject(objects->data[i]);
         if (!psMetadataAddMetadata(
             output,
             PS_LIST_TAIL,
-            PZPENDINGIMFILE_TABLE_NAME,
+            PZDOWNLOADIMFILE_TABLE_NAME,
             PS_META_DUPLICATE_OK,
             NULL,
@@ -2126,9 +2192,9 @@
     return true;
 }
-bool pzPendingImfilePrintObject(FILE *stream, pzPendingImfileRow *object, bool mdcf)
+bool pzDownloadImfilePrintObject(FILE *stream, pzDownloadImfileRow *object, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(object, false);
 
-    psMetadata *md = pzPendingImfileMetadataFromObject(object);
+    psMetadata *md = pzDownloadImfileMetadataFromObject(object);
 
     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
@@ -2141,721 +2207,7 @@
     return true;
 }
-static void pzDoneExpRowFree(pzDoneExpRow *object);
-
-pzDoneExpRow *pzDoneExpRowAlloc(const char *exp_name, const char *camera, const char *telescope)
-{
-    pzDoneExpRow    *_object;
-
-    _object = psAlloc(sizeof(pzDoneExpRow));
-    psMemSetDeallocator(_object, (psFreeFunc)pzDoneExpRowFree);
-
-    _object->exp_name = psStringCopy(exp_name);
-    _object->camera = psStringCopy(camera);
-    _object->telescope = psStringCopy(telescope);
-
-    return _object;
-}
-
-static void pzDoneExpRowFree(pzDoneExpRow *object)
-{
-    psFree(object->exp_name);
-    psFree(object->camera);
-    psFree(object->telescope);
-}
-
-bool pzDoneExpCreateTable(psDB *dbh)
-{
-    psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBCreateTable(dbh, PZDONEEXP_TABLE_NAME, md);
-
-    psFree(md);
-
-    return status;
-}
-
-bool pzDoneExpDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, PZDONEEXP_TABLE_NAME);
-}
-
-bool pzDoneExpInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope)
-{
-    psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, NULL, exp_name)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, NULL, camera)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, NULL, telescope)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBInsertOneRow(dbh, PZDONEEXP_TABLE_NAME, md);
-    psFree(md);
-
-    return status;
-}
-
-long long pzDoneExpDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
-{
-    long long       deleted = 0;
-
-    long long count = psDBDeleteRows(dbh, PZDONEEXP_TABLE_NAME, where, limit);
-    if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneExp");
-        return count;
-
-        deleted += count;
-    }
-
-    return deleted;
-}
-bool pzDoneExpInsertObject(psDB *dbh, pzDoneExpRow *object)
-{
-    return pzDoneExpInsert(dbh, object->exp_name, object->camera, object->telescope);
-}
-
-bool pzDoneExpInsertObjects(psDB *dbh, psArray *objects)
-{
-    for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!pzDoneExpInsertObject(dbh, objects->data[i])) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool pzDoneExpInsertFits(psDB *dbh, const psFits *fits)
-{
-    psArray         *rowSet;
-
-    // move to (the first?) extension named  PZDONEEXP_TABLE_NAME
-    if (!psFitsMoveExtName(fits, PZDONEEXP_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PZDONEEXP_TABLE_NAME);
-        return false;
-    }
-
-    // check HDU type
-    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
-        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
-        return false;
-    }
-
-    // read fits table
-    rowSet = psFitsReadTable(fits);
-    if (!rowSet) {
-        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
-        psFree(rowSet);
-        return false;
-    }
-
-    if (!psDBInsertRows(dbh, PZDONEEXP_TABLE_NAME, rowSet)) {
-        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
-        psFree(rowSet);
-        return false;
-    }
-
-    psFree(rowSet);
-
-    return true;
-}
-
-bool pzDoneExpSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
-{
-    psArray         *rowSet;
-
-    rowSet = psDBSelectRows(dbh, PZDONEEXP_TABLE_NAME, where, limit);
-    if (!rowSet) {
-        return false;
-    }
-
-    // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, PZDONEEXP_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
-        psFree(rowSet);
-        return false;
-    }
-
-    psFree(rowSet);
-
-    return true;
-}
-
-psMetadata *pzDoneExpMetadataFromObject(const pzDoneExpRow *object)
-{
-    psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, NULL, object->exp_name)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, NULL, object->camera)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, NULL, object->telescope)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
-        psFree(md);
-        return false;
-    }
-
-
-    return md;
-}
-
-pzDoneExpRow *pzDoneExpObjectFromMetadata(psMetadata *md)
-{
-
-bool status = false;
-    char* exp_name = psMetadataLookupPtr(&status, md, "exp_name");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_name");
-        return false;
-    }
-    char* camera = psMetadataLookupPtr(&status, md, "camera");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item camera");
-        return false;
-    }
-    char* telescope = psMetadataLookupPtr(&status, md, "telescope");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item telescope");
-        return false;
-    }
-
-    return pzDoneExpRowAlloc(exp_name, camera, telescope);
-}
-psArray *pzDoneExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
-{
-    psArray         *rowSet;
-    psArray         *returnSet;
-    psU64           i;
-
-    rowSet = psDBSelectRows(dbh, PZDONEEXP_TABLE_NAME, where, limit);
-    if (!rowSet) {
-        return NULL;
-    }
-
-    // convert psMetadata rows to row objects
-
-    returnSet = psArrayAllocEmpty(rowSet->n);
-
-    for (i = 0; i < rowSet->n; i++) {
-        pzDoneExpRow *object = pzDoneExpObjectFromMetadata(rowSet->data[i]);
-        if (!object) {
-            psFree(object);
-            psFree(returnSet);
-            psError(PS_ERR_UNKNOWN, false, "database error");
-            return NULL;
-        }
-        psArrayAdd(returnSet, 0, object);
-        psFree(object);
-    }
-
-    psFree(rowSet);
-
-    return returnSet;
-}
-bool pzDoneExpDeleteObject(psDB *dbh, const pzDoneExpRow *object)
-{
-    psMetadata *where = pzDoneExpMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, PZDONEEXP_TABLE_NAME, where, 0);
-    psFree(where);
-    if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneExp");
-        return false;
-    }
-    if (count > 1) {
-        // XXX should this be a psAbort() instead?  It is possible that
-        // having an object match multiple rows was by design.
-        psError(PS_ERR_UNKNOWN, true, "pzDoneExpRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long pzDoneExpDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
-{
-    long long       deleted = 0;
-
-    for (long long i = 0; i < objects->n; i++) {
-        pzDoneExpRow *object = objects->data[i];
-        psMetadata *where = pzDoneExpMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, PZDONEEXP_TABLE_NAME, where, limit);
-        psFree(where);
-        if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneExp");
-            return count;
-        }
-
-        deleted += count;
-    }
-
-    return deleted;
-}
-bool pzDoneExpPrintObjects(FILE *stream, psArray *objects, bool mdcf)
-{
-    PS_ASSERT_PTR_NON_NULL(objects, false);
-
-    psMetadata *output = psMetadataAlloc();
-    for (long i = 0; i < psArrayLength(objects); i++) {
-        psMetadata *md = pzDoneExpMetadataFromObject(objects->data[i]);
-        if (!psMetadataAddMetadata(
-            output,
-            PS_LIST_TAIL,
-            PZDONEEXP_TABLE_NAME,
-            PS_META_DUPLICATE_OK,
-            NULL,
-            md
-        )) {
-            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
-            psFree(md);
-            psFree(output);
-            return false;
-        }
-        psFree(md);
-    }
-
-    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
-        psFree(output);
-    }
-    psFree(output);
-
-    return true;
-}
-bool pzDoneExpPrintObject(FILE *stream, pzDoneExpRow *object, bool mdcf)
-{
-    PS_ASSERT_PTR_NON_NULL(object, false);
-
-    psMetadata *md = pzDoneExpMetadataFromObject(object);
-
-    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
-        psFree(md);
-    }
-
-    psFree(md);
-
-    return true;
-}
-static void pzDoneImfileRowFree(pzDoneImfileRow *object);
-
-pzDoneImfileRow *pzDoneImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, const char *uri)
-{
-    pzDoneImfileRow *_object;
-
-    _object = psAlloc(sizeof(pzDoneImfileRow));
-    psMemSetDeallocator(_object, (psFreeFunc)pzDoneImfileRowFree);
-
-    _object->exp_name = psStringCopy(exp_name);
-    _object->camera = psStringCopy(camera);
-    _object->telescope = psStringCopy(telescope);
-    _object->class = psStringCopy(class);
-    _object->class_id = psStringCopy(class_id);
-    _object->uri = psStringCopy(uri);
-
-    return _object;
-}
-
-static void pzDoneImfileRowFree(pzDoneImfileRow *object)
-{
-    psFree(object->exp_name);
-    psFree(object->camera);
-    psFree(object->telescope);
-    psFree(object->class);
-    psFree(object->class_id);
-    psFree(object->uri);
-}
-
-bool pzDoneImfileCreateTable(psDB *dbh)
-{
-    psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBCreateTable(dbh, PZDONEIMFILE_TABLE_NAME, md);
-
-    psFree(md);
-
-    return status;
-}
-
-bool pzDoneImfileDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, PZDONEIMFILE_TABLE_NAME);
-}
-
-bool pzDoneImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, const char *uri)
-{
-    psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, NULL, exp_name)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, NULL, camera)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, NULL, telescope)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class", PS_DATA_STRING, NULL, class)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBInsertOneRow(dbh, PZDONEIMFILE_TABLE_NAME, md);
-    psFree(md);
-
-    return status;
-}
-
-long long pzDoneImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
-{
-    long long       deleted = 0;
-
-    long long count = psDBDeleteRows(dbh, PZDONEIMFILE_TABLE_NAME, where, limit);
-    if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneImfile");
-        return count;
-
-        deleted += count;
-    }
-
-    return deleted;
-}
-bool pzDoneImfileInsertObject(psDB *dbh, pzDoneImfileRow *object)
-{
-    return pzDoneImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id, object->uri);
-}
-
-bool pzDoneImfileInsertObjects(psDB *dbh, psArray *objects)
-{
-    for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!pzDoneImfileInsertObject(dbh, objects->data[i])) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool pzDoneImfileInsertFits(psDB *dbh, const psFits *fits)
-{
-    psArray         *rowSet;
-
-    // move to (the first?) extension named  PZDONEIMFILE_TABLE_NAME
-    if (!psFitsMoveExtName(fits, PZDONEIMFILE_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PZDONEIMFILE_TABLE_NAME);
-        return false;
-    }
-
-    // check HDU type
-    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
-        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
-        return false;
-    }
-
-    // read fits table
-    rowSet = psFitsReadTable(fits);
-    if (!rowSet) {
-        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
-        psFree(rowSet);
-        return false;
-    }
-
-    if (!psDBInsertRows(dbh, PZDONEIMFILE_TABLE_NAME, rowSet)) {
-        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
-        psFree(rowSet);
-        return false;
-    }
-
-    psFree(rowSet);
-
-    return true;
-}
-
-bool pzDoneImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
-{
-    psArray         *rowSet;
-
-    rowSet = psDBSelectRows(dbh, PZDONEIMFILE_TABLE_NAME, where, limit);
-    if (!rowSet) {
-        return false;
-    }
-
-    // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, PZDONEIMFILE_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
-        psFree(rowSet);
-        return false;
-    }
-
-    psFree(rowSet);
-
-    return true;
-}
-
-psMetadata *pzDoneImfileMetadataFromObject(const pzDoneImfileRow *object)
-{
-    psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, NULL, object->exp_name)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, NULL, object->camera)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "telescope", PS_DATA_STRING, NULL, object->telescope)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class", PS_DATA_STRING, NULL, object->class)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
-        psFree(md);
-        return false;
-    }
-
-
-    return md;
-}
-
-pzDoneImfileRow *pzDoneImfileObjectFromMetadata(psMetadata *md)
-{
-
-bool status = false;
-    char* exp_name = psMetadataLookupPtr(&status, md, "exp_name");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_name");
-        return false;
-    }
-    char* camera = psMetadataLookupPtr(&status, md, "camera");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item camera");
-        return false;
-    }
-    char* telescope = psMetadataLookupPtr(&status, md, "telescope");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item telescope");
-        return false;
-    }
-    char* class = psMetadataLookupPtr(&status, md, "class");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class");
-        return false;
-    }
-    char* class_id = psMetadataLookupPtr(&status, md, "class_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id");
-        return false;
-    }
-    char* uri = psMetadataLookupPtr(&status, md, "uri");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
-        return false;
-    }
-
-    return pzDoneImfileRowAlloc(exp_name, camera, telescope, class, class_id, uri);
-}
-psArray *pzDoneImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
-{
-    psArray         *rowSet;
-    psArray         *returnSet;
-    psU64           i;
-
-    rowSet = psDBSelectRows(dbh, PZDONEIMFILE_TABLE_NAME, where, limit);
-    if (!rowSet) {
-        return NULL;
-    }
-
-    // convert psMetadata rows to row objects
-
-    returnSet = psArrayAllocEmpty(rowSet->n);
-
-    for (i = 0; i < rowSet->n; i++) {
-        pzDoneImfileRow *object = pzDoneImfileObjectFromMetadata(rowSet->data[i]);
-        if (!object) {
-            psFree(object);
-            psFree(returnSet);
-            psError(PS_ERR_UNKNOWN, false, "database error");
-            return NULL;
-        }
-        psArrayAdd(returnSet, 0, object);
-        psFree(object);
-    }
-
-    psFree(rowSet);
-
-    return returnSet;
-}
-bool pzDoneImfileDeleteObject(psDB *dbh, const pzDoneImfileRow *object)
-{
-    psMetadata *where = pzDoneImfileMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, PZDONEIMFILE_TABLE_NAME, where, 0);
-    psFree(where);
-    if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneImfile");
-        return false;
-    }
-    if (count > 1) {
-        // XXX should this be a psAbort() instead?  It is possible that
-        // having an object match multiple rows was by design.
-        psError(PS_ERR_UNKNOWN, true, "pzDoneImfileRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long pzDoneImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
-{
-    long long       deleted = 0;
-
-    for (long long i = 0; i < objects->n; i++) {
-        pzDoneImfileRow *object = objects->data[i];
-        psMetadata *where = pzDoneImfileMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, PZDONEIMFILE_TABLE_NAME, where, limit);
-        psFree(where);
-        if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneImfile");
-            return count;
-        }
-
-        deleted += count;
-    }
-
-    return deleted;
-}
-bool pzDoneImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
-{
-    PS_ASSERT_PTR_NON_NULL(objects, false);
-
-    psMetadata *output = psMetadataAlloc();
-    for (long i = 0; i < psArrayLength(objects); i++) {
-        psMetadata *md = pzDoneImfileMetadataFromObject(objects->data[i]);
-        if (!psMetadataAddMetadata(
-            output,
-            PS_LIST_TAIL,
-            PZDONEIMFILE_TABLE_NAME,
-            PS_META_DUPLICATE_OK,
-            NULL,
-            md
-        )) {
-            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
-            psFree(md);
-            psFree(output);
-            return false;
-        }
-        psFree(md);
-    }
-
-    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
-        psFree(output);
-    }
-    psFree(output);
-
-    return true;
-}
-bool pzDoneImfilePrintObject(FILE *stream, pzDoneImfileRow *object, bool mdcf)
-{
-    PS_ASSERT_PTR_NON_NULL(object, false);
-
-    psMetadata *md = pzDoneImfileMetadataFromObject(object);
-
-    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
-        psFree(md);
-    }
-
-    psFree(md);
-
-    return true;
-}
 static void newExpRowFree(newExpRow *object);
 
-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)
+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, const char *label)
 {
     newExpRow       *_object;
@@ -2875,4 +2227,5 @@
     _object->tess_id = psStringCopy(tess_id);
     _object->end_stage = psStringCopy(end_stage);
+    _object->label = psStringCopy(label);
 
     return _object;
@@ -2891,4 +2244,5 @@
     psFree(object->tess_id);
     psFree(object->end_stage);
+    psFree(object->label);
 }
 
@@ -2951,4 +2305,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, "Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item label");
+        psFree(md);
+        return false;
+    }
 
     bool status = psDBCreateTable(dbh, NEWEXP_TABLE_NAME, md);
@@ -2964,5 +2323,5 @@
 }
 
-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)
+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, const char *label)
 {
     psMetadata *md = psMetadataAlloc();
@@ -3019,4 +2378,9 @@
     if (!psMetadataAdd(md, PS_LIST_TAIL, "end_stage", PS_DATA_STRING, NULL, end_stage)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item end_stage");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, NULL, label)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item label");
         psFree(md);
         return false;
@@ -3045,5 +2409,5 @@
 bool newExpInsertObject(psDB *dbh, newExpRow *object)
 {
-    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);
+    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);
 }
 
@@ -3173,4 +2537,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, NULL, object->label)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item label");
+        psFree(md);
+        return false;
+    }
 
 
@@ -3237,6 +2606,11 @@
         return false;
     }
-
-    return newExpRowAlloc(exp_id, tmp_exp_name, tmp_camera, tmp_telescope, state, workdir, workdir_state, reduction, dvodb, tess_id, end_stage);
+    char* label = psMetadataLookupPtr(&status, md, "label");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item label");
+        return false;
+    }
+
+    return newExpRowAlloc(exp_id, tmp_exp_name, tmp_camera, tmp_telescope, state, workdir, workdir_state, reduction, dvodb, tess_id, end_stage, label);
 }
 psArray *newExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -7310,5 +6684,5 @@
 static void chipProcessedImfileRowFree(chipProcessedImfileRow *object);
 
-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)
+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 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)
 {
     chipProcessedImfileRow *_object;
@@ -7333,6 +6707,12 @@
     _object->ap_resid = ap_resid;
     _object->ap_resid_stdev = ap_resid_stdev;
-    _object->fwhm = fwhm;
-    _object->fwhm_range = fwhm_range;
+    _object->zp_mean = zp_mean;
+    _object->zp_stdev = zp_stdev;
+    _object->fwhm_major = fwhm_major;
+    _object->fwhm_minor = fwhm_minor;
+    _object->dtime_detrend = dtime_detrend;
+    _object->dtime_photom = dtime_photom;
+    _object->dtime_astrom = dtime_astrom;
+    _object->hostname = psStringCopy(hostname);
     _object->n_stars = n_stars;
     _object->n_extended = n_extended;
@@ -7349,4 +6729,5 @@
     psFree(object->class_id);
     psFree(object->uri);
+    psFree(object->hostname);
     psFree(object->path_base);
 }
@@ -7435,11 +6816,41 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, "# replace this with fwhm_major", 0.0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, "# replace this with fwhm_minor", 0.0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_range");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_mean", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_mean");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_stdev", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_stdev");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_major", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_major");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_minor", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_minor");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_detrend", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_detrend");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_photom", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_photom");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_astrom", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_astrom");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
         psFree(md);
         return false;
@@ -7488,5 +6899,5 @@
 }
 
-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)
+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 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)
 {
     psMetadata *md = psMetadataAlloc();
@@ -7571,11 +6982,41 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, NULL, fwhm)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, NULL, fwhm_range)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_range");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_mean", PS_DATA_F32, NULL, zp_mean)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_mean");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_stdev", PS_DATA_F32, NULL, zp_stdev)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_stdev");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_major", PS_DATA_F32, NULL, fwhm_major)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_major");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_minor", PS_DATA_F32, NULL, fwhm_minor)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_minor");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_detrend", PS_DATA_F32, NULL, dtime_detrend)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_detrend");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_photom", PS_DATA_F32, NULL, dtime_photom)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_photom");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_astrom", PS_DATA_F32, NULL, dtime_astrom)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_astrom");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, hostname)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
         psFree(md);
         return false;
@@ -7634,5 +7075,5 @@
 bool chipProcessedImfileInsertObject(psDB *dbh, chipProcessedImfileRow *object)
 {
-    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);
+    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);
 }
 
@@ -7787,11 +7228,41 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, NULL, object->fwhm)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, NULL, object->fwhm_range)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_range");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_mean", PS_DATA_F32, NULL, object->zp_mean)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_mean");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_stdev", PS_DATA_F32, NULL, object->zp_stdev)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item zp_stdev");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_major", PS_DATA_F32, NULL, object->fwhm_major)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_major");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_minor", PS_DATA_F32, NULL, object->fwhm_minor)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_minor");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_detrend", PS_DATA_F32, NULL, object->dtime_detrend)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_detrend");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_photom", PS_DATA_F32, NULL, object->dtime_photom)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_photom");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_astrom", PS_DATA_F32, NULL, object->dtime_astrom)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_astrom");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, object->hostname)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
         psFree(md);
         return false;
@@ -7916,12 +7387,42 @@
         return false;
     }
-    psF32 fwhm = psMetadataLookupF32(&status, md, "fwhm");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm");
-        return false;
-    }
-    psF32 fwhm_range = psMetadataLookupF32(&status, md, "fwhm_range");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm_range");
+    psF32 zp_mean = psMetadataLookupF32(&status, md, "zp_mean");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item zp_mean");
+        return false;
+    }
+    psF32 zp_stdev = psMetadataLookupF32(&status, md, "zp_stdev");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item zp_stdev");
+        return false;
+    }
+    psF32 fwhm_major = psMetadataLookupF32(&status, md, "fwhm_major");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm_major");
+        return false;
+    }
+    psF32 fwhm_minor = psMetadataLookupF32(&status, md, "fwhm_minor");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm_minor");
+        return false;
+    }
+    psF32 dtime_detrend = psMetadataLookupF32(&status, md, "dtime_detrend");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_detrend");
+        return false;
+    }
+    psF32 dtime_photom = psMetadataLookupF32(&status, md, "dtime_photom");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_photom");
+        return false;
+    }
+    psF32 dtime_astrom = psMetadataLookupF32(&status, md, "dtime_astrom");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_astrom");
+        return false;
+    }
+    char* hostname = psMetadataLookupPtr(&status, md, "hostname");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item hostname");
         return false;
     }
@@ -7957,5 +7458,5 @@
     }
 
-    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);
+    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);
 }
 psArray *chipProcessedImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -8853,5 +8354,5 @@
 static void camProcessedExpRowFree(camProcessedExpRow *object);
 
-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)
+camProcessedExpRow *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)
 {
     camProcessedExpRow *_object;
@@ -8866,10 +8367,21 @@
     _object->bg_stdev = bg_stdev;
     _object->bg_mean_stdev = bg_mean_stdev;
+    _object->bias = bias;
+    _object->bias_stdev = bias_stdev;
+    _object->fringe_0 = fringe_0;
+    _object->fringe_1 = fringe_1;
+    _object->fringe_2 = fringe_2;
     _object->sigma_ra = sigma_ra;
     _object->sigma_dec = sigma_dec;
+    _object->ap_resid = ap_resid;
+    _object->ap_resid_stdev = ap_resid_stdev;
     _object->zp_mean = zp_mean;
     _object->zp_stdev = zp_stdev;
-    _object->fwhm = fwhm;
-    _object->fwhm_range = fwhm_range;
+    _object->fwhm_major = fwhm_major;
+    _object->fwhm_minor = fwhm_minor;
+    _object->dtime_detrend = dtime_detrend;
+    _object->dtime_photom = dtime_photom;
+    _object->dtime_astrom = dtime_astrom;
+    _object->hostname = psStringCopy(hostname);
     _object->n_stars = n_stars;
     _object->n_extended = n_extended;
@@ -8885,4 +8397,5 @@
 {
     psFree(object->uri);
+    psFree(object->hostname);
     psFree(object->path_base);
 }
@@ -8921,4 +8434,29 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bias", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bias");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bias_stdev", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bias_stdev");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_0", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_0");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_1", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_1");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_2", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_2");
+        psFree(md);
+        return false;
+    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "sigma_ra", PS_DATA_F32, NULL, 0.0)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item sigma_ra");
@@ -8931,4 +8469,14 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ap_resid", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ap_resid");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ap_resid_stdev", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ap_resid_stdev");
+        psFree(md);
+        return false;
+    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_mean", PS_DATA_F32, NULL, 0.0)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item zp_mean");
@@ -8941,11 +8489,31 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, NULL, 0.0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, NULL, 0.0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_range");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_major", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_major");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_minor", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_minor");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_detrend", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_detrend");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_photom", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_photom");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_astrom", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_astrom");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
         psFree(md);
         return false;
@@ -8994,5 +8562,5 @@
 }
 
-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)
+bool 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)
 {
     psMetadata *md = psMetadataAlloc();
@@ -9027,4 +8595,29 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bias", PS_DATA_F32, NULL, bias)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bias");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bias_stdev", PS_DATA_F32, NULL, bias_stdev)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bias_stdev");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_0", PS_DATA_F32, NULL, fringe_0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_0");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_1", PS_DATA_F32, NULL, fringe_1)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_1");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_2", PS_DATA_F32, NULL, fringe_2)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_2");
+        psFree(md);
+        return false;
+    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "sigma_ra", PS_DATA_F32, NULL, sigma_ra)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item sigma_ra");
@@ -9037,4 +8630,14 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ap_resid", PS_DATA_F32, NULL, ap_resid)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ap_resid");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ap_resid_stdev", PS_DATA_F32, NULL, ap_resid_stdev)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ap_resid_stdev");
+        psFree(md);
+        return false;
+    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_mean", PS_DATA_F32, NULL, zp_mean)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item zp_mean");
@@ -9047,11 +8650,31 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, NULL, fwhm)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, NULL, fwhm_range)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_range");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_major", PS_DATA_F32, NULL, fwhm_major)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_major");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_minor", PS_DATA_F32, NULL, fwhm_minor)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_minor");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_detrend", PS_DATA_F32, NULL, dtime_detrend)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_detrend");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_photom", PS_DATA_F32, NULL, dtime_photom)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_photom");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_astrom", PS_DATA_F32, NULL, dtime_astrom)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_astrom");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, hostname)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
         psFree(md);
         return false;
@@ -9110,5 +8733,5 @@
 bool camProcessedExpInsertObject(psDB *dbh, camProcessedExpRow *object)
 {
-    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);
+    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);
 }
 
@@ -9213,4 +8836,29 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bias", PS_DATA_F32, NULL, object->bias)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bias");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bias_stdev", PS_DATA_F32, NULL, object->bias_stdev)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bias_stdev");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_0", PS_DATA_F32, NULL, object->fringe_0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_0");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_1", PS_DATA_F32, NULL, object->fringe_1)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_1");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fringe_2", PS_DATA_F32, NULL, object->fringe_2)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fringe_2");
+        psFree(md);
+        return false;
+    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "sigma_ra", PS_DATA_F32, NULL, object->sigma_ra)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item sigma_ra");
@@ -9223,4 +8871,14 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ap_resid", PS_DATA_F32, NULL, object->ap_resid)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ap_resid");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ap_resid_stdev", PS_DATA_F32, NULL, object->ap_resid_stdev)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ap_resid_stdev");
+        psFree(md);
+        return false;
+    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "zp_mean", PS_DATA_F32, NULL, object->zp_mean)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item zp_mean");
@@ -9233,11 +8891,31 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm", PS_DATA_F32, NULL, object->fwhm)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_range", PS_DATA_F32, NULL, object->fwhm_range)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_range");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_major", PS_DATA_F32, NULL, object->fwhm_major)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_major");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "fwhm_minor", PS_DATA_F32, NULL, object->fwhm_minor)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item fwhm_minor");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_detrend", PS_DATA_F32, NULL, object->dtime_detrend)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_detrend");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_photom", PS_DATA_F32, NULL, object->dtime_photom)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_photom");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_astrom", PS_DATA_F32, NULL, object->dtime_astrom)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_astrom");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, object->hostname)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
         psFree(md);
         return false;
@@ -9312,4 +8990,29 @@
         return false;
     }
+    psF32 bias = psMetadataLookupF32(&status, md, "bias");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bias");
+        return false;
+    }
+    psF32 bias_stdev = psMetadataLookupF32(&status, md, "bias_stdev");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bias_stdev");
+        return false;
+    }
+    psF32 fringe_0 = psMetadataLookupF32(&status, md, "fringe_0");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fringe_0");
+        return false;
+    }
+    psF32 fringe_1 = psMetadataLookupF32(&status, md, "fringe_1");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fringe_1");
+        return false;
+    }
+    psF32 fringe_2 = psMetadataLookupF32(&status, md, "fringe_2");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fringe_2");
+        return false;
+    }
     psF32 sigma_ra = psMetadataLookupF32(&status, md, "sigma_ra");
     if (!status) {
@@ -9322,4 +9025,14 @@
         return false;
     }
+    psF32 ap_resid = psMetadataLookupF32(&status, md, "ap_resid");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ap_resid");
+        return false;
+    }
+    psF32 ap_resid_stdev = psMetadataLookupF32(&status, md, "ap_resid_stdev");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ap_resid_stdev");
+        return false;
+    }
     psF32 zp_mean = psMetadataLookupF32(&status, md, "zp_mean");
     if (!status) {
@@ -9332,12 +9045,32 @@
         return false;
     }
-    psF32 fwhm = psMetadataLookupF32(&status, md, "fwhm");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm");
-        return false;
-    }
-    psF32 fwhm_range = psMetadataLookupF32(&status, md, "fwhm_range");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm_range");
+    psF32 fwhm_major = psMetadataLookupF32(&status, md, "fwhm_major");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm_major");
+        return false;
+    }
+    psF32 fwhm_minor = psMetadataLookupF32(&status, md, "fwhm_minor");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item fwhm_minor");
+        return false;
+    }
+    psF32 dtime_detrend = psMetadataLookupF32(&status, md, "dtime_detrend");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_detrend");
+        return false;
+    }
+    psF32 dtime_photom = psMetadataLookupF32(&status, md, "dtime_photom");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_photom");
+        return false;
+    }
+    psF32 dtime_astrom = psMetadataLookupF32(&status, md, "dtime_astrom");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_astrom");
+        return false;
+    }
+    char* hostname = psMetadataLookupPtr(&status, md, "hostname");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item hostname");
         return false;
     }
@@ -9373,5 +9106,5 @@
     }
 
-    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);
+    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);
 }
 psArray *camProcessedExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -10934,5 +10667,5 @@
 static void warpSkyfileRowFree(warpSkyfileRow *object);
 
-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)
+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, psF32 dtime_warp, const char *hostname, psF32 good_frac, bool ignored, psS16 fault)
 {
     warpSkyfileRow  *_object;
@@ -10948,4 +10681,6 @@
     _object->bg = bg;
     _object->bg_stdev = bg_stdev;
+    _object->dtime_warp = dtime_warp;
+    _object->hostname = psStringCopy(hostname);
     _object->good_frac = good_frac;
     _object->ignored = ignored;
@@ -10961,4 +10696,5 @@
     psFree(object->uri);
     psFree(object->path_base);
+    psFree(object->hostname);
 }
 
@@ -11001,5 +10737,15 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, "Key", 0.0)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_warp", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_warp");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, "Key", 0.0)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
         psFree(md);
@@ -11029,5 +10775,5 @@
 }
 
-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)
+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, psF32 dtime_warp, const char *hostname, psF32 good_frac, bool ignored, psS16 fault)
 {
     psMetadata *md = psMetadataAlloc();
@@ -11067,5 +10813,15 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, NULL, good_frac)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_warp", PS_DATA_F32, NULL, dtime_warp)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_warp");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, hostname)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, NULL, good_frac)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
         psFree(md);
@@ -11105,5 +10861,5 @@
 bool warpSkyfileInsertObject(psDB *dbh, warpSkyfileRow *object)
 {
-    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);
+    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);
 }
 
@@ -11213,5 +10969,15 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, NULL, object->good_frac)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_warp", PS_DATA_F32, NULL, object->dtime_warp)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_warp");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, object->hostname)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, NULL, object->good_frac)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
         psFree(md);
@@ -11272,5 +11038,15 @@
         return false;
     }
-    psF64 good_frac = psMetadataLookupF64(&status, md, "good_frac");
+    psF32 dtime_warp = psMetadataLookupF32(&status, md, "dtime_warp");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_warp");
+        return false;
+    }
+    char* hostname = psMetadataLookupPtr(&status, md, "hostname");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item hostname");
+        return false;
+    }
+    psF32 good_frac = psMetadataLookupF32(&status, md, "good_frac");
     if (!status) {
         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item good_frac");
@@ -11288,5 +11064,5 @@
     }
 
-    return warpSkyfileRowAlloc(warp_id, skycell_id, tess_id, uri, path_base, bg, bg_stdev, good_frac, ignored, fault);
+    return warpSkyfileRowAlloc(warp_id, skycell_id, tess_id, uri, path_base, bg, bg_stdev, dtime_warp, hostname, good_frac, ignored, fault);
 }
 psArray *warpSkyfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -12225,5 +12001,5 @@
 static void diffSkyfileRowFree(diffSkyfileRow *object);
 
-diffSkyfileRow *diffSkyfileRowAlloc(psS64 diff_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF64 good_frac, psS16 fault)
+diffSkyfileRow *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)
 {
     diffSkyfileRow  *_object;
@@ -12237,4 +12013,6 @@
     _object->bg = bg;
     _object->bg_stdev = bg_stdev;
+    _object->dtime_diff = dtime_diff;
+    _object->hostname = psStringCopy(hostname);
     _object->good_frac = good_frac;
     _object->fault = fault;
@@ -12247,4 +12025,5 @@
     psFree(object->uri);
     psFree(object->path_base);
+    psFree(object->hostname);
 }
 
@@ -12277,5 +12056,15 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, "Key", 0.0)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_diff", PS_DATA_F32, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_diff");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, "Key", 0.0)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
         psFree(md);
@@ -12300,5 +12089,5 @@
 }
 
-bool diffSkyfileInsert(psDB * dbh, psS64 diff_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF64 good_frac, psS16 fault)
+bool 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)
 {
     psMetadata *md = psMetadataAlloc();
@@ -12328,5 +12117,15 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, NULL, good_frac)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_diff", PS_DATA_F32, NULL, dtime_diff)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_diff");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, hostname)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, NULL, good_frac)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
         psFree(md);
@@ -12361,5 +12160,5 @@
 bool diffSkyfileInsertObject(psDB *dbh, diffSkyfileRow *object)
 {
-    return diffSkyfileInsert(dbh, object->diff_id, object->uri, object->path_base, object->bg, object->bg_stdev, object->good_frac, object->fault);
+    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);
 }
 
@@ -12459,5 +12258,15 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, NULL, object->good_frac)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_diff", PS_DATA_F32, NULL, object->dtime_diff)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_diff");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, object->hostname)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, NULL, object->good_frac)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
         psFree(md);
@@ -12503,5 +12312,15 @@
         return false;
     }
-    psF64 good_frac = psMetadataLookupF64(&status, md, "good_frac");
+    psF32 dtime_diff = psMetadataLookupF32(&status, md, "dtime_diff");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_diff");
+        return false;
+    }
+    char* hostname = psMetadataLookupPtr(&status, md, "hostname");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item hostname");
+        return false;
+    }
+    psF32 good_frac = psMetadataLookupF32(&status, md, "good_frac");
     if (!status) {
         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item good_frac");
@@ -12514,5 +12333,5 @@
     }
 
-    return diffSkyfileRowAlloc(diff_id, uri, path_base, bg, bg_stdev, good_frac, fault);
+    return diffSkyfileRowAlloc(diff_id, uri, path_base, bg, bg_stdev, dtime_diff, hostname, good_frac, fault);
 }
 psArray *diffSkyfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -13343,5 +13162,5 @@
 static void stackSumSkyfileRowFree(stackSumSkyfileRow *object);
 
-stackSumSkyfileRow *stackSumSkyfileRowAlloc(psS64 stack_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF64 good_frac, psS16 fault)
+stackSumSkyfileRow *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)
 {
     stackSumSkyfileRow *_object;
@@ -13355,4 +13174,6 @@
     _object->bg = bg;
     _object->bg_stdev = bg_stdev;
+    _object->dtime_stack = dtime_stack;
+    _object->hostname = psStringCopy(hostname);
     _object->good_frac = good_frac;
     _object->fault = fault;
@@ -13365,4 +13186,5 @@
     psFree(object->uri);
     psFree(object->path_base);
+    psFree(object->hostname);
 }
 
@@ -13395,5 +13217,15 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, "Key", 0.0)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_stack", PS_DATA_F32, "Key", 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_stack");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, "Key", 0.0)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
         psFree(md);
@@ -13418,5 +13250,5 @@
 }
 
-bool stackSumSkyfileInsert(psDB * dbh, psS64 stack_id, const char *uri, const char *path_base, psF64 bg, psF64 bg_stdev, psF64 good_frac, psS16 fault)
+bool 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)
 {
     psMetadata *md = psMetadataAlloc();
@@ -13446,5 +13278,15 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, NULL, good_frac)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_stack", PS_DATA_F32, NULL, dtime_stack)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_stack");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, hostname)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, NULL, good_frac)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
         psFree(md);
@@ -13479,5 +13321,5 @@
 bool stackSumSkyfileInsertObject(psDB *dbh, stackSumSkyfileRow *object)
 {
-    return stackSumSkyfileInsert(dbh, object->stack_id, object->uri, object->path_base, object->bg, object->bg_stdev, object->good_frac, object->fault);
+    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);
 }
 
@@ -13577,5 +13419,15 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F64, NULL, object->good_frac)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dtime_stack", PS_DATA_F32, NULL, object->dtime_stack)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dtime_stack");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "hostname", PS_DATA_STRING, NULL, object->hostname)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item hostname");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "good_frac", PS_DATA_F32, NULL, object->good_frac)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item good_frac");
         psFree(md);
@@ -13621,5 +13473,15 @@
         return false;
     }
-    psF64 good_frac = psMetadataLookupF64(&status, md, "good_frac");
+    psF32 dtime_stack = psMetadataLookupF32(&status, md, "dtime_stack");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dtime_stack");
+        return false;
+    }
+    char* hostname = psMetadataLookupPtr(&status, md, "hostname");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item hostname");
+        return false;
+    }
+    psF32 good_frac = psMetadataLookupF32(&status, md, "good_frac");
     if (!status) {
         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item good_frac");
@@ -13632,5 +13494,5 @@
     }
 
-    return stackSumSkyfileRowAlloc(stack_id, uri, path_base, bg, bg_stdev, good_frac, fault);
+    return stackSumSkyfileRowAlloc(stack_id, uri, path_base, bg, bg_stdev, dtime_stack, hostname, good_frac, fault);
 }
 psArray *stackSumSkyfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -23548,5 +23410,5 @@
 static void calDBRowFree(calDBRow *object);
 
-calDBRow *calDBRowAlloc(psS64 cal_id, const char *catdir, const char *state)
+calDBRow *calDBRowAlloc(psS64 cal_id, const char *dvodb, const char *state)
 {
     calDBRow        *_object;
@@ -23556,5 +23418,5 @@
 
     _object->cal_id = cal_id;
-    _object->catdir = psStringCopy(catdir);
+    _object->dvodb = psStringCopy(dvodb);
     _object->state = psStringCopy(state);
 
@@ -23564,5 +23426,5 @@
 static void calDBRowFree(calDBRow *object)
 {
-    psFree(object->catdir);
+    psFree(object->dvodb);
     psFree(object->state);
 }
@@ -23576,6 +23438,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "catdir", PS_DATA_STRING, NULL, "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item catdir");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
         psFree(md);
         return false;
@@ -23599,5 +23461,5 @@
 }
 
-bool calDBInsert(psDB * dbh, psS64 cal_id, const char *catdir, const char *state)
+bool calDBInsert(psDB * dbh, psS64 cal_id, const char *dvodb, const char *state)
 {
     psMetadata *md = psMetadataAlloc();
@@ -23607,6 +23469,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "catdir", PS_DATA_STRING, NULL, catdir)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item catdir");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, dvodb)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
         psFree(md);
         return false;
@@ -23640,5 +23502,5 @@
 bool calDBInsertObject(psDB *dbh, calDBRow *object)
 {
-    return calDBInsert(dbh, object->cal_id, object->catdir, object->state);
+    return calDBInsert(dbh, object->cal_id, object->dvodb, object->state);
 }
 
@@ -23718,6 +23580,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "catdir", PS_DATA_STRING, NULL, object->catdir)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item catdir");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, object->dvodb)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
         psFree(md);
         return false;
@@ -23742,7 +23604,7 @@
         return false;
     }
-    char* catdir = psMetadataLookupPtr(&status, md, "catdir");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item catdir");
+    char* dvodb = psMetadataLookupPtr(&status, md, "dvodb");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dvodb");
         return false;
     }
@@ -23753,5 +23615,5 @@
     }
 
-    return calDBRowAlloc(cal_id, catdir, state);
+    return calDBRowAlloc(cal_id, dvodb, state);
 }
 psArray *calDBSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -24216,5 +24078,5 @@
 static void flatcorrRunRowFree(flatcorrRunRow *object);
 
-flatcorrRunRow *flatcorrRunRowAlloc(psS64 corr_id, const char *dvodb, const char *state, const char *workdir, const char *label, const char *stats)
+flatcorrRunRow *flatcorrRunRowAlloc(psS64 corr_id, const char *dvodb, const char *filter, const char *state, const char *workdir, const char *label, const char *stats)
 {
     flatcorrRunRow  *_object;
@@ -24225,4 +24087,5 @@
     _object->corr_id = corr_id;
     _object->dvodb = psStringCopy(dvodb);
+    _object->filter = psStringCopy(filter);
     _object->state = psStringCopy(state);
     _object->workdir = psStringCopy(workdir);
@@ -24236,4 +24099,5 @@
 {
     psFree(object->dvodb);
+    psFree(object->filter);
     psFree(object->state);
     psFree(object->workdir);
@@ -24255,4 +24119,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item filter");
+        psFree(md);
+        return false;
+    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, "64")) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item state");
@@ -24288,5 +24157,5 @@
 }
 
-bool flatcorrRunInsert(psDB * dbh, psS64 corr_id, const char *dvodb, const char *state, const char *workdir, const char *label, const char *stats)
+bool flatcorrRunInsert(psDB * dbh, psS64 corr_id, const char *dvodb, const char *filter, const char *state, const char *workdir, const char *label, const char *stats)
 {
     psMetadata *md = psMetadataAlloc();
@@ -24298,4 +24167,9 @@
     if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, dvodb)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, filter)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item filter");
         psFree(md);
         return false;
@@ -24344,5 +24218,5 @@
 bool flatcorrRunInsertObject(psDB *dbh, flatcorrRunRow *object)
 {
-    return flatcorrRunInsert(dbh, object->corr_id, object->dvodb, object->state, object->workdir, object->label, object->stats);
+    return flatcorrRunInsert(dbh, object->corr_id, object->dvodb, object->filter, object->state, object->workdir, object->label, object->stats);
 }
 
@@ -24427,4 +24301,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, object->filter)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item filter");
+        psFree(md);
+        return false;
+    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item state");
@@ -24466,4 +24345,9 @@
         return false;
     }
+    char* filter = psMetadataLookupPtr(&status, md, "filter");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item filter");
+        return false;
+    }
     char* state = psMetadataLookupPtr(&status, md, "state");
     if (!status) {
@@ -24487,5 +24371,5 @@
     }
 
-    return flatcorrRunRowAlloc(corr_id, dvodb, state, workdir, label, stats);
+    return flatcorrRunRowAlloc(corr_id, dvodb, filter, state, workdir, label, stats);
 }
 psArray *flatcorrRunSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -24903,2 +24787,1100 @@
     return true;
 }
+static void pstampDataStoreRowFree(pstampDataStoreRow *object);
+
+pstampDataStoreRow *pstampDataStoreRowAlloc(psS64 ds_id, const char *uri, const char *lastFileset, const char *state)
+{
+    pstampDataStoreRow *_object;
+
+    _object = psAlloc(sizeof(pstampDataStoreRow));
+    psMemSetDeallocator(_object, (psFreeFunc)pstampDataStoreRowFree);
+
+    _object->ds_id = ds_id;
+    _object->uri = psStringCopy(uri);
+    _object->lastFileset = psStringCopy(lastFileset);
+    _object->state = psStringCopy(state);
+
+    return _object;
+}
+
+static void pstampDataStoreRowFree(pstampDataStoreRow *object)
+{
+    psFree(object->uri);
+    psFree(object->lastFileset);
+    psFree(object->state);
+}
+
+bool pstampDataStoreCreateTable(psDB *dbh)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ds_id", PS_DATA_S64, "Primary Key AUTO_INCREMENT", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ds_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "lastFileset", PS_DATA_STRING, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item lastFileset");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, PSTAMPDATASTORE_TABLE_NAME, md);
+
+    psFree(md);
+
+    return status;
+}
+
+bool pstampDataStoreDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, PSTAMPDATASTORE_TABLE_NAME);
+}
+
+bool pstampDataStoreInsert(psDB * dbh, psS64 ds_id, const char *uri, const char *lastFileset, const char *state)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ds_id", PS_DATA_S64, NULL, ds_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ds_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "lastFileset", PS_DATA_STRING, NULL, lastFileset)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item lastFileset");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, PSTAMPDATASTORE_TABLE_NAME, md);
+    psFree(md);
+
+    return status;
+}
+
+long long pstampDataStoreDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    long long count = psDBDeleteRows(dbh, PSTAMPDATASTORE_TABLE_NAME, where, limit);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampDataStore");
+        return count;
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool pstampDataStoreInsertObject(psDB *dbh, pstampDataStoreRow *object)
+{
+    return pstampDataStoreInsert(dbh, object->ds_id, object->uri, object->lastFileset, object->state);
+}
+
+bool pstampDataStoreInsertObjects(psDB *dbh, psArray *objects)
+{
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        if (!pstampDataStoreInsertObject(dbh, objects->data[i])) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool pstampDataStoreInsertFits(psDB *dbh, const psFits *fits)
+{
+    psArray         *rowSet;
+
+    // move to (the first?) extension named  PSTAMPDATASTORE_TABLE_NAME
+    if (!psFitsMoveExtName(fits, PSTAMPDATASTORE_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PSTAMPDATASTORE_TABLE_NAME);
+        return false;
+    }
+
+    // check HDU type
+    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
+        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
+        return false;
+    }
+
+    // read fits table
+    rowSet = psFitsReadTable(fits);
+    if (!rowSet) {
+        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
+        psFree(rowSet);
+        return false;
+    }
+
+    if (!psDBInsertRows(dbh, PSTAMPDATASTORE_TABLE_NAME, rowSet)) {
+        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+bool pstampDataStoreSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+
+    rowSet = psDBSelectRows(dbh, PSTAMPDATASTORE_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return false;
+    }
+
+    // output to fits
+    if (!psFitsWriteTable(fits, NULL, rowSet, PSTAMPDATASTORE_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+psMetadata *pstampDataStoreMetadataFromObject(const pstampDataStoreRow *object)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ds_id", PS_DATA_S64, NULL, object->ds_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ds_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "lastFileset", PS_DATA_STRING, NULL, object->lastFileset)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item lastFileset");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+
+
+    return md;
+}
+
+pstampDataStoreRow *pstampDataStoreObjectFromMetadata(psMetadata *md)
+{
+
+bool status = false;
+    psS64 ds_id = psMetadataLookupS64(&status, md, "ds_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ds_id");
+        return false;
+    }
+    char* uri = psMetadataLookupPtr(&status, md, "uri");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
+        return false;
+    }
+    char* lastFileset = psMetadataLookupPtr(&status, md, "lastFileset");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item lastFileset");
+        return false;
+    }
+    char* state = psMetadataLookupPtr(&status, md, "state");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
+        return false;
+    }
+
+    return pstampDataStoreRowAlloc(ds_id, uri, lastFileset, state);
+}
+psArray *pstampDataStoreSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+    psArray         *returnSet;
+    psU64           i;
+
+    rowSet = psDBSelectRows(dbh, PSTAMPDATASTORE_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return NULL;
+    }
+
+    // convert psMetadata rows to row objects
+
+    returnSet = psArrayAllocEmpty(rowSet->n);
+
+    for (i = 0; i < rowSet->n; i++) {
+        pstampDataStoreRow *object = pstampDataStoreObjectFromMetadata(rowSet->data[i]);
+        if (!object) {
+            psFree(object);
+            psFree(returnSet);
+            psError(PS_ERR_UNKNOWN, false, "database error");
+            return NULL;
+        }
+        psArrayAdd(returnSet, 0, object);
+        psFree(object);
+    }
+
+    psFree(rowSet);
+
+    return returnSet;
+}
+bool pstampDataStoreDeleteObject(psDB *dbh, const pstampDataStoreRow *object)
+{
+    psMetadata *where = pstampDataStoreMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, PSTAMPDATASTORE_TABLE_NAME, where, 0);
+    psFree(where);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampDataStore");
+        return false;
+    }
+    if (count > 1) {
+        // XXX should this be a psAbort() instead?  It is possible that
+        // having an object match multiple rows was by design.
+        psError(PS_ERR_UNKNOWN, true, "pstampDataStoreRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long pstampDataStoreDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    for (long long i = 0; i < objects->n; i++) {
+        pstampDataStoreRow *object = objects->data[i];
+        psMetadata *where = pstampDataStoreMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, PSTAMPDATASTORE_TABLE_NAME, where, limit);
+        psFree(where);
+        if (count < 0) {
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampDataStore");
+            return count;
+        }
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool pstampDataStorePrintObjects(FILE *stream, psArray *objects, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(objects, false);
+
+    psMetadata *output = psMetadataAlloc();
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        psMetadata *md = pstampDataStoreMetadataFromObject(objects->data[i]);
+        if (!psMetadataAddMetadata(
+            output,
+            PS_LIST_TAIL,
+            PSTAMPDATASTORE_TABLE_NAME,
+            PS_META_DUPLICATE_OK,
+            NULL,
+            md
+        )) {
+            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
+            psFree(md);
+            psFree(output);
+            return false;
+        }
+        psFree(md);
+    }
+
+    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(output);
+    }
+    psFree(output);
+
+    return true;
+}
+bool pstampDataStorePrintObject(FILE *stream, pstampDataStoreRow *object, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(object, false);
+
+    psMetadata *md = pstampDataStoreMetadataFromObject(object);
+
+    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(md);
+    }
+
+    psFree(md);
+
+    return true;
+}
+static void pstampRequestRowFree(pstampRequestRow *object);
+
+pstampRequestRow *pstampRequestRowAlloc(psS64 req_id, psS64 ds_id, const char *state, const char *uri)
+{
+    pstampRequestRow *_object;
+
+    _object = psAlloc(sizeof(pstampRequestRow));
+    psMemSetDeallocator(_object, (psFreeFunc)pstampRequestRowFree);
+
+    _object->req_id = req_id;
+    _object->ds_id = ds_id;
+    _object->state = psStringCopy(state);
+    _object->uri = psStringCopy(uri);
+
+    return _object;
+}
+
+static void pstampRequestRowFree(pstampRequestRow *object)
+{
+    psFree(object->state);
+    psFree(object->uri);
+}
+
+bool pstampRequestCreateTable(psDB *dbh)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "req_id", PS_DATA_S64, "Primary Key AUTO_INCREMENT", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item req_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ds_id", PS_DATA_S64, NULL, 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ds_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, PSTAMPREQUEST_TABLE_NAME, md);
+
+    psFree(md);
+
+    return status;
+}
+
+bool pstampRequestDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, PSTAMPREQUEST_TABLE_NAME);
+}
+
+bool pstampRequestInsert(psDB * dbh, psS64 req_id, psS64 ds_id, const char *state, const char *uri)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "req_id", PS_DATA_S64, NULL, req_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item req_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ds_id", PS_DATA_S64, NULL, ds_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ds_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, PSTAMPREQUEST_TABLE_NAME, md);
+    psFree(md);
+
+    return status;
+}
+
+long long pstampRequestDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    long long count = psDBDeleteRows(dbh, PSTAMPREQUEST_TABLE_NAME, where, limit);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampRequest");
+        return count;
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool pstampRequestInsertObject(psDB *dbh, pstampRequestRow *object)
+{
+    return pstampRequestInsert(dbh, object->req_id, object->ds_id, object->state, object->uri);
+}
+
+bool pstampRequestInsertObjects(psDB *dbh, psArray *objects)
+{
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        if (!pstampRequestInsertObject(dbh, objects->data[i])) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool pstampRequestInsertFits(psDB *dbh, const psFits *fits)
+{
+    psArray         *rowSet;
+
+    // move to (the first?) extension named  PSTAMPREQUEST_TABLE_NAME
+    if (!psFitsMoveExtName(fits, PSTAMPREQUEST_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PSTAMPREQUEST_TABLE_NAME);
+        return false;
+    }
+
+    // check HDU type
+    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
+        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
+        return false;
+    }
+
+    // read fits table
+    rowSet = psFitsReadTable(fits);
+    if (!rowSet) {
+        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
+        psFree(rowSet);
+        return false;
+    }
+
+    if (!psDBInsertRows(dbh, PSTAMPREQUEST_TABLE_NAME, rowSet)) {
+        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+bool pstampRequestSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+
+    rowSet = psDBSelectRows(dbh, PSTAMPREQUEST_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return false;
+    }
+
+    // output to fits
+    if (!psFitsWriteTable(fits, NULL, rowSet, PSTAMPREQUEST_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+psMetadata *pstampRequestMetadataFromObject(const pstampRequestRow *object)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "req_id", PS_DATA_S64, NULL, object->req_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item req_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ds_id", PS_DATA_S64, NULL, object->ds_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ds_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+
+
+    return md;
+}
+
+pstampRequestRow *pstampRequestObjectFromMetadata(psMetadata *md)
+{
+
+bool status = false;
+    psS64 req_id = psMetadataLookupS64(&status, md, "req_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item req_id");
+        return false;
+    }
+    psS64 ds_id = psMetadataLookupS64(&status, md, "ds_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ds_id");
+        return false;
+    }
+    char* state = psMetadataLookupPtr(&status, md, "state");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
+        return false;
+    }
+    char* uri = psMetadataLookupPtr(&status, md, "uri");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
+        return false;
+    }
+
+    return pstampRequestRowAlloc(req_id, ds_id, state, uri);
+}
+psArray *pstampRequestSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+    psArray         *returnSet;
+    psU64           i;
+
+    rowSet = psDBSelectRows(dbh, PSTAMPREQUEST_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return NULL;
+    }
+
+    // convert psMetadata rows to row objects
+
+    returnSet = psArrayAllocEmpty(rowSet->n);
+
+    for (i = 0; i < rowSet->n; i++) {
+        pstampRequestRow *object = pstampRequestObjectFromMetadata(rowSet->data[i]);
+        if (!object) {
+            psFree(object);
+            psFree(returnSet);
+            psError(PS_ERR_UNKNOWN, false, "database error");
+            return NULL;
+        }
+        psArrayAdd(returnSet, 0, object);
+        psFree(object);
+    }
+
+    psFree(rowSet);
+
+    return returnSet;
+}
+bool pstampRequestDeleteObject(psDB *dbh, const pstampRequestRow *object)
+{
+    psMetadata *where = pstampRequestMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, PSTAMPREQUEST_TABLE_NAME, where, 0);
+    psFree(where);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampRequest");
+        return false;
+    }
+    if (count > 1) {
+        // XXX should this be a psAbort() instead?  It is possible that
+        // having an object match multiple rows was by design.
+        psError(PS_ERR_UNKNOWN, true, "pstampRequestRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long pstampRequestDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    for (long long i = 0; i < objects->n; i++) {
+        pstampRequestRow *object = objects->data[i];
+        psMetadata *where = pstampRequestMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, PSTAMPREQUEST_TABLE_NAME, where, limit);
+        psFree(where);
+        if (count < 0) {
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampRequest");
+            return count;
+        }
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool pstampRequestPrintObjects(FILE *stream, psArray *objects, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(objects, false);
+
+    psMetadata *output = psMetadataAlloc();
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        psMetadata *md = pstampRequestMetadataFromObject(objects->data[i]);
+        if (!psMetadataAddMetadata(
+            output,
+            PS_LIST_TAIL,
+            PSTAMPREQUEST_TABLE_NAME,
+            PS_META_DUPLICATE_OK,
+            NULL,
+            md
+        )) {
+            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
+            psFree(md);
+            psFree(output);
+            return false;
+        }
+        psFree(md);
+    }
+
+    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(output);
+    }
+    psFree(output);
+
+    return true;
+}
+bool pstampRequestPrintObject(FILE *stream, pstampRequestRow *object, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(object, false);
+
+    psMetadata *md = pstampRequestMetadataFromObject(object);
+
+    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(md);
+    }
+
+    psFree(md);
+
+    return true;
+}
+static void pstampJobRowFree(pstampJobRow *object);
+
+pstampJobRow *pstampJobRowAlloc(psS64 job_id, psS64 req_id, const char *state, psS32 result, const char *uri, const char *outputBase, const char *args)
+{
+    pstampJobRow    *_object;
+
+    _object = psAlloc(sizeof(pstampJobRow));
+    psMemSetDeallocator(_object, (psFreeFunc)pstampJobRowFree);
+
+    _object->job_id = job_id;
+    _object->req_id = req_id;
+    _object->state = psStringCopy(state);
+    _object->result = result;
+    _object->uri = psStringCopy(uri);
+    _object->outputBase = psStringCopy(outputBase);
+    _object->args = psStringCopy(args);
+
+    return _object;
+}
+
+static void pstampJobRowFree(pstampJobRow *object)
+{
+    psFree(object->state);
+    psFree(object->uri);
+    psFree(object->outputBase);
+    psFree(object->args);
+}
+
+bool pstampJobCreateTable(psDB *dbh)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "job_id", PS_DATA_S64, "Primary Key AUTO_INCREMENT", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item job_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "req_id", PS_DATA_S64, "Primary Key fkey(req_id) ref pstampRequest(req_id)", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item req_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "result", PS_DATA_S32, NULL, 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item result");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "outputBase", PS_DATA_STRING, NULL, "255")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item outputBase");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "args", PS_DATA_STRING, NULL, "511")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item args");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, PSTAMPJOB_TABLE_NAME, md);
+
+    psFree(md);
+
+    return status;
+}
+
+bool pstampJobDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, PSTAMPJOB_TABLE_NAME);
+}
+
+bool pstampJobInsert(psDB * dbh, psS64 job_id, psS64 req_id, const char *state, psS32 result, const char *uri, const char *outputBase, const char *args)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "job_id", PS_DATA_S64, NULL, job_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item job_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "req_id", PS_DATA_S64, NULL, req_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item req_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "result", PS_DATA_S32, NULL, result)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item result");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "outputBase", PS_DATA_STRING, NULL, outputBase)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item outputBase");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "args", PS_DATA_STRING, NULL, args)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item args");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, PSTAMPJOB_TABLE_NAME, md);
+    psFree(md);
+
+    return status;
+}
+
+long long pstampJobDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    long long count = psDBDeleteRows(dbh, PSTAMPJOB_TABLE_NAME, where, limit);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampJob");
+        return count;
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool pstampJobInsertObject(psDB *dbh, pstampJobRow *object)
+{
+    return pstampJobInsert(dbh, object->job_id, object->req_id, object->state, object->result, object->uri, object->outputBase, object->args);
+}
+
+bool pstampJobInsertObjects(psDB *dbh, psArray *objects)
+{
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        if (!pstampJobInsertObject(dbh, objects->data[i])) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool pstampJobInsertFits(psDB *dbh, const psFits *fits)
+{
+    psArray         *rowSet;
+
+    // move to (the first?) extension named  PSTAMPJOB_TABLE_NAME
+    if (!psFitsMoveExtName(fits, PSTAMPJOB_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", PSTAMPJOB_TABLE_NAME);
+        return false;
+    }
+
+    // check HDU type
+    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
+        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
+        return false;
+    }
+
+    // read fits table
+    rowSet = psFitsReadTable(fits);
+    if (!rowSet) {
+        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
+        psFree(rowSet);
+        return false;
+    }
+
+    if (!psDBInsertRows(dbh, PSTAMPJOB_TABLE_NAME, rowSet)) {
+        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+bool pstampJobSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+
+    rowSet = psDBSelectRows(dbh, PSTAMPJOB_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return false;
+    }
+
+    // output to fits
+    if (!psFitsWriteTable(fits, NULL, rowSet, PSTAMPJOB_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+psMetadata *pstampJobMetadataFromObject(const pstampJobRow *object)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "job_id", PS_DATA_S64, NULL, object->job_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item job_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "req_id", PS_DATA_S64, NULL, object->req_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item req_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "result", PS_DATA_S32, NULL, object->result)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item result");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "outputBase", PS_DATA_STRING, NULL, object->outputBase)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item outputBase");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "args", PS_DATA_STRING, NULL, object->args)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item args");
+        psFree(md);
+        return false;
+    }
+
+
+    return md;
+}
+
+pstampJobRow *pstampJobObjectFromMetadata(psMetadata *md)
+{
+
+bool status = false;
+    psS64 job_id = psMetadataLookupS64(&status, md, "job_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item job_id");
+        return false;
+    }
+    psS64 req_id = psMetadataLookupS64(&status, md, "req_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item req_id");
+        return false;
+    }
+    char* state = psMetadataLookupPtr(&status, md, "state");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
+        return false;
+    }
+    psS32 result = psMetadataLookupS32(&status, md, "result");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item result");
+        return false;
+    }
+    char* uri = psMetadataLookupPtr(&status, md, "uri");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
+        return false;
+    }
+    char* outputBase = psMetadataLookupPtr(&status, md, "outputBase");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item outputBase");
+        return false;
+    }
+    char* args = psMetadataLookupPtr(&status, md, "args");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item args");
+        return false;
+    }
+
+    return pstampJobRowAlloc(job_id, req_id, state, result, uri, outputBase, args);
+}
+psArray *pstampJobSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+    psArray         *returnSet;
+    psU64           i;
+
+    rowSet = psDBSelectRows(dbh, PSTAMPJOB_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return NULL;
+    }
+
+    // convert psMetadata rows to row objects
+
+    returnSet = psArrayAllocEmpty(rowSet->n);
+
+    for (i = 0; i < rowSet->n; i++) {
+        pstampJobRow *object = pstampJobObjectFromMetadata(rowSet->data[i]);
+        if (!object) {
+            psFree(object);
+            psFree(returnSet);
+            psError(PS_ERR_UNKNOWN, false, "database error");
+            return NULL;
+        }
+        psArrayAdd(returnSet, 0, object);
+        psFree(object);
+    }
+
+    psFree(rowSet);
+
+    return returnSet;
+}
+bool pstampJobDeleteObject(psDB *dbh, const pstampJobRow *object)
+{
+    psMetadata *where = pstampJobMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, PSTAMPJOB_TABLE_NAME, where, 0);
+    psFree(where);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampJob");
+        return false;
+    }
+    if (count > 1) {
+        // XXX should this be a psAbort() instead?  It is possible that
+        // having an object match multiple rows was by design.
+        psError(PS_ERR_UNKNOWN, true, "pstampJobRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long pstampJobDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    for (long long i = 0; i < objects->n; i++) {
+        pstampJobRow *object = objects->data[i];
+        psMetadata *where = pstampJobMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, PSTAMPJOB_TABLE_NAME, where, limit);
+        psFree(where);
+        if (count < 0) {
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from pstampJob");
+            return count;
+        }
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool pstampJobPrintObjects(FILE *stream, psArray *objects, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(objects, false);
+
+    psMetadata *output = psMetadataAlloc();
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        psMetadata *md = pstampJobMetadataFromObject(objects->data[i]);
+        if (!psMetadataAddMetadata(
+            output,
+            PS_LIST_TAIL,
+            PSTAMPJOB_TABLE_NAME,
+            PS_META_DUPLICATE_OK,
+            NULL,
+            md
+        )) {
+            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
+            psFree(md);
+            psFree(output);
+            return false;
+        }
+        psFree(md);
+    }
+
+    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(output);
+    }
+    psFree(output);
+
+    return true;
+}
+bool pstampJobPrintObject(FILE *stream, pstampJobRow *object, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(object, false);
+
+    psMetadata *md = pstampJobMetadataFromObject(object);
+
+    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(md);
+    }
+
+    psFree(md);
+
+    return true;
+}
