Index: trunk/ippdb/src/ippdb.c
===================================================================
--- trunk/ippdb/src/ippdb.c	(revision 13937)
+++ trunk/ippdb/src/ippdb.c	(revision 14061)
@@ -31,5 +31,4 @@
 #include "ippdb.h"
 
-#define EXPTAGCOUNTER_TABLE_NAME "expTagCounter"
 #define SUMMITEXP_TABLE_NAME "summitExp"
 #define SUMMITIMFILE_TABLE_NAME "summitImfile"
@@ -43,10 +42,9 @@
 #define RAWIMFILE_TABLE_NAME "rawImfile"
 #define GUIDEPENDINGEXP_TABLE_NAME "guidePendingExp"
-#define CHIPPENDINGEXP_TABLE_NAME "chipPendingExp"
-#define CHIPPENDINGIMFILE_TABLE_NAME "chipPendingImfile"
-#define CHIPPROCESSEDEXP_TABLE_NAME "chipProcessedExp"
+#define CHIPRUN_TABLE_NAME "chipRun"
+#define CHIPINPUTIMFILE_TABLE_NAME "chipInputImfile"
+#define CHIPPROCESSEDIMFILE_TABLE_NAME "chipProcessedImfile"
 #define CHIPMASK_TABLE_NAME "chipMask"
-#define CHIPPROCESSEDIMFILE_TABLE_NAME "chipProcessedImfile"
-#define CAMPENDINGEXP_TABLE_NAME "camPendingExp"
+#define CAMRUN_TABLE_NAME "camRun"
 #define CAMPROCESSEDEXP_TABLE_NAME "camProcessedExp"
 #define CAMMASK_TABLE_NAME "camMask"
@@ -248,280 +246,7 @@
 }
 
-static void expTagCounterRowFree(expTagCounterRow *object);
-
-expTagCounterRow *expTagCounterRowAlloc(psU64 counter)
-{
-    expTagCounterRow *_object;
-
-    _object = psAlloc(sizeof(expTagCounterRow));
-    psMemSetDeallocator(_object, (psFreeFunc)expTagCounterRowFree);
-
-    _object->counter = counter;
-
-    return _object;
-}
-
-static void expTagCounterRowFree(expTagCounterRow *object)
-{
-}
-
-bool expTagCounterCreateTable(psDB *dbh)
-{
-    psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "counter", PS_DATA_U64, NULL, 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item counter");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBCreateTable(dbh, EXPTAGCOUNTER_TABLE_NAME, md);
-
-    psFree(md);
-
-    return status;
-}
-
-bool expTagCounterDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, EXPTAGCOUNTER_TABLE_NAME);
-}
-
-bool expTagCounterInsert(psDB * dbh, psU64 counter)
-{
-    psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "counter", PS_DATA_U64, NULL, counter)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item counter");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBInsertOneRow(dbh, EXPTAGCOUNTER_TABLE_NAME, md);
-    psFree(md);
-
-    return status;
-}
-
-long long expTagCounterDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
-{
-    long long       deleted = 0;
-
-    long long count = psDBDeleteRows(dbh, EXPTAGCOUNTER_TABLE_NAME, where, limit);
-    if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from expTagCounter");
-        return count;
-
-        deleted += count;
-    }
-
-    return deleted;
-}
-bool expTagCounterInsertObject(psDB *dbh, expTagCounterRow *object)
-{
-    return expTagCounterInsert(dbh, object->counter);
-}
-
-bool expTagCounterInsertObjects(psDB *dbh, psArray *objects)
-{
-    for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!expTagCounterInsertObject(dbh, objects->data[i])) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool expTagCounterInsertFits(psDB *dbh, const psFits *fits)
-{
-    psArray         *rowSet;
-
-    // move to (the first?) extension named  EXPTAGCOUNTER_TABLE_NAME
-    if (!psFitsMoveExtName(fits, EXPTAGCOUNTER_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", EXPTAGCOUNTER_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, EXPTAGCOUNTER_TABLE_NAME, rowSet)) {
-        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
-        psFree(rowSet);
-        return false;
-    }
-
-    psFree(rowSet);
-
-    return true;
-}
-
-bool expTagCounterSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
-{
-    psArray         *rowSet;
-
-    rowSet = psDBSelectRows(dbh, EXPTAGCOUNTER_TABLE_NAME, where, limit);
-    if (!rowSet) {
-        return false;
-    }
-
-    // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, EXPTAGCOUNTER_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
-        psFree(rowSet);
-        return false;
-    }
-
-    psFree(rowSet);
-
-    return true;
-}
-
-psMetadata *expTagCounterMetadataFromObject(const expTagCounterRow *object)
-{
-    psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "counter", PS_DATA_U64, NULL, object->counter)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item counter");
-        psFree(md);
-        return false;
-    }
-
-
-    return md;
-}
-
-expTagCounterRow *expTagCounterObjectFromMetadata(psMetadata *md)
-{
-
-bool status = false;
-    psU64 counter = psMetadataLookupU64(&status, md, "counter");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item counter");
-        return false;
-    }
-
-    return expTagCounterRowAlloc(counter);
-}
-psArray *expTagCounterSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
-{
-    psArray         *rowSet;
-    psArray         *returnSet;
-    psU64           i;
-
-    rowSet = psDBSelectRows(dbh, EXPTAGCOUNTER_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++) {
-        expTagCounterRow *object = expTagCounterObjectFromMetadata(rowSet->data[i]);
-        psArrayAdd(returnSet, 0, object);
-        psFree(object);
-    }
-
-    psFree(rowSet);
-
-    return returnSet;
-}
-bool expTagCounterDeleteObject(psDB *dbh, const expTagCounterRow *object)
-{
-    psMetadata *where = expTagCounterMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, EXPTAGCOUNTER_TABLE_NAME, where, 0);
-    psFree(where);
-    if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from expTagCounter");
-        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, "expTagCounterRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long expTagCounterDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
-{
-    long long       deleted = 0;
-
-    for (long long i = 0; i < objects->n; i++) {
-        expTagCounterRow *object = objects->data[i];
-        psMetadata *where = expTagCounterMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, EXPTAGCOUNTER_TABLE_NAME, where, limit);
-        psFree(where);
-        if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from expTagCounter");
-            return count;
-        }
-
-        deleted += count;
-    }
-
-    return deleted;
-}
-bool expTagCounterPrintObjects(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 = expTagCounterMetadataFromObject(objects->data[i]);
-        if (!psMetadataAddMetadata(
-            output,
-            PS_LIST_TAIL,
-            EXPTAGCOUNTER_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 expTagCounterPrintObject(FILE *stream, expTagCounterRow *object, bool mdcf)
-{
-    PS_ASSERT_PTR_NON_NULL(object, false);
-
-    psMetadata *md = expTagCounterMetadataFromObject(object);
-
-    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
-        psFree(md);
-    }
-
-    psFree(md);
-
-    return true;
-}
 static void summitExpRowFree(summitExpRow *object);
 
-summitExpRow *summitExpRowAlloc(const char *exp_id, const char *camera, const char *telescope, psTime* dateobs, const char *exp_type, const char *uri, psS32 imfiles)
+summitExpRow *summitExpRowAlloc(const char *exp_name, const char *camera, const char *telescope, psTime* dateobs, const char *exp_type, const char *uri, psS32 imfiles)
 {
     summitExpRow    *_object;
@@ -530,5 +255,5 @@
     psMemSetDeallocator(_object, (psFreeFunc)summitExpRowFree);
 
-    _object->exp_id = psStringCopy(exp_id);
+    _object->exp_name = psStringCopy(exp_name);
     _object->camera = psStringCopy(camera);
     _object->telescope = psStringCopy(telescope);
@@ -543,5 +268,5 @@
 static void summitExpRowFree(summitExpRow *object)
 {
-    psFree(object->exp_id);
+    psFree(object->exp_name);
     psFree(object->camera);
     psFree(object->telescope);
@@ -554,6 +279,6 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -602,9 +327,9 @@
 }
 
-bool summitExpInsert(psDB * dbh, const char *exp_id, const char *camera, const char *telescope, psTime* dateobs, const char *exp_type, const char *uri, psS32 imfiles)
+bool summitExpInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, psTime* dateobs, const char *exp_type, const char *uri, psS32 imfiles)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -663,5 +388,5 @@
 bool summitExpInsertObject(psDB *dbh, summitExpRow *object)
 {
-    return summitExpInsert(dbh, object->exp_id, object->camera, object->telescope, object->dateobs, object->exp_type, object->uri, object->imfiles);
+    return summitExpInsert(dbh, object->exp_name, object->camera, object->telescope, object->dateobs, object->exp_type, object->uri, object->imfiles);
 }
 
@@ -736,6 +461,6 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, object->exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -780,7 +505,7 @@
 
 bool status = false;
-    char* exp_id = psMetadataLookupPtr(&status, md, "exp_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
+    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;
     }
@@ -816,5 +541,5 @@
     }
 
-    return summitExpRowAlloc(exp_id, camera, telescope, dateobs, exp_type, uri, imfiles);
+    return summitExpRowAlloc(exp_name, camera, telescope, dateobs, exp_type, uri, imfiles);
 }
 psArray *summitExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -928,5 +653,5 @@
 static void summitImfileRowFree(summitImfileRow *object);
 
-summitImfileRow *summitImfileRowAlloc(const char *exp_id, const char *camera, const char *telescope, const char *file_id, psS32 bytes, const char *md5sum, const char *class, const char *class_id, const char *uri)
+summitImfileRow *summitImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *file_id, psS32 bytes, const char *md5sum, const char *class, const char *class_id, const char *uri)
 {
     summitImfileRow *_object;
@@ -935,5 +660,5 @@
     psMemSetDeallocator(_object, (psFreeFunc)summitImfileRowFree);
 
-    _object->exp_id = psStringCopy(exp_id);
+    _object->exp_name = psStringCopy(exp_name);
     _object->camera = psStringCopy(camera);
     _object->telescope = psStringCopy(telescope);
@@ -950,5 +675,5 @@
 static void summitImfileRowFree(summitImfileRow *object)
 {
-    psFree(object->exp_id);
+    psFree(object->exp_name);
     psFree(object->camera);
     psFree(object->telescope);
@@ -963,6 +688,6 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -1021,9 +746,9 @@
 }
 
-bool summitImfileInsert(psDB * dbh, const char *exp_id, const char *camera, const char *telescope, const char *file_id, psS32 bytes, const char *md5sum, const char *class, const char *class_id, const char *uri)
+bool summitImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *file_id, psS32 bytes, const char *md5sum, const char *class, const char *class_id, const char *uri)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -1092,5 +817,5 @@
 bool summitImfileInsertObject(psDB *dbh, summitImfileRow *object)
 {
-    return summitImfileInsert(dbh, object->exp_id, object->camera, object->telescope, object->file_id, object->bytes, object->md5sum, object->class, object->class_id, object->uri);
+    return summitImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->file_id, object->bytes, object->md5sum, object->class, object->class_id, object->uri);
 }
 
@@ -1165,6 +890,6 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, object->exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -1219,7 +944,7 @@
 
 bool status = false;
-    char* exp_id = psMetadataLookupPtr(&status, md, "exp_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
+    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;
     }
@@ -1265,5 +990,5 @@
     }
 
-    return summitImfileRowAlloc(exp_id, camera, telescope, file_id, bytes, md5sum, class, class_id, uri);
+    return summitImfileRowAlloc(exp_name, camera, telescope, file_id, bytes, md5sum, class, class_id, uri);
 }
 psArray *summitImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -1377,5 +1102,5 @@
 static void pzPendingExpRowFree(pzPendingExpRow *object);
 
-pzPendingExpRow *pzPendingExpRowAlloc(const char *exp_id, const char *camera, const char *telescope)
+pzPendingExpRow *pzPendingExpRowAlloc(const char *exp_name, const char *camera, const char *telescope)
 {
     pzPendingExpRow *_object;
@@ -1384,5 +1109,5 @@
     psMemSetDeallocator(_object, (psFreeFunc)pzPendingExpRowFree);
 
-    _object->exp_id = psStringCopy(exp_id);
+    _object->exp_name = psStringCopy(exp_name);
     _object->camera = psStringCopy(camera);
     _object->telescope = psStringCopy(telescope);
@@ -1393,5 +1118,5 @@
 static void pzPendingExpRowFree(pzPendingExpRow *object)
 {
-    psFree(object->exp_id);
+    psFree(object->exp_name);
     psFree(object->camera);
     psFree(object->telescope);
@@ -1401,6 +1126,6 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -1429,9 +1154,9 @@
 }
 
-bool pzPendingExpInsert(psDB * dbh, const char *exp_id, const char *camera, const char *telescope)
+bool pzPendingExpInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -1470,5 +1195,5 @@
 bool pzPendingExpInsertObject(psDB *dbh, pzPendingExpRow *object)
 {
-    return pzPendingExpInsert(dbh, object->exp_id, object->camera, object->telescope);
+    return pzPendingExpInsert(dbh, object->exp_name, object->camera, object->telescope);
 }
 
@@ -1543,6 +1268,6 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, object->exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -1567,7 +1292,7 @@
 
 bool status = false;
-    char* exp_id = psMetadataLookupPtr(&status, md, "exp_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
+    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;
     }
@@ -1583,5 +1308,5 @@
     }
 
-    return pzPendingExpRowAlloc(exp_id, camera, telescope);
+    return pzPendingExpRowAlloc(exp_name, camera, telescope);
 }
 psArray *pzPendingExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -1695,5 +1420,5 @@
 static void pzPendingImfileRowFree(pzPendingImfileRow *object);
 
-pzPendingImfileRow *pzPendingImfileRowAlloc(const char *exp_id, const char *camera, const char *telescope, const char *class, const char *class_id, const char *exp_tag)
+pzPendingImfileRow *pzPendingImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, psS64 exp_id)
 {
     pzPendingImfileRow *_object;
@@ -1702,10 +1427,10 @@
     psMemSetDeallocator(_object, (psFreeFunc)pzPendingImfileRowFree);
 
-    _object->exp_id = psStringCopy(exp_id);
+    _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->exp_tag = psStringCopy(exp_tag);
+    _object->exp_id = exp_id;
 
     return _object;
@@ -1714,10 +1439,9 @@
 static void pzPendingImfileRowFree(pzPendingImfileRow *object)
 {
-    psFree(object->exp_id);
+    psFree(object->exp_name);
     psFree(object->camera);
     psFree(object->telescope);
     psFree(object->class);
     psFree(object->class_id);
-    psFree(object->exp_tag);
 }
 
@@ -1725,6 +1449,6 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -1750,6 +1474,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Unique Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Unique Key", 64)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -1768,9 +1492,9 @@
 }
 
-bool pzPendingImfileInsert(psDB * dbh, const char *exp_id, const char *camera, const char *telescope, const char *class, const char *class_id, const char *exp_tag)
+bool pzPendingImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, psS64 exp_id)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -1796,6 +1520,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -1824,5 +1548,5 @@
 bool pzPendingImfileInsertObject(psDB *dbh, pzPendingImfileRow *object)
 {
-    return pzPendingImfileInsert(dbh, object->exp_id, object->camera, object->telescope, object->class, object->class_id, object->exp_tag);
+    return pzPendingImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id, object->exp_id);
 }
 
@@ -1897,6 +1621,6 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, object->exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -1922,6 +1646,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -1936,36 +1660,36 @@
 
 bool status = false;
-    char* exp_id = psMetadataLookupPtr(&status, md, "exp_id");
+    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;
+    }
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
     if (!status) {
         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
         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* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
-        return false;
-    }
-
-    return pzPendingImfileRowAlloc(exp_id, camera, telescope, class, class_id, exp_tag);
+
+    return pzPendingImfileRowAlloc(exp_name, camera, telescope, class, class_id, exp_id);
 }
 psArray *pzPendingImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -2079,5 +1803,5 @@
 static void pzDoneExpRowFree(pzDoneExpRow *object);
 
-pzDoneExpRow *pzDoneExpRowAlloc(const char *exp_id, const char *camera, const char *telescope)
+pzDoneExpRow *pzDoneExpRowAlloc(const char *exp_name, const char *camera, const char *telescope)
 {
     pzDoneExpRow    *_object;
@@ -2086,5 +1810,5 @@
     psMemSetDeallocator(_object, (psFreeFunc)pzDoneExpRowFree);
 
-    _object->exp_id = psStringCopy(exp_id);
+    _object->exp_name = psStringCopy(exp_name);
     _object->camera = psStringCopy(camera);
     _object->telescope = psStringCopy(telescope);
@@ -2095,5 +1819,5 @@
 static void pzDoneExpRowFree(pzDoneExpRow *object)
 {
-    psFree(object->exp_id);
+    psFree(object->exp_name);
     psFree(object->camera);
     psFree(object->telescope);
@@ -2103,6 +1827,6 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -2131,9 +1855,9 @@
 }
 
-bool pzDoneExpInsert(psDB * dbh, const char *exp_id, const char *camera, const char *telescope)
+bool pzDoneExpInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -2172,5 +1896,5 @@
 bool pzDoneExpInsertObject(psDB *dbh, pzDoneExpRow *object)
 {
-    return pzDoneExpInsert(dbh, object->exp_id, object->camera, object->telescope);
+    return pzDoneExpInsert(dbh, object->exp_name, object->camera, object->telescope);
 }
 
@@ -2245,6 +1969,6 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, object->exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -2269,7 +1993,7 @@
 
 bool status = false;
-    char* exp_id = psMetadataLookupPtr(&status, md, "exp_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
+    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;
     }
@@ -2285,5 +2009,5 @@
     }
 
-    return pzDoneExpRowAlloc(exp_id, camera, telescope);
+    return pzDoneExpRowAlloc(exp_name, camera, telescope);
 }
 psArray *pzDoneExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -2397,5 +2121,5 @@
 static void pzDoneImfileRowFree(pzDoneImfileRow *object);
 
-pzDoneImfileRow *pzDoneImfileRowAlloc(const char *exp_id, const char *camera, const char *telescope, const char *class, const char *class_id, const char *exp_tag, const char *uri)
+pzDoneImfileRow *pzDoneImfileRowAlloc(const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, psS64 exp_id, const char *uri)
 {
     pzDoneImfileRow *_object;
@@ -2404,10 +2128,10 @@
     psMemSetDeallocator(_object, (psFreeFunc)pzDoneImfileRowFree);
 
-    _object->exp_id = psStringCopy(exp_id);
+    _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->exp_tag = psStringCopy(exp_tag);
+    _object->exp_id = exp_id;
     _object->uri = psStringCopy(uri);
 
@@ -2417,10 +2141,9 @@
 static void pzDoneImfileRowFree(pzDoneImfileRow *object)
 {
-    psFree(object->exp_id);
+    psFree(object->exp_name);
     psFree(object->camera);
     psFree(object->telescope);
     psFree(object->class);
     psFree(object->class_id);
-    psFree(object->exp_tag);
     psFree(object->uri);
 }
@@ -2429,6 +2152,6 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -2454,6 +2177,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Unique Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Unique Key", 64)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -2477,9 +2200,9 @@
 }
 
-bool pzDoneImfileInsert(psDB * dbh, const char *exp_id, const char *camera, const char *telescope, const char *class, const char *class_id, const char *exp_tag, const char *uri)
+bool pzDoneImfileInsert(psDB * dbh, const char *exp_name, const char *camera, const char *telescope, const char *class, const char *class_id, psS64 exp_id, const char *uri)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -2505,6 +2228,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -2538,5 +2261,5 @@
 bool pzDoneImfileInsertObject(psDB *dbh, pzDoneImfileRow *object)
 {
-    return pzDoneImfileInsert(dbh, object->exp_id, object->camera, object->telescope, object->class, object->class_id, object->exp_tag, object->uri);
+    return pzDoneImfileInsert(dbh, object->exp_name, object->camera, object->telescope, object->class, object->class_id, object->exp_id, object->uri);
 }
 
@@ -2611,6 +2334,6 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, object->exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+    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;
@@ -2636,6 +2359,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -2655,34 +2378,34 @@
 
 bool status = false;
-    char* exp_id = psMetadataLookupPtr(&status, md, "exp_id");
+    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;
+    }
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
     if (!status) {
         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
         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* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
-        return false;
-    }
     char* uri = psMetadataLookupPtr(&status, md, "uri");
     if (!status) {
@@ -2691,5 +2414,5 @@
     }
 
-    return pzDoneImfileRowAlloc(exp_id, camera, telescope, class, class_id, exp_tag, uri);
+    return pzDoneImfileRowAlloc(exp_name, camera, telescope, class, class_id, exp_id, uri);
 }
 psArray *pzDoneImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -2803,5 +2526,5 @@
 static void newExpRowFree(newExpRow *object);
 
-newExpRow *newExpRowAlloc(const char *exp_tag, const char *exp_id, const char *camera, const char *telescope, psS32 imfiles, const char *workdir)
+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)
 {
     newExpRow       *_object;
@@ -2810,10 +2533,11 @@
     psMemSetDeallocator(_object, (psFreeFunc)newExpRowFree);
 
-    _object->exp_tag = psStringCopy(exp_tag);
-    _object->exp_id = psStringCopy(exp_id);
-    _object->camera = psStringCopy(camera);
-    _object->telescope = psStringCopy(telescope);
-    _object->imfiles = imfiles;
+    _object->exp_id = exp_id;
+    _object->tmp_exp_name = psStringCopy(tmp_exp_name);
+    _object->tmp_camera = psStringCopy(tmp_camera);
+    _object->tmp_telescope = psStringCopy(tmp_telescope);
+    _object->state = psStringCopy(state);
     _object->workdir = psStringCopy(workdir);
+    _object->workdir_state = psStringCopy(workdir_state);
 
     return _object;
@@ -2822,9 +2546,10 @@
 static void newExpRowFree(newExpRow *object)
 {
-    psFree(object->exp_tag);
-    psFree(object->exp_id);
-    psFree(object->camera);
-    psFree(object->telescope);
+    psFree(object->tmp_exp_name);
+    psFree(object->tmp_camera);
+    psFree(object->tmp_telescope);
+    psFree(object->state);
     psFree(object->workdir);
+    psFree(object->workdir_state);
 }
 
@@ -2832,26 +2557,26 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, "Key", "64")) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key AUTO_INCREMENT", 0)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "camera", PS_DATA_STRING, "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, "Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "imfiles", PS_DATA_S32, NULL, 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item imfiles");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_exp_name", PS_DATA_STRING, "Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_exp_name");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_camera", PS_DATA_STRING, "Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_camera");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_telescope", PS_DATA_STRING, "Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_telescope");
+        psFree(md);
+        return false;
+    }
+    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;
@@ -2862,4 +2587,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, "key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
+        psFree(md);
+        return false;
+    }
 
     bool status = psDBCreateTable(dbh, NEWEXP_TABLE_NAME, md);
@@ -2875,29 +2605,29 @@
 }
 
-bool newExpInsert(psDB * dbh, const char *exp_tag, const char *exp_id, const char *camera, const char *telescope, psS32 imfiles, const char *workdir)
+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)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, exp_id)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         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, "imfiles", PS_DATA_S32, NULL, imfiles)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item imfiles");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_exp_name", PS_DATA_STRING, NULL, tmp_exp_name)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_exp_name");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_camera", PS_DATA_STRING, NULL, tmp_camera)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_camera");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_telescope", PS_DATA_STRING, NULL, tmp_telescope)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_telescope");
+        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;
@@ -2905,4 +2635,9 @@
     if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, workdir)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, NULL, workdir_state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
         psFree(md);
         return false;
@@ -2931,5 +2666,5 @@
 bool newExpInsertObject(psDB *dbh, newExpRow *object)
 {
-    return newExpInsert(dbh, object->exp_tag, object->exp_id, object->camera, object->telescope, object->imfiles, object->workdir);
+    return newExpInsert(dbh, object->exp_id, object->tmp_exp_name, object->tmp_camera, object->tmp_telescope, object->state, object->workdir, object->workdir_state);
 }
 
@@ -3004,26 +2739,26 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, object->exp_id)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         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, "imfiles", PS_DATA_S32, NULL, object->imfiles)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item imfiles");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_exp_name", PS_DATA_STRING, NULL, object->tmp_exp_name)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_exp_name");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_camera", PS_DATA_STRING, NULL, object->tmp_camera)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_camera");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_telescope", PS_DATA_STRING, NULL, object->tmp_telescope)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_telescope");
+        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;
@@ -3034,4 +2769,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, NULL, object->workdir_state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
+        psFree(md);
+        return false;
+    }
 
 
@@ -3043,27 +2783,27 @@
 
 bool status = false;
-    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
-        return false;
-    }
-    char* exp_id = psMetadataLookupPtr(&status, md, "exp_id");
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
     if (!status) {
         psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
         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;
-    }
-    psS32 imfiles = psMetadataLookupS32(&status, md, "imfiles");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item imfiles");
+    char* tmp_exp_name = psMetadataLookupPtr(&status, md, "tmp_exp_name");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tmp_exp_name");
+        return false;
+    }
+    char* tmp_camera = psMetadataLookupPtr(&status, md, "tmp_camera");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tmp_camera");
+        return false;
+    }
+    char* tmp_telescope = psMetadataLookupPtr(&status, md, "tmp_telescope");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tmp_telescope");
+        return false;
+    }
+    char* state = psMetadataLookupPtr(&status, md, "state");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
         return false;
     }
@@ -3073,6 +2813,11 @@
         return false;
     }
-
-    return newExpRowAlloc(exp_tag, exp_id, camera, telescope, imfiles, workdir);
+    char* workdir_state = psMetadataLookupPtr(&status, md, "workdir_state");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item workdir_state");
+        return false;
+    }
+
+    return newExpRowAlloc(exp_id, tmp_exp_name, tmp_camera, tmp_telescope, state, workdir, workdir_state);
 }
 psArray *newExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -3186,5 +2931,5 @@
 static void newImfileRowFree(newImfileRow *object);
 
-newImfileRow *newImfileRowAlloc(const char *exp_tag, const char *class, const char *class_id, const char *uri)
+newImfileRow *newImfileRowAlloc(psS64 exp_id, const char *tmp_class_id, const char *uri)
 {
     newImfileRow    *_object;
@@ -3193,7 +2938,6 @@
     psMemSetDeallocator(_object, (psFreeFunc)newImfileRowFree);
 
-    _object->exp_tag = psStringCopy(exp_tag);
-    _object->class = psStringCopy(class);
-    _object->class_id = psStringCopy(class_id);
+    _object->exp_id = exp_id;
+    _object->tmp_class_id = psStringCopy(tmp_class_id);
     _object->uri = psStringCopy(uri);
 
@@ -3203,7 +2947,5 @@
 static void newImfileRowFree(newImfileRow *object)
 {
-    psFree(object->exp_tag);
-    psFree(object->class);
-    psFree(object->class_id);
+    psFree(object->tmp_class_id);
     psFree(object->uri);
 }
@@ -3212,16 +2954,11 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
-        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");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key fkey(exp_id) ref newExp(exp_id)", 64)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_class_id", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_class_id");
         psFree(md);
         return false;
@@ -3245,19 +2982,14 @@
 }
 
-bool newImfileInsert(psDB * dbh, const char *exp_tag, const char *class, const char *class_id, const char *uri)
+bool newImfileInsert(psDB * dbh, psS64 exp_id, const char *tmp_class_id, const char *uri)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
-        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");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_class_id", PS_DATA_STRING, NULL, tmp_class_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_class_id");
         psFree(md);
         return false;
@@ -3291,5 +3023,5 @@
 bool newImfileInsertObject(psDB *dbh, newImfileRow *object)
 {
-    return newImfileInsert(dbh, object->exp_tag, object->class, object->class_id, object->uri);
+    return newImfileInsert(dbh, object->exp_id, object->tmp_class_id, object->uri);
 }
 
@@ -3364,16 +3096,11 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
-        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");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_class_id", PS_DATA_STRING, NULL, object->tmp_class_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_class_id");
         psFree(md);
         return false;
@@ -3393,17 +3120,12 @@
 
 bool status = false;
-    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
-        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");
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
+        return false;
+    }
+    char* tmp_class_id = psMetadataLookupPtr(&status, md, "tmp_class_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tmp_class_id");
         return false;
     }
@@ -3414,5 +3136,5 @@
     }
 
-    return newImfileRowAlloc(exp_tag, class, class_id, uri);
+    return newImfileRowAlloc(exp_id, tmp_class_id, uri);
 }
 psArray *newImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -3526,5 +3248,5 @@
 static void rawExpRowFree(rawExpRow *object);
 
-rawExpRow *rawExpRowAlloc(const char *exp_tag, const char *exp_id, const char *camera, const char *telescope, psTime* dateobs, const char *exp_type, psS32 imfiles, const char *filelevel, const char *workdir, const char *filter, psF32 airmass, psF64 ra, psF64 decl, psF32 exp_time, psF32 sat_pixel_frac, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 alt, psF64 az, psF32 ccd_temp, psF64 posang, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *object, psF32 solang, psS16 fault)
+rawExpRow *rawExpRowAlloc(psS64 exp_id, const char *exp_name, const char *camera, const char *telescope, psTime* dateobs, const char *exp_tag, const char *exp_type, const char *filelevel, const char *workdir, const char *filter, psF32 airmass, psF64 ra, psF64 decl, psF32 exp_time, psF32 sat_pixel_frac, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 alt, psF64 az, psF32 ccd_temp, psF64 posang, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *object, psF32 solang, psS16 fault)
 {
     rawExpRow       *_object;
@@ -3533,11 +3255,11 @@
     psMemSetDeallocator(_object, (psFreeFunc)rawExpRowFree);
 
-    _object->exp_tag = psStringCopy(exp_tag);
-    _object->exp_id = psStringCopy(exp_id);
+    _object->exp_id = exp_id;
+    _object->exp_name = psStringCopy(exp_name);
     _object->camera = psStringCopy(camera);
     _object->telescope = psStringCopy(telescope);
     _object->dateobs = psTimeCopy(dateobs);
+    _object->exp_tag = psStringCopy(exp_tag);
     _object->exp_type = psStringCopy(exp_type);
-    _object->imfiles = imfiles;
     _object->filelevel = psStringCopy(filelevel);
     _object->workdir = psStringCopy(workdir);
@@ -3569,9 +3291,9 @@
 static void rawExpRowFree(rawExpRow *object)
 {
-    psFree(object->exp_tag);
-    psFree(object->exp_id);
+    psFree(object->exp_name);
     psFree(object->camera);
     psFree(object->telescope);
     psFree(object->dateobs);
+    psFree(object->exp_tag);
     psFree(object->exp_type);
     psFree(object->filelevel);
@@ -3584,11 +3306,11 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, "Key", "64")) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key fkey(exp_id) ref newExp(exp_id)", 64)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_name");
         psFree(md);
         return false;
@@ -3609,4 +3331,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, "255")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+        psFree(md);
+        return false;
+    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_type", PS_DATA_STRING, NULL, "64")) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_type");
@@ -3614,9 +3341,4 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "imfiles", PS_DATA_S32, NULL, 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item imfiles");
-        psFree(md);
-        return false;
-    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "filelevel", PS_DATA_STRING, NULL, "64")) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item filelevel");
@@ -3747,7 +3469,32 @@
 }
 
-bool rawExpInsert(psDB * dbh, const char *exp_tag, const char *exp_id, const char *camera, const char *telescope, psTime* dateobs, const char *exp_type, psS32 imfiles, const char *filelevel, const char *workdir, const char *filter, psF32 airmass, psF64 ra, psF64 decl, psF32 exp_time, psF32 sat_pixel_frac, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 alt, psF64 az, psF32 ccd_temp, psF64 posang, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *object, psF32 solang, psS16 fault)
+bool rawExpInsert(psDB * dbh, psS64 exp_id, const char *exp_name, const char *camera, const char *telescope, psTime* dateobs, const char *exp_tag, const char *exp_type, const char *filelevel, const char *workdir, const char *filter, psF32 airmass, psF64 ra, psF64 decl, psF32 exp_time, psF32 sat_pixel_frac, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 alt, psF64 az, psF32 ccd_temp, psF64 posang, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *object, psF32 solang, psS16 fault)
 {
     psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+        psFree(md);
+        return false;
+    }
+    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, "dateobs", PS_DATA_TIME, NULL, dateobs)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs");
+        psFree(md);
+        return false;
+    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
@@ -3755,31 +3502,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
-        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, "dateobs", PS_DATA_TIME, NULL, dateobs)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs");
-        psFree(md);
-        return false;
-    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_type", PS_DATA_STRING, NULL, exp_type)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_type");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "imfiles", PS_DATA_S32, NULL, imfiles)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item imfiles");
         psFree(md);
         return false;
@@ -3923,5 +3645,5 @@
 bool rawExpInsertObject(psDB *dbh, rawExpRow *object)
 {
-    return rawExpInsert(dbh, object->exp_tag, object->exp_id, object->camera, object->telescope, object->dateobs, object->exp_type, object->imfiles, object->filelevel, object->workdir, object->filter, object->airmass, object->ra, object->decl, object->exp_time, object->sat_pixel_frac, object->bg, object->bg_stdev, object->bg_mean_stdev, object->alt, object->az, object->ccd_temp, object->posang, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->object, object->solang, object->fault);
+    return rawExpInsert(dbh, object->exp_id, object->exp_name, object->camera, object->telescope, object->dateobs, object->exp_tag, object->exp_type, object->filelevel, object->workdir, object->filter, object->airmass, object->ra, object->decl, object->exp_time, object->sat_pixel_frac, object->bg, object->bg_stdev, object->bg_mean_stdev, object->alt, object->az, object->ccd_temp, object->posang, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->object, object->solang, object->fault);
 }
 
@@ -3996,4 +3718,29 @@
 {
     psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+        psFree(md);
+        return false;
+    }
+    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, "dateobs", PS_DATA_TIME, NULL, object->dateobs)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs");
+        psFree(md);
+        return false;
+    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
@@ -4001,24 +3748,4 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_STRING, NULL, object->exp_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
-        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, "dateobs", PS_DATA_TIME, NULL, object->dateobs)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs");
-        psFree(md);
-        return false;
-    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_type", PS_DATA_STRING, NULL, object->exp_type)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item exp_type");
@@ -4026,9 +3753,4 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "imfiles", PS_DATA_S32, NULL, object->imfiles)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item imfiles");
-        psFree(md);
-        return false;
-    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "filelevel", PS_DATA_STRING, NULL, object->filelevel)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item filelevel");
@@ -4155,4 +3877,29 @@
 
 bool status = false;
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
+        return 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;
+    }
+    psTime* dateobs = psMetadataLookupPtr(&status, md, "dateobs");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dateobs");
+        return false;
+    }
     char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
     if (!status) {
@@ -4160,24 +3907,4 @@
         return false;
     }
-    char* exp_id = psMetadataLookupPtr(&status, md, "exp_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
-        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;
-    }
-    psTime* dateobs = psMetadataLookupPtr(&status, md, "dateobs");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dateobs");
-        return false;
-    }
     char* exp_type = psMetadataLookupPtr(&status, md, "exp_type");
     if (!status) {
@@ -4185,9 +3912,4 @@
         return false;
     }
-    psS32 imfiles = psMetadataLookupS32(&status, md, "imfiles");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item imfiles");
-        return false;
-    }
     char* filelevel = psMetadataLookupPtr(&status, md, "filelevel");
     if (!status) {
@@ -4306,5 +4028,5 @@
     }
 
-    return rawExpRowAlloc(exp_tag, exp_id, camera, telescope, dateobs, exp_type, imfiles, filelevel, workdir, filter, airmass, ra, decl, exp_time, sat_pixel_frac, bg, bg_stdev, bg_mean_stdev, alt, az, ccd_temp, posang, user_1, user_2, user_3, user_4, user_5, object, solang, fault);
+    return rawExpRowAlloc(exp_id, exp_name, camera, telescope, dateobs, exp_tag, exp_type, filelevel, workdir, filter, airmass, ra, decl, exp_time, sat_pixel_frac, bg, bg_stdev, bg_mean_stdev, alt, az, ccd_temp, posang, user_1, user_2, user_3, user_4, user_5, object, solang, fault);
 }
 psArray *rawExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -4418,5 +4140,5 @@
 static void rawImfileRowFree(rawImfileRow *object);
 
-rawImfileRow *rawImfileRowAlloc(const char *exp_tag, const char *class_id, const char *uri, const char *exp_type, const char *filelevel, const char *filter, psF32 airmass, psF64 ra, psF64 decl, psF32 exp_time, psF32 sat_pixel_frac, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 alt, psF64 az, psF32 ccd_temp, psF64 posang, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *object, psTime* dateobs, psS16 fault)
+rawImfileRow *rawImfileRowAlloc(psS64 exp_id, const char *exp_name, const char *camera, const char *telescope, psTime* dateobs, const char *tmp_class_id, const char *class_id, const char *uri, const char *exp_type, const char *filelevel, const char *filter, psF32 airmass, psF64 ra, psF64 decl, psF32 exp_time, psF32 sat_pixel_frac, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 alt, psF64 az, psF32 ccd_temp, psF64 posang, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *object, psS16 fault)
 {
     rawImfileRow    *_object;
@@ -4425,5 +4147,10 @@
     psMemSetDeallocator(_object, (psFreeFunc)rawImfileRowFree);
 
-    _object->exp_tag = psStringCopy(exp_tag);
+    _object->exp_id = exp_id;
+    _object->exp_name = psStringCopy(exp_name);
+    _object->camera = psStringCopy(camera);
+    _object->telescope = psStringCopy(telescope);
+    _object->dateobs = psTimeCopy(dateobs);
+    _object->tmp_class_id = psStringCopy(tmp_class_id);
     _object->class_id = psStringCopy(class_id);
     _object->uri = psStringCopy(uri);
@@ -4449,5 +4176,4 @@
     _object->user_5 = user_5;
     _object->object = psStringCopy(object);
-    _object->dateobs = psTimeCopy(dateobs);
     _object->fault = fault;
 
@@ -4457,5 +4183,9 @@
 static void rawImfileRowFree(rawImfileRow *object)
 {
-    psFree(object->exp_tag);
+    psFree(object->exp_name);
+    psFree(object->camera);
+    psFree(object->telescope);
+    psFree(object->dateobs);
+    psFree(object->tmp_class_id);
     psFree(object->class_id);
     psFree(object->uri);
@@ -4464,5 +4194,4 @@
     psFree(object->filter);
     psFree(object->object);
-    psFree(object->dateobs);
 }
 
@@ -4470,6 +4199,31 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key fkey(exp_id, tmp_class_id) ref newImfile(exp_id, tmp_class_id)", 64)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_name", PS_DATA_STRING, NULL, "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, NULL, "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, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dateobs", PS_DATA_TIME, NULL, NULL)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_class_id", PS_DATA_STRING, "Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_class_id");
         psFree(md);
         return false;
@@ -4590,9 +4344,4 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "dateobs", PS_DATA_TIME, NULL, NULL)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs");
-        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");
@@ -4613,9 +4362,34 @@
 }
 
-bool rawImfileInsert(psDB * dbh, const char *exp_tag, const char *class_id, const char *uri, const char *exp_type, const char *filelevel, const char *filter, psF32 airmass, psF64 ra, psF64 decl, psF32 exp_time, psF32 sat_pixel_frac, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 alt, psF64 az, psF32 ccd_temp, psF64 posang, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *object, psTime* dateobs, psS16 fault)
+bool rawImfileInsert(psDB * dbh, psS64 exp_id, const char *exp_name, const char *camera, const char *telescope, psTime* dateobs, const char *tmp_class_id, const char *class_id, const char *uri, const char *exp_type, const char *filelevel, const char *filter, psF32 airmass, psF64 ra, psF64 decl, psF32 exp_time, psF32 sat_pixel_frac, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 alt, psF64 az, psF32 ccd_temp, psF64 posang, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *object, psS16 fault)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+        psFree(md);
+        return false;
+    }
+    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, "dateobs", PS_DATA_TIME, NULL, dateobs)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_class_id", PS_DATA_STRING, NULL, tmp_class_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_class_id");
         psFree(md);
         return false;
@@ -4733,9 +4507,4 @@
     if (!psMetadataAdd(md, PS_LIST_TAIL, "object", PS_DATA_STRING, NULL, object)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item object");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "dateobs", PS_DATA_TIME, NULL, dateobs)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs");
         psFree(md);
         return false;
@@ -4769,5 +4538,5 @@
 bool rawImfileInsertObject(psDB *dbh, rawImfileRow *object)
 {
-    return rawImfileInsert(dbh, object->exp_tag, object->class_id, object->uri, object->exp_type, object->filelevel, object->filter, object->airmass, object->ra, object->decl, object->exp_time, object->sat_pixel_frac, object->bg, object->bg_stdev, object->bg_mean_stdev, object->alt, object->az, object->ccd_temp, object->posang, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->object, object->dateobs, object->fault);
+    return rawImfileInsert(dbh, object->exp_id, object->exp_name, object->camera, object->telescope, object->dateobs, object->tmp_class_id, object->class_id, object->uri, object->exp_type, object->filelevel, object->filter, object->airmass, object->ra, object->decl, object->exp_time, object->sat_pixel_frac, object->bg, object->bg_stdev, object->bg_mean_stdev, object->alt, object->az, object->ccd_temp, object->posang, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->object, object->fault);
 }
 
@@ -4842,6 +4611,31 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+        psFree(md);
+        return false;
+    }
+    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, "dateobs", PS_DATA_TIME, NULL, object->dateobs)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tmp_class_id", PS_DATA_STRING, NULL, object->tmp_class_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tmp_class_id");
         psFree(md);
         return false;
@@ -4962,9 +4756,4 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "dateobs", PS_DATA_TIME, NULL, object->dateobs)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs");
-        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");
@@ -4981,7 +4770,32 @@
 
 bool status = false;
-    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
+        return 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;
+    }
+    psTime* dateobs = psMetadataLookupPtr(&status, md, "dateobs");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dateobs");
+        return false;
+    }
+    char* tmp_class_id = psMetadataLookupPtr(&status, md, "tmp_class_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tmp_class_id");
         return false;
     }
@@ -5101,9 +4915,4 @@
         return false;
     }
-    psTime* dateobs = psMetadataLookupPtr(&status, md, "dateobs");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dateobs");
-        return false;
-    }
     psS16 fault = psMetadataLookupS16(&status, md, "fault");
     if (!status) {
@@ -5112,5 +4921,5 @@
     }
 
-    return rawImfileRowAlloc(exp_tag, class_id, uri, exp_type, filelevel, filter, airmass, ra, decl, exp_time, sat_pixel_frac, bg, bg_stdev, bg_mean_stdev, alt, az, ccd_temp, posang, user_1, user_2, user_3, user_4, user_5, object, dateobs, fault);
+    return rawImfileRowAlloc(exp_id, exp_name, camera, telescope, dateobs, tmp_class_id, class_id, uri, exp_type, filelevel, filter, airmass, ra, decl, exp_time, sat_pixel_frac, bg, bg_stdev, bg_mean_stdev, alt, az, ccd_temp, posang, user_1, user_2, user_3, user_4, user_5, object, fault);
 }
 psArray *rawImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -5224,5 +5033,5 @@
 static void guidePendingExpRowFree(guidePendingExpRow *object);
 
-guidePendingExpRow *guidePendingExpRowAlloc(psS64 guide_id, const char *exp_tag, const char *recipe)
+guidePendingExpRow *guidePendingExpRowAlloc(psS64 guide_id, psS64 exp_id, const char *recipe)
 {
     guidePendingExpRow *_object;
@@ -5232,5 +5041,5 @@
 
     _object->guide_id = guide_id;
-    _object->exp_tag = psStringCopy(exp_tag);
+    _object->exp_id = exp_id;
     _object->recipe = psStringCopy(recipe);
 
@@ -5240,5 +5049,4 @@
 static void guidePendingExpRowFree(guidePendingExpRow *object)
 {
-    psFree(object->exp_tag);
     psFree(object->recipe);
 }
@@ -5252,6 +5060,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Key", 64)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -5275,5 +5083,5 @@
 }
 
-bool guidePendingExpInsert(psDB * dbh, psS64 guide_id, const char *exp_tag, const char *recipe)
+bool guidePendingExpInsert(psDB * dbh, psS64 guide_id, psS64 exp_id, const char *recipe)
 {
     psMetadata *md = psMetadataAlloc();
@@ -5283,6 +5091,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -5316,5 +5124,5 @@
 bool guidePendingExpInsertObject(psDB *dbh, guidePendingExpRow *object)
 {
-    return guidePendingExpInsert(dbh, object->guide_id, object->exp_tag, object->recipe);
+    return guidePendingExpInsert(dbh, object->guide_id, object->exp_id, object->recipe);
 }
 
@@ -5394,6 +5202,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -5418,7 +5226,7 @@
         return false;
     }
-    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
         return false;
     }
@@ -5429,5 +5237,5 @@
     }
 
-    return guidePendingExpRowAlloc(guide_id, exp_tag, recipe);
+    return guidePendingExpRowAlloc(guide_id, exp_id, recipe);
 }
 psArray *guidePendingExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -5539,17 +5347,17 @@
     return true;
 }
-static void chipPendingExpRowFree(chipPendingExpRow *object);
-
-chipPendingExpRow *chipPendingExpRowAlloc(psS64 chip_id, const char *exp_tag, psS64 guide_id, const char *workdir, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
-{
-    chipPendingExpRow *_object;
-
-    _object = psAlloc(sizeof(chipPendingExpRow));
-    psMemSetDeallocator(_object, (psFreeFunc)chipPendingExpRowFree);
+static void chipRunRowFree(chipRunRow *object);
+
+chipRunRow *chipRunRowAlloc(psS64 chip_id, const char *state, const char *workdir, const char *workdir_state, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
+{
+    chipRunRow      *_object;
+
+    _object = psAlloc(sizeof(chipRunRow));
+    psMemSetDeallocator(_object, (psFreeFunc)chipRunRowFree);
 
     _object->chip_id = chip_id;
-    _object->exp_tag = psStringCopy(exp_tag);
-    _object->guide_id = guide_id;
+    _object->state = psStringCopy(state);
     _object->workdir = psStringCopy(workdir);
+    _object->workdir_state = psStringCopy(workdir_state);
     _object->label = psStringCopy(label);
     _object->reduction = psStringCopy(reduction);
@@ -5560,8 +5368,9 @@
 }
 
-static void chipPendingExpRowFree(chipPendingExpRow *object)
-{
-    psFree(object->exp_tag);
+static void chipRunRowFree(chipRunRow *object)
+{
+    psFree(object->state);
     psFree(object->workdir);
+    psFree(object->workdir_state);
     psFree(object->label);
     psFree(object->reduction);
@@ -5570,5 +5379,5 @@
 }
 
-bool chipPendingExpCreateTable(psDB *dbh)
+bool chipRunCreateTable(psDB *dbh)
 {
     psMetadata *md = psMetadataAlloc();
@@ -5578,11 +5387,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "guide_id", PS_DATA_S64, "Not NULL", 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item guide_id");
+    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;
@@ -5593,4 +5397,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, "key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
+        psFree(md);
+        return false;
+    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, "key", "64")) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item label");
@@ -5614,5 +5423,5 @@
     }
 
-    bool status = psDBCreateTable(dbh, CHIPPENDINGEXP_TABLE_NAME, md);
+    bool status = psDBCreateTable(dbh, CHIPRUN_TABLE_NAME, md);
 
     psFree(md);
@@ -5621,10 +5430,10 @@
 }
 
-bool chipPendingExpDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, CHIPPENDINGEXP_TABLE_NAME);
-}
-
-bool chipPendingExpInsert(psDB * dbh, psS64 chip_id, const char *exp_tag, psS64 guide_id, const char *workdir, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
+bool chipRunDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, CHIPRUN_TABLE_NAME);
+}
+
+bool chipRunInsert(psDB * dbh, psS64 chip_id, const char *state, const char *workdir, const char *workdir_state, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
 {
     psMetadata *md = psMetadataAlloc();
@@ -5634,11 +5443,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "guide_id", PS_DATA_S64, NULL, guide_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item guide_id");
+    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;
@@ -5649,4 +5453,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, NULL, workdir_state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
+        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");
@@ -5670,5 +5479,5 @@
     }
 
-    bool status = psDBInsertOneRow(dbh, CHIPPENDINGEXP_TABLE_NAME, md);
+    bool status = psDBInsertOneRow(dbh, CHIPRUN_TABLE_NAME, md);
     psFree(md);
 
@@ -5676,11 +5485,11 @@
 }
 
-long long chipPendingExpDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+long long chipRunDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     long long       deleted = 0;
 
-    long long count = psDBDeleteRows(dbh, CHIPPENDINGEXP_TABLE_NAME, where, limit);
+    long long count = psDBDeleteRows(dbh, CHIPRUN_TABLE_NAME, where, limit);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipPendingExp");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipRun");
         return count;
 
@@ -5690,13 +5499,13 @@
     return deleted;
 }
-bool chipPendingExpInsertObject(psDB *dbh, chipPendingExpRow *object)
-{
-    return chipPendingExpInsert(dbh, object->chip_id, object->exp_tag, object->guide_id, object->workdir, object->label, object->reduction, object->expgroup, object->dvodb);
-}
-
-bool chipPendingExpInsertObjects(psDB *dbh, psArray *objects)
+bool chipRunInsertObject(psDB *dbh, chipRunRow *object)
+{
+    return chipRunInsert(dbh, object->chip_id, object->state, object->workdir, object->workdir_state, object->label, object->reduction, object->expgroup, object->dvodb);
+}
+
+bool chipRunInsertObjects(psDB *dbh, psArray *objects)
 {
     for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!chipPendingExpInsertObject(dbh, objects->data[i])) {
+        if (!chipRunInsertObject(dbh, objects->data[i])) {
             return false;
         }
@@ -5706,11 +5515,11 @@
 }
 
-bool chipPendingExpInsertFits(psDB *dbh, const psFits *fits)
+bool chipRunInsertFits(psDB *dbh, const psFits *fits)
 {
     psArray         *rowSet;
 
-    // move to (the first?) extension named  CHIPPENDINGEXP_TABLE_NAME
-    if (!psFitsMoveExtName(fits, CHIPPENDINGEXP_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", CHIPPENDINGEXP_TABLE_NAME);
+    // move to (the first?) extension named  CHIPRUN_TABLE_NAME
+    if (!psFitsMoveExtName(fits, CHIPRUN_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", CHIPRUN_TABLE_NAME);
         return false;
     }
@@ -5730,5 +5539,5 @@
     }
 
-    if (!psDBInsertRows(dbh, CHIPPENDINGEXP_TABLE_NAME, rowSet)) {
+    if (!psDBInsertRows(dbh, CHIPRUN_TABLE_NAME, rowSet)) {
         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
         psFree(rowSet);
@@ -5741,9 +5550,9 @@
 }
 
-bool chipPendingExpSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+bool chipRunSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
 
-    rowSet = psDBSelectRows(dbh, CHIPPENDINGEXP_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, CHIPRUN_TABLE_NAME, where, limit);
     if (!rowSet) {
         return false;
@@ -5751,5 +5560,5 @@
 
     // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, CHIPPENDINGEXP_TABLE_NAME)) {
+    if (!psFitsWriteTable(fits, NULL, rowSet, CHIPRUN_TABLE_NAME)) {
         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
         psFree(rowSet);
@@ -5762,5 +5571,5 @@
 }
 
-psMetadata *chipPendingExpMetadataFromObject(const chipPendingExpRow *object)
+psMetadata *chipRunMetadataFromObject(const chipRunRow *object)
 {
     psMetadata *md = psMetadataAlloc();
@@ -5770,11 +5579,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "guide_id", PS_DATA_S64, NULL, object->guide_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item guide_id");
+    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;
@@ -5785,4 +5589,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, NULL, object->workdir_state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
+        psFree(md);
+        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");
@@ -5810,5 +5619,5 @@
 }
 
-chipPendingExpRow *chipPendingExpObjectFromMetadata(psMetadata *md)
+chipRunRow *chipRunObjectFromMetadata(psMetadata *md)
 {
 
@@ -5819,12 +5628,7 @@
         return false;
     }
-    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
-        return false;
-    }
-    psS64 guide_id = psMetadataLookupS64(&status, md, "guide_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item guide_id");
+    char* state = psMetadataLookupPtr(&status, md, "state");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
         return false;
     }
@@ -5834,4 +5638,9 @@
         return false;
     }
+    char* workdir_state = psMetadataLookupPtr(&status, md, "workdir_state");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item workdir_state");
+        return false;
+    }
     char* label = psMetadataLookupPtr(&status, md, "label");
     if (!status) {
@@ -5855,7 +5664,7 @@
     }
 
-    return chipPendingExpRowAlloc(chip_id, exp_tag, guide_id, workdir, label, reduction, expgroup, dvodb);
-}
-psArray *chipPendingExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+    return chipRunRowAlloc(chip_id, state, workdir, workdir_state, label, reduction, expgroup, dvodb);
+}
+psArray *chipRunSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
@@ -5863,5 +5672,5 @@
     psU64           i;
 
-    rowSet = psDBSelectRows(dbh, CHIPPENDINGEXP_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, CHIPRUN_TABLE_NAME, where, limit);
     if (!rowSet) {
         return NULL;
@@ -5873,5 +5682,5 @@
 
     for (i = 0; i < rowSet->n; i++) {
-        chipPendingExpRow *object = chipPendingExpObjectFromMetadata(rowSet->data[i]);
+        chipRunRow *object = chipRunObjectFromMetadata(rowSet->data[i]);
         psArrayAdd(returnSet, 0, object);
         psFree(object);
@@ -5882,11 +5691,11 @@
     return returnSet;
 }
-bool chipPendingExpDeleteObject(psDB *dbh, const chipPendingExpRow *object)
-{
-    psMetadata *where = chipPendingExpMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, CHIPPENDINGEXP_TABLE_NAME, where, 0);
+bool chipRunDeleteObject(psDB *dbh, const chipRunRow *object)
+{
+    psMetadata *where = chipRunMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, CHIPRUN_TABLE_NAME, where, 0);
     psFree(where);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipPendingExp");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipRun");
         return false;
     }
@@ -5894,21 +5703,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, "chipPendingExpRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long chipPendingExpDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+        psError(PS_ERR_UNKNOWN, true, "chipRunRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long chipRunDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
 {
     long long       deleted = 0;
 
     for (long long i = 0; i < objects->n; i++) {
-        chipPendingExpRow *object = objects->data[i];
-        psMetadata *where = chipPendingExpMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, CHIPPENDINGEXP_TABLE_NAME, where, limit);
+        chipRunRow *object = objects->data[i];
+        psMetadata *where = chipRunMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, CHIPRUN_TABLE_NAME, where, limit);
         psFree(where);
         if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipPendingExp");
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipRun");
             return count;
         }
@@ -5919,5 +5728,5 @@
     return deleted;
 }
-bool chipPendingExpPrintObjects(FILE *stream, psArray *objects, bool mdcf)
+bool chipRunPrintObjects(FILE *stream, psArray *objects, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(objects, false);
@@ -5925,9 +5734,9 @@
     psMetadata *output = psMetadataAlloc();
     for (long i = 0; i < psArrayLength(objects); i++) {
-        psMetadata *md = chipPendingExpMetadataFromObject(objects->data[i]);
+        psMetadata *md = chipRunMetadataFromObject(objects->data[i]);
         if (!psMetadataAddMetadata(
             output,
             PS_LIST_TAIL,
-            CHIPPENDINGEXP_TABLE_NAME,
+            CHIPRUN_TABLE_NAME,
             PS_META_DUPLICATE_OK,
             NULL,
@@ -5950,9 +5759,9 @@
     return true;
 }
-bool chipPendingExpPrintObject(FILE *stream, chipPendingExpRow *object, bool mdcf)
+bool chipRunPrintObject(FILE *stream, chipRunRow *object, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(object, false);
 
-    psMetadata *md = chipPendingExpMetadataFromObject(object);
+    psMetadata *md = chipRunMetadataFromObject(object);
 
     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
@@ -5965,31 +5774,35 @@
     return true;
 }
-static void chipPendingImfileRowFree(chipPendingImfileRow *object);
-
-chipPendingImfileRow *chipPendingImfileRowAlloc(psS64 chip_id, const char *class_id, const char *uri)
-{
-    chipPendingImfileRow *_object;
-
-    _object = psAlloc(sizeof(chipPendingImfileRow));
-    psMemSetDeallocator(_object, (psFreeFunc)chipPendingImfileRowFree);
+static void chipInputImfileRowFree(chipInputImfileRow *object);
+
+chipInputImfileRow *chipInputImfileRowAlloc(psS64 chip_id, psS64 exp_id, const char *class_id)
+{
+    chipInputImfileRow *_object;
+
+    _object = psAlloc(sizeof(chipInputImfileRow));
+    psMemSetDeallocator(_object, (psFreeFunc)chipInputImfileRowFree);
 
     _object->chip_id = chip_id;
+    _object->exp_id = exp_id;
     _object->class_id = psStringCopy(class_id);
-    _object->uri = psStringCopy(uri);
 
     return _object;
 }
 
-static void chipPendingImfileRowFree(chipPendingImfileRow *object)
+static void chipInputImfileRowFree(chipInputImfileRow *object)
 {
     psFree(object->class_id);
-    psFree(object->uri);
-}
-
-bool chipPendingImfileCreateTable(psDB *dbh)
+}
+
+bool chipInputImfileCreateTable(psDB *dbh)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Primary Key", 0)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Primary Key fkey (chip_id) ref chipRun(chip_id)", 0)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key fkey (exp_id, class_id) ref rawImfile (exp_id, class_id)", 64)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -6000,11 +5813,6 @@
         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, CHIPPENDINGIMFILE_TABLE_NAME, md);
+
+    bool status = psDBCreateTable(dbh, CHIPINPUTIMFILE_TABLE_NAME, md);
 
     psFree(md);
@@ -6013,10 +5821,10 @@
 }
 
-bool chipPendingImfileDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, CHIPPENDINGIMFILE_TABLE_NAME);
-}
-
-bool chipPendingImfileInsert(psDB * dbh, psS64 chip_id, const char *class_id, const char *uri)
+bool chipInputImfileDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, CHIPINPUTIMFILE_TABLE_NAME);
+}
+
+bool chipInputImfileInsert(psDB * dbh, psS64 chip_id, psS64 exp_id, const char *class_id)
 {
     psMetadata *md = psMetadataAlloc();
@@ -6026,4 +5834,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+        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");
@@ -6031,11 +5844,6 @@
         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, CHIPPENDINGIMFILE_TABLE_NAME, md);
+
+    bool status = psDBInsertOneRow(dbh, CHIPINPUTIMFILE_TABLE_NAME, md);
     psFree(md);
 
@@ -6043,11 +5851,11 @@
 }
 
-long long chipPendingImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+long long chipInputImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     long long       deleted = 0;
 
-    long long count = psDBDeleteRows(dbh, CHIPPENDINGIMFILE_TABLE_NAME, where, limit);
+    long long count = psDBDeleteRows(dbh, CHIPINPUTIMFILE_TABLE_NAME, where, limit);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipPendingImfile");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipInputImfile");
         return count;
 
@@ -6057,13 +5865,13 @@
     return deleted;
 }
-bool chipPendingImfileInsertObject(psDB *dbh, chipPendingImfileRow *object)
-{
-    return chipPendingImfileInsert(dbh, object->chip_id, object->class_id, object->uri);
-}
-
-bool chipPendingImfileInsertObjects(psDB *dbh, psArray *objects)
+bool chipInputImfileInsertObject(psDB *dbh, chipInputImfileRow *object)
+{
+    return chipInputImfileInsert(dbh, object->chip_id, object->exp_id, object->class_id);
+}
+
+bool chipInputImfileInsertObjects(psDB *dbh, psArray *objects)
 {
     for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!chipPendingImfileInsertObject(dbh, objects->data[i])) {
+        if (!chipInputImfileInsertObject(dbh, objects->data[i])) {
             return false;
         }
@@ -6073,11 +5881,11 @@
 }
 
-bool chipPendingImfileInsertFits(psDB *dbh, const psFits *fits)
+bool chipInputImfileInsertFits(psDB *dbh, const psFits *fits)
 {
     psArray         *rowSet;
 
-    // move to (the first?) extension named  CHIPPENDINGIMFILE_TABLE_NAME
-    if (!psFitsMoveExtName(fits, CHIPPENDINGIMFILE_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", CHIPPENDINGIMFILE_TABLE_NAME);
+    // move to (the first?) extension named  CHIPINPUTIMFILE_TABLE_NAME
+    if (!psFitsMoveExtName(fits, CHIPINPUTIMFILE_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", CHIPINPUTIMFILE_TABLE_NAME);
         return false;
     }
@@ -6097,5 +5905,5 @@
     }
 
-    if (!psDBInsertRows(dbh, CHIPPENDINGIMFILE_TABLE_NAME, rowSet)) {
+    if (!psDBInsertRows(dbh, CHIPINPUTIMFILE_TABLE_NAME, rowSet)) {
         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
         psFree(rowSet);
@@ -6108,9 +5916,9 @@
 }
 
-bool chipPendingImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+bool chipInputImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
 
-    rowSet = psDBSelectRows(dbh, CHIPPENDINGIMFILE_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, CHIPINPUTIMFILE_TABLE_NAME, where, limit);
     if (!rowSet) {
         return false;
@@ -6118,5 +5926,5 @@
 
     // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, CHIPPENDINGIMFILE_TABLE_NAME)) {
+    if (!psFitsWriteTable(fits, NULL, rowSet, CHIPINPUTIMFILE_TABLE_NAME)) {
         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
         psFree(rowSet);
@@ -6129,5 +5937,5 @@
 }
 
-psMetadata *chipPendingImfileMetadataFromObject(const chipPendingImfileRow *object)
+psMetadata *chipInputImfileMetadataFromObject(const chipInputImfileRow *object)
 {
     psMetadata *md = psMetadataAlloc();
@@ -6137,4 +5945,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+        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");
@@ -6142,9 +5955,4 @@
         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;
-    }
 
 
@@ -6152,5 +5960,5 @@
 }
 
-chipPendingImfileRow *chipPendingImfileObjectFromMetadata(psMetadata *md)
+chipInputImfileRow *chipInputImfileObjectFromMetadata(psMetadata *md)
 {
 
@@ -6161,4 +5969,9 @@
         return false;
     }
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
+        return false;
+    }
     char* class_id = psMetadataLookupPtr(&status, md, "class_id");
     if (!status) {
@@ -6166,13 +5979,8 @@
         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 chipPendingImfileRowAlloc(chip_id, class_id, uri);
-}
-psArray *chipPendingImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+
+    return chipInputImfileRowAlloc(chip_id, exp_id, class_id);
+}
+psArray *chipInputImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
@@ -6180,5 +5988,5 @@
     psU64           i;
 
-    rowSet = psDBSelectRows(dbh, CHIPPENDINGIMFILE_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, CHIPINPUTIMFILE_TABLE_NAME, where, limit);
     if (!rowSet) {
         return NULL;
@@ -6190,5 +5998,5 @@
 
     for (i = 0; i < rowSet->n; i++) {
-        chipPendingImfileRow *object = chipPendingImfileObjectFromMetadata(rowSet->data[i]);
+        chipInputImfileRow *object = chipInputImfileObjectFromMetadata(rowSet->data[i]);
         psArrayAdd(returnSet, 0, object);
         psFree(object);
@@ -6199,11 +6007,11 @@
     return returnSet;
 }
-bool chipPendingImfileDeleteObject(psDB *dbh, const chipPendingImfileRow *object)
-{
-    psMetadata *where = chipPendingImfileMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, CHIPPENDINGIMFILE_TABLE_NAME, where, 0);
+bool chipInputImfileDeleteObject(psDB *dbh, const chipInputImfileRow *object)
+{
+    psMetadata *where = chipInputImfileMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, CHIPINPUTIMFILE_TABLE_NAME, where, 0);
     psFree(where);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipPendingImfile");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipInputImfile");
         return false;
     }
@@ -6211,21 +6019,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, "chipPendingImfileRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long chipPendingImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+        psError(PS_ERR_UNKNOWN, true, "chipInputImfileRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long chipInputImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
 {
     long long       deleted = 0;
 
     for (long long i = 0; i < objects->n; i++) {
-        chipPendingImfileRow *object = objects->data[i];
-        psMetadata *where = chipPendingImfileMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, CHIPPENDINGIMFILE_TABLE_NAME, where, limit);
+        chipInputImfileRow *object = objects->data[i];
+        psMetadata *where = chipInputImfileMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, CHIPINPUTIMFILE_TABLE_NAME, where, limit);
         psFree(where);
         if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipPendingImfile");
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipInputImfile");
             return count;
         }
@@ -6236,5 +6044,5 @@
     return deleted;
 }
-bool chipPendingImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
+bool chipInputImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(objects, false);
@@ -6242,9 +6050,9 @@
     psMetadata *output = psMetadataAlloc();
     for (long i = 0; i < psArrayLength(objects); i++) {
-        psMetadata *md = chipPendingImfileMetadataFromObject(objects->data[i]);
+        psMetadata *md = chipInputImfileMetadataFromObject(objects->data[i]);
         if (!psMetadataAddMetadata(
             output,
             PS_LIST_TAIL,
-            CHIPPENDINGIMFILE_TABLE_NAME,
+            CHIPINPUTIMFILE_TABLE_NAME,
             PS_META_DUPLICATE_OK,
             NULL,
@@ -6267,9 +6075,9 @@
     return true;
 }
-bool chipPendingImfilePrintObject(FILE *stream, chipPendingImfileRow *object, bool mdcf)
+bool chipInputImfilePrintObject(FILE *stream, chipInputImfileRow *object, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(object, false);
 
-    psMetadata *md = chipPendingImfileMetadataFromObject(object);
+    psMetadata *md = chipInputImfileMetadataFromObject(object);
 
     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
@@ -6282,707 +6090,7 @@
     return true;
 }
-static void chipProcessedExpRowFree(chipProcessedExpRow *object);
-
-chipProcessedExpRow *chipProcessedExpRowAlloc(psS64 chip_id, const char *exp_tag, psS64 guide_id, const char *workdir, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
-{
-    chipProcessedExpRow *_object;
-
-    _object = psAlloc(sizeof(chipProcessedExpRow));
-    psMemSetDeallocator(_object, (psFreeFunc)chipProcessedExpRowFree);
-
-    _object->chip_id = chip_id;
-    _object->exp_tag = psStringCopy(exp_tag);
-    _object->guide_id = guide_id;
-    _object->workdir = psStringCopy(workdir);
-    _object->label = psStringCopy(label);
-    _object->reduction = psStringCopy(reduction);
-    _object->expgroup = psStringCopy(expgroup);
-    _object->dvodb = psStringCopy(dvodb);
-
-    return _object;
-}
-
-static void chipProcessedExpRowFree(chipProcessedExpRow *object)
-{
-    psFree(object->exp_tag);
-    psFree(object->workdir);
-    psFree(object->label);
-    psFree(object->reduction);
-    psFree(object->expgroup);
-    psFree(object->dvodb);
-}
-
-bool chipProcessedExpCreateTable(psDB *dbh)
-{
-    psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Primary Key", 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "guide_id", PS_DATA_S64, "Not NULL", 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item guide_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
-        psFree(md);
-        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;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, "key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item expgroup");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBCreateTable(dbh, CHIPPROCESSEDEXP_TABLE_NAME, md);
-
-    psFree(md);
-
-    return status;
-}
-
-bool chipProcessedExpDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, CHIPPROCESSEDEXP_TABLE_NAME);
-}
-
-bool chipProcessedExpInsert(psDB * dbh, psS64 chip_id, const char *exp_tag, psS64 guide_id, const char *workdir, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
-{
-    psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, NULL, chip_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "guide_id", PS_DATA_S64, NULL, guide_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item guide_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, workdir)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
-        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;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, reduction)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, NULL, expgroup)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item expgroup");
-        psFree(md);
-        return false;
-    }
-    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;
-    }
-
-    bool status = psDBInsertOneRow(dbh, CHIPPROCESSEDEXP_TABLE_NAME, md);
-    psFree(md);
-
-    return status;
-}
-
-long long chipProcessedExpDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
-{
-    long long       deleted = 0;
-
-    long long count = psDBDeleteRows(dbh, CHIPPROCESSEDEXP_TABLE_NAME, where, limit);
-    if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipProcessedExp");
-        return count;
-
-        deleted += count;
-    }
-
-    return deleted;
-}
-bool chipProcessedExpInsertObject(psDB *dbh, chipProcessedExpRow *object)
-{
-    return chipProcessedExpInsert(dbh, object->chip_id, object->exp_tag, object->guide_id, object->workdir, object->label, object->reduction, object->expgroup, object->dvodb);
-}
-
-bool chipProcessedExpInsertObjects(psDB *dbh, psArray *objects)
-{
-    for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!chipProcessedExpInsertObject(dbh, objects->data[i])) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool chipProcessedExpInsertFits(psDB *dbh, const psFits *fits)
-{
-    psArray         *rowSet;
-
-    // move to (the first?) extension named  CHIPPROCESSEDEXP_TABLE_NAME
-    if (!psFitsMoveExtName(fits, CHIPPROCESSEDEXP_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", CHIPPROCESSEDEXP_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, CHIPPROCESSEDEXP_TABLE_NAME, rowSet)) {
-        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
-        psFree(rowSet);
-        return false;
-    }
-
-    psFree(rowSet);
-
-    return true;
-}
-
-bool chipProcessedExpSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
-{
-    psArray         *rowSet;
-
-    rowSet = psDBSelectRows(dbh, CHIPPROCESSEDEXP_TABLE_NAME, where, limit);
-    if (!rowSet) {
-        return false;
-    }
-
-    // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, CHIPPROCESSEDEXP_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
-        psFree(rowSet);
-        return false;
-    }
-
-    psFree(rowSet);
-
-    return true;
-}
-
-psMetadata *chipProcessedExpMetadataFromObject(const chipProcessedExpRow *object)
-{
-    psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, NULL, object->chip_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "guide_id", PS_DATA_S64, NULL, object->guide_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item guide_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, object->workdir)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
-        psFree(md);
-        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;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, object->reduction)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, NULL, object->expgroup)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item expgroup");
-        psFree(md);
-        return false;
-    }
-    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;
-    }
-
-
-    return md;
-}
-
-chipProcessedExpRow *chipProcessedExpObjectFromMetadata(psMetadata *md)
-{
-
-bool status = false;
-    psS64 chip_id = psMetadataLookupS64(&status, md, "chip_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item chip_id");
-        return false;
-    }
-    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
-        return false;
-    }
-    psS64 guide_id = psMetadataLookupS64(&status, md, "guide_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item guide_id");
-        return false;
-    }
-    char* workdir = psMetadataLookupPtr(&status, md, "workdir");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item workdir");
-        return false;
-    }
-    char* label = psMetadataLookupPtr(&status, md, "label");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item label");
-        return false;
-    }
-    char* reduction = psMetadataLookupPtr(&status, md, "reduction");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item reduction");
-        return false;
-    }
-    char* expgroup = psMetadataLookupPtr(&status, md, "expgroup");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item expgroup");
-        return false;
-    }
-    char* dvodb = psMetadataLookupPtr(&status, md, "dvodb");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dvodb");
-        return false;
-    }
-
-    return chipProcessedExpRowAlloc(chip_id, exp_tag, guide_id, workdir, label, reduction, expgroup, dvodb);
-}
-psArray *chipProcessedExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
-{
-    psArray         *rowSet;
-    psArray         *returnSet;
-    psU64           i;
-
-    rowSet = psDBSelectRows(dbh, CHIPPROCESSEDEXP_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++) {
-        chipProcessedExpRow *object = chipProcessedExpObjectFromMetadata(rowSet->data[i]);
-        psArrayAdd(returnSet, 0, object);
-        psFree(object);
-    }
-
-    psFree(rowSet);
-
-    return returnSet;
-}
-bool chipProcessedExpDeleteObject(psDB *dbh, const chipProcessedExpRow *object)
-{
-    psMetadata *where = chipProcessedExpMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, CHIPPROCESSEDEXP_TABLE_NAME, where, 0);
-    psFree(where);
-    if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipProcessedExp");
-        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, "chipProcessedExpRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long chipProcessedExpDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
-{
-    long long       deleted = 0;
-
-    for (long long i = 0; i < objects->n; i++) {
-        chipProcessedExpRow *object = objects->data[i];
-        psMetadata *where = chipProcessedExpMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, CHIPPROCESSEDEXP_TABLE_NAME, where, limit);
-        psFree(where);
-        if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipProcessedExp");
-            return count;
-        }
-
-        deleted += count;
-    }
-
-    return deleted;
-}
-bool chipProcessedExpPrintObjects(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 = chipProcessedExpMetadataFromObject(objects->data[i]);
-        if (!psMetadataAddMetadata(
-            output,
-            PS_LIST_TAIL,
-            CHIPPROCESSEDEXP_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 chipProcessedExpPrintObject(FILE *stream, chipProcessedExpRow *object, bool mdcf)
-{
-    PS_ASSERT_PTR_NON_NULL(object, false);
-
-    psMetadata *md = chipProcessedExpMetadataFromObject(object);
-
-    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
-        psFree(md);
-    }
-
-    psFree(md);
-
-    return true;
-}
-static void chipMaskRowFree(chipMaskRow *object);
-
-chipMaskRow *chipMaskRowAlloc(const char *label)
-{
-    chipMaskRow     *_object;
-
-    _object = psAlloc(sizeof(chipMaskRow));
-    psMemSetDeallocator(_object, (psFreeFunc)chipMaskRowFree);
-
-    _object->label = psStringCopy(label);
-
-    return _object;
-}
-
-static void chipMaskRowFree(chipMaskRow *object)
-{
-    psFree(object->label);
-}
-
-bool chipMaskCreateTable(psDB *dbh)
-{
-    psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item label");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBCreateTable(dbh, CHIPMASK_TABLE_NAME, md);
-
-    psFree(md);
-
-    return status;
-}
-
-bool chipMaskDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, CHIPMASK_TABLE_NAME);
-}
-
-bool chipMaskInsert(psDB * dbh, const char *label)
-{
-    psMetadata *md = psMetadataAlloc();
-    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;
-    }
-
-    bool status = psDBInsertOneRow(dbh, CHIPMASK_TABLE_NAME, md);
-    psFree(md);
-
-    return status;
-}
-
-long long chipMaskDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
-{
-    long long       deleted = 0;
-
-    long long count = psDBDeleteRows(dbh, CHIPMASK_TABLE_NAME, where, limit);
-    if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipMask");
-        return count;
-
-        deleted += count;
-    }
-
-    return deleted;
-}
-bool chipMaskInsertObject(psDB *dbh, chipMaskRow *object)
-{
-    return chipMaskInsert(dbh, object->label);
-}
-
-bool chipMaskInsertObjects(psDB *dbh, psArray *objects)
-{
-    for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!chipMaskInsertObject(dbh, objects->data[i])) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool chipMaskInsertFits(psDB *dbh, const psFits *fits)
-{
-    psArray         *rowSet;
-
-    // move to (the first?) extension named  CHIPMASK_TABLE_NAME
-    if (!psFitsMoveExtName(fits, CHIPMASK_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", CHIPMASK_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, CHIPMASK_TABLE_NAME, rowSet)) {
-        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
-        psFree(rowSet);
-        return false;
-    }
-
-    psFree(rowSet);
-
-    return true;
-}
-
-bool chipMaskSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
-{
-    psArray         *rowSet;
-
-    rowSet = psDBSelectRows(dbh, CHIPMASK_TABLE_NAME, where, limit);
-    if (!rowSet) {
-        return false;
-    }
-
-    // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, CHIPMASK_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
-        psFree(rowSet);
-        return false;
-    }
-
-    psFree(rowSet);
-
-    return true;
-}
-
-psMetadata *chipMaskMetadataFromObject(const chipMaskRow *object)
-{
-    psMetadata *md = psMetadataAlloc();
-    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;
-    }
-
-
-    return md;
-}
-
-chipMaskRow *chipMaskObjectFromMetadata(psMetadata *md)
-{
-
-bool status = false;
-    char* label = psMetadataLookupPtr(&status, md, "label");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item label");
-        return false;
-    }
-
-    return chipMaskRowAlloc(label);
-}
-psArray *chipMaskSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
-{
-    psArray         *rowSet;
-    psArray         *returnSet;
-    psU64           i;
-
-    rowSet = psDBSelectRows(dbh, CHIPMASK_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++) {
-        chipMaskRow *object = chipMaskObjectFromMetadata(rowSet->data[i]);
-        psArrayAdd(returnSet, 0, object);
-        psFree(object);
-    }
-
-    psFree(rowSet);
-
-    return returnSet;
-}
-bool chipMaskDeleteObject(psDB *dbh, const chipMaskRow *object)
-{
-    psMetadata *where = chipMaskMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, CHIPMASK_TABLE_NAME, where, 0);
-    psFree(where);
-    if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipMask");
-        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, "chipMaskRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long chipMaskDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
-{
-    long long       deleted = 0;
-
-    for (long long i = 0; i < objects->n; i++) {
-        chipMaskRow *object = objects->data[i];
-        psMetadata *where = chipMaskMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, CHIPMASK_TABLE_NAME, where, limit);
-        psFree(where);
-        if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipMask");
-            return count;
-        }
-
-        deleted += count;
-    }
-
-    return deleted;
-}
-bool chipMaskPrintObjects(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 = chipMaskMetadataFromObject(objects->data[i]);
-        if (!psMetadataAddMetadata(
-            output,
-            PS_LIST_TAIL,
-            CHIPMASK_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 chipMaskPrintObject(FILE *stream, chipMaskRow *object, bool mdcf)
-{
-    PS_ASSERT_PTR_NON_NULL(object, false);
-
-    psMetadata *md = chipMaskMetadataFromObject(object);
-
-    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
-        psFree(md);
-    }
-
-    psFree(md);
-
-    return true;
-}
 static void chipProcessedImfileRowFree(chipProcessedImfileRow *object);
 
-chipProcessedImfileRow *chipProcessedImfileRowAlloc(psS64 chip_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 fwhm, psF32 fwhm_range, psS32 n_stars, psS32 n_extended, psS32 n_cr, psS32 n_astrom, const char *path_base, psS16 fault)
 {
     chipProcessedImfileRow *_object;
@@ -6992,4 +6100,5 @@
 
     _object->chip_id = chip_id;
+    _object->exp_id = exp_id;
     _object->class_id = psStringCopy(class_id);
     _object->uri = psStringCopy(uri);
@@ -7028,6 +6137,11 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Primary Key", 0)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Primary Key fkey (chip_id, exp_id, class_id) ref chipInputImfile(chip_id, exp_id, class_id)", 0)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key", 64)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -7156,9 +6270,14 @@
 }
 
-bool chipProcessedImfileInsert(psDB * dbh, psS64 chip_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 fwhm, psF32 fwhm_range, psS32 n_stars, psS32 n_extended, psS32 n_cr, psS32 n_astrom, const char *path_base, psS16 fault)
 {
     psMetadata *md = psMetadataAlloc();
     if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, NULL, chip_id)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -7297,5 +6416,5 @@
 bool chipProcessedImfileInsertObject(psDB *dbh, chipProcessedImfileRow *object)
 {
-    return chipProcessedImfileInsert(dbh, object->chip_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->fwhm, object->fwhm_range, object->n_stars, object->n_extended, object->n_cr, object->n_astrom, object->path_base, object->fault);
 }
 
@@ -7375,4 +6494,9 @@
         return false;
     }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+        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");
@@ -7499,4 +6623,9 @@
         return false;
     }
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
+        return false;
+    }
     char* class_id = psMetadataLookupPtr(&status, md, "class_id");
     if (!status) {
@@ -7610,5 +6739,5 @@
     }
 
-    return chipProcessedImfileRowAlloc(chip_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, fwhm, fwhm_range, n_stars, n_extended, n_cr, n_astrom, path_base, fault);
 }
 psArray *chipProcessedImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -7720,73 +6849,33 @@
     return true;
 }
-static void camPendingExpRowFree(camPendingExpRow *object);
-
-camPendingExpRow *camPendingExpRowAlloc(psS64 cam_id, psS64 chip_id, const char *workdir, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
-{
-    camPendingExpRow *_object;
-
-    _object = psAlloc(sizeof(camPendingExpRow));
-    psMemSetDeallocator(_object, (psFreeFunc)camPendingExpRowFree);
-
-    _object->cam_id = cam_id;
-    _object->chip_id = chip_id;
-    _object->workdir = psStringCopy(workdir);
+static void chipMaskRowFree(chipMaskRow *object);
+
+chipMaskRow *chipMaskRowAlloc(const char *label)
+{
+    chipMaskRow     *_object;
+
+    _object = psAlloc(sizeof(chipMaskRow));
+    psMemSetDeallocator(_object, (psFreeFunc)chipMaskRowFree);
+
     _object->label = psStringCopy(label);
-    _object->reduction = psStringCopy(reduction);
-    _object->expgroup = psStringCopy(expgroup);
-    _object->dvodb = psStringCopy(dvodb);
 
     return _object;
 }
 
-static void camPendingExpRowFree(camPendingExpRow *object)
-{
-    psFree(object->workdir);
+static void chipMaskRowFree(chipMaskRow *object)
+{
     psFree(object->label);
-    psFree(object->reduction);
-    psFree(object->expgroup);
-    psFree(object->dvodb);
-}
-
-bool camPendingExpCreateTable(psDB *dbh)
+}
+
+bool chipMaskCreateTable(psDB *dbh)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "cam_id", PS_DATA_S64, "Primary Key AUTO_INCREMENT", 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item cam_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Primary Key fkey(chip_id) ref chipProcessedExp(chip_id)", 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, "key", "64")) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "label", PS_DATA_STRING, "Primary Key", "64")) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item label");
         psFree(md);
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, "key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item expgroup");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBCreateTable(dbh, CAMPENDINGEXP_TABLE_NAME, md);
+
+    bool status = psDBCreateTable(dbh, CHIPMASK_TABLE_NAME, md);
 
     psFree(md);
@@ -7795,27 +6884,12 @@
 }
 
-bool camPendingExpDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, CAMPENDINGEXP_TABLE_NAME);
-}
-
-bool camPendingExpInsert(psDB * dbh, psS64 cam_id, psS64 chip_id, const char *workdir, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
+bool chipMaskDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, CHIPMASK_TABLE_NAME);
+}
+
+bool chipMaskInsert(psDB * dbh, const char *label)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "cam_id", PS_DATA_S64, NULL, cam_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item cam_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, NULL, chip_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, workdir)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
-        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");
@@ -7823,21 +6897,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, reduction)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, NULL, expgroup)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item expgroup");
-        psFree(md);
-        return false;
-    }
-    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;
-    }
-
-    bool status = psDBInsertOneRow(dbh, CAMPENDINGEXP_TABLE_NAME, md);
+
+    bool status = psDBInsertOneRow(dbh, CHIPMASK_TABLE_NAME, md);
     psFree(md);
 
@@ -7845,11 +6904,11 @@
 }
 
-long long camPendingExpDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+long long chipMaskDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     long long       deleted = 0;
 
-    long long count = psDBDeleteRows(dbh, CAMPENDINGEXP_TABLE_NAME, where, limit);
+    long long count = psDBDeleteRows(dbh, CHIPMASK_TABLE_NAME, where, limit);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from camPendingExp");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipMask");
         return count;
 
@@ -7859,13 +6918,13 @@
     return deleted;
 }
-bool camPendingExpInsertObject(psDB *dbh, camPendingExpRow *object)
-{
-    return camPendingExpInsert(dbh, object->cam_id, object->chip_id, object->workdir, object->label, object->reduction, object->expgroup, object->dvodb);
-}
-
-bool camPendingExpInsertObjects(psDB *dbh, psArray *objects)
+bool chipMaskInsertObject(psDB *dbh, chipMaskRow *object)
+{
+    return chipMaskInsert(dbh, object->label);
+}
+
+bool chipMaskInsertObjects(psDB *dbh, psArray *objects)
 {
     for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!camPendingExpInsertObject(dbh, objects->data[i])) {
+        if (!chipMaskInsertObject(dbh, objects->data[i])) {
             return false;
         }
@@ -7875,11 +6934,11 @@
 }
 
-bool camPendingExpInsertFits(psDB *dbh, const psFits *fits)
+bool chipMaskInsertFits(psDB *dbh, const psFits *fits)
 {
     psArray         *rowSet;
 
-    // move to (the first?) extension named  CAMPENDINGEXP_TABLE_NAME
-    if (!psFitsMoveExtName(fits, CAMPENDINGEXP_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", CAMPENDINGEXP_TABLE_NAME);
+    // move to (the first?) extension named  CHIPMASK_TABLE_NAME
+    if (!psFitsMoveExtName(fits, CHIPMASK_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", CHIPMASK_TABLE_NAME);
         return false;
     }
@@ -7899,5 +6958,5 @@
     }
 
-    if (!psDBInsertRows(dbh, CAMPENDINGEXP_TABLE_NAME, rowSet)) {
+    if (!psDBInsertRows(dbh, CHIPMASK_TABLE_NAME, rowSet)) {
         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
         psFree(rowSet);
@@ -7910,9 +6969,9 @@
 }
 
-bool camPendingExpSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+bool chipMaskSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
 
-    rowSet = psDBSelectRows(dbh, CAMPENDINGEXP_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, CHIPMASK_TABLE_NAME, where, limit);
     if (!rowSet) {
         return false;
@@ -7920,5 +6979,5 @@
 
     // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, CAMPENDINGEXP_TABLE_NAME)) {
+    if (!psFitsWriteTable(fits, NULL, rowSet, CHIPMASK_TABLE_NAME)) {
         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
         psFree(rowSet);
@@ -7931,22 +6990,7 @@
 }
 
-psMetadata *camPendingExpMetadataFromObject(const camPendingExpRow *object)
+psMetadata *chipMaskMetadataFromObject(const chipMaskRow *object)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "cam_id", PS_DATA_S64, NULL, object->cam_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item cam_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, NULL, object->chip_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, object->workdir)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
-        psFree(md);
-        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");
@@ -7954,19 +6998,4 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, object->reduction)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, NULL, object->expgroup)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item expgroup");
-        psFree(md);
-        return false;
-    }
-    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;
-    }
 
 
@@ -7974,23 +7003,8 @@
 }
 
-camPendingExpRow *camPendingExpObjectFromMetadata(psMetadata *md)
+chipMaskRow *chipMaskObjectFromMetadata(psMetadata *md)
 {
 
 bool status = false;
-    psS64 cam_id = psMetadataLookupS64(&status, md, "cam_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item cam_id");
-        return false;
-    }
-    psS64 chip_id = psMetadataLookupS64(&status, md, "chip_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item chip_id");
-        return false;
-    }
-    char* workdir = psMetadataLookupPtr(&status, md, "workdir");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item workdir");
-        return false;
-    }
     char* label = psMetadataLookupPtr(&status, md, "label");
     if (!status) {
@@ -7998,23 +7012,8 @@
         return false;
     }
-    char* reduction = psMetadataLookupPtr(&status, md, "reduction");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item reduction");
-        return false;
-    }
-    char* expgroup = psMetadataLookupPtr(&status, md, "expgroup");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item expgroup");
-        return false;
-    }
-    char* dvodb = psMetadataLookupPtr(&status, md, "dvodb");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dvodb");
-        return false;
-    }
-
-    return camPendingExpRowAlloc(cam_id, chip_id, workdir, label, reduction, expgroup, dvodb);
-}
-psArray *camPendingExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+
+    return chipMaskRowAlloc(label);
+}
+psArray *chipMaskSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
@@ -8022,5 +7021,5 @@
     psU64           i;
 
-    rowSet = psDBSelectRows(dbh, CAMPENDINGEXP_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, CHIPMASK_TABLE_NAME, where, limit);
     if (!rowSet) {
         return NULL;
@@ -8032,5 +7031,5 @@
 
     for (i = 0; i < rowSet->n; i++) {
-        camPendingExpRow *object = camPendingExpObjectFromMetadata(rowSet->data[i]);
+        chipMaskRow *object = chipMaskObjectFromMetadata(rowSet->data[i]);
         psArrayAdd(returnSet, 0, object);
         psFree(object);
@@ -8041,11 +7040,11 @@
     return returnSet;
 }
-bool camPendingExpDeleteObject(psDB *dbh, const camPendingExpRow *object)
-{
-    psMetadata *where = camPendingExpMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, CAMPENDINGEXP_TABLE_NAME, where, 0);
+bool chipMaskDeleteObject(psDB *dbh, const chipMaskRow *object)
+{
+    psMetadata *where = chipMaskMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, CHIPMASK_TABLE_NAME, where, 0);
     psFree(where);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from camPendingExp");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipMask");
         return false;
     }
@@ -8053,21 +7052,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, "camPendingExpRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long camPendingExpDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+        psError(PS_ERR_UNKNOWN, true, "chipMaskRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long chipMaskDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
 {
     long long       deleted = 0;
 
     for (long long i = 0; i < objects->n; i++) {
-        camPendingExpRow *object = objects->data[i];
-        psMetadata *where = camPendingExpMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, CAMPENDINGEXP_TABLE_NAME, where, limit);
+        chipMaskRow *object = objects->data[i];
+        psMetadata *where = chipMaskMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, CHIPMASK_TABLE_NAME, where, limit);
         psFree(where);
         if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from camPendingExp");
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from chipMask");
             return count;
         }
@@ -8078,5 +7077,5 @@
     return deleted;
 }
-bool camPendingExpPrintObjects(FILE *stream, psArray *objects, bool mdcf)
+bool chipMaskPrintObjects(FILE *stream, psArray *objects, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(objects, false);
@@ -8084,9 +7083,9 @@
     psMetadata *output = psMetadataAlloc();
     for (long i = 0; i < psArrayLength(objects); i++) {
-        psMetadata *md = camPendingExpMetadataFromObject(objects->data[i]);
+        psMetadata *md = chipMaskMetadataFromObject(objects->data[i]);
         if (!psMetadataAddMetadata(
             output,
             PS_LIST_TAIL,
-            CAMPENDINGEXP_TABLE_NAME,
+            CHIPMASK_TABLE_NAME,
             PS_META_DUPLICATE_OK,
             NULL,
@@ -8109,9 +7108,9 @@
     return true;
 }
-bool camPendingExpPrintObject(FILE *stream, camPendingExpRow *object, bool mdcf)
+bool chipMaskPrintObject(FILE *stream, chipMaskRow *object, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(object, false);
 
-    psMetadata *md = camPendingExpMetadataFromObject(object);
+    psMetadata *md = chipMaskMetadataFromObject(object);
 
     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
@@ -8124,20 +7123,463 @@
     return true;
 }
-static void camProcessedExpRowFree(camProcessedExpRow *object);
-
-camProcessedExpRow *camProcessedExpRowAlloc(psS64 cam_id, psS64 chip_id, const char *workdir, const char *label, const char *reduction, const char *expgroup, const char *dvodb, 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 *_object;
-
-    _object = psAlloc(sizeof(camProcessedExpRow));
-    psMemSetDeallocator(_object, (psFreeFunc)camProcessedExpRowFree);
+static void camRunRowFree(camRunRow *object);
+
+camRunRow *camRunRowAlloc(psS64 cam_id, psS64 chip_id, const char *state, const char *workdir, const char *workdir_state, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
+{
+    camRunRow       *_object;
+
+    _object = psAlloc(sizeof(camRunRow));
+    psMemSetDeallocator(_object, (psFreeFunc)camRunRowFree);
 
     _object->cam_id = cam_id;
     _object->chip_id = chip_id;
+    _object->state = psStringCopy(state);
     _object->workdir = psStringCopy(workdir);
+    _object->workdir_state = psStringCopy(workdir_state);
     _object->label = psStringCopy(label);
     _object->reduction = psStringCopy(reduction);
     _object->expgroup = psStringCopy(expgroup);
     _object->dvodb = psStringCopy(dvodb);
+
+    return _object;
+}
+
+static void camRunRowFree(camRunRow *object)
+{
+    psFree(object->state);
+    psFree(object->workdir);
+    psFree(object->workdir_state);
+    psFree(object->label);
+    psFree(object->reduction);
+    psFree(object->expgroup);
+    psFree(object->dvodb);
+}
+
+bool camRunCreateTable(psDB *dbh)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "cam_id", PS_DATA_S64, "Primary Key AUTO_INCREMENT", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item cam_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Primary Key fkey(chip_id) ref chipRun(chip_id)", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
+        psFree(md);
+        return false;
+    }
+    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;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, "255")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, "key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
+        psFree(md);
+        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;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, "key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item expgroup");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, "255")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, CAMRUN_TABLE_NAME, md);
+
+    psFree(md);
+
+    return status;
+}
+
+bool camRunDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, CAMRUN_TABLE_NAME);
+}
+
+bool camRunInsert(psDB * dbh, psS64 cam_id, psS64 chip_id, const char *state, const char *workdir, const char *workdir_state, const char *label, const char *reduction, const char *expgroup, const char *dvodb)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "cam_id", PS_DATA_S64, NULL, cam_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item cam_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, NULL, chip_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_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, "workdir", PS_DATA_STRING, NULL, workdir)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, NULL, workdir_state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
+        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;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, reduction)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, NULL, expgroup)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item expgroup");
+        psFree(md);
+        return false;
+    }
+    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;
+    }
+
+    bool status = psDBInsertOneRow(dbh, CAMRUN_TABLE_NAME, md);
+    psFree(md);
+
+    return status;
+}
+
+long long camRunDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    long long count = psDBDeleteRows(dbh, CAMRUN_TABLE_NAME, where, limit);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from camRun");
+        return count;
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool camRunInsertObject(psDB *dbh, camRunRow *object)
+{
+    return camRunInsert(dbh, object->cam_id, object->chip_id, object->state, object->workdir, object->workdir_state, object->label, object->reduction, object->expgroup, object->dvodb);
+}
+
+bool camRunInsertObjects(psDB *dbh, psArray *objects)
+{
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        if (!camRunInsertObject(dbh, objects->data[i])) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool camRunInsertFits(psDB *dbh, const psFits *fits)
+{
+    psArray         *rowSet;
+
+    // move to (the first?) extension named  CAMRUN_TABLE_NAME
+    if (!psFitsMoveExtName(fits, CAMRUN_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", CAMRUN_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, CAMRUN_TABLE_NAME, rowSet)) {
+        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+bool camRunSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+
+    rowSet = psDBSelectRows(dbh, CAMRUN_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return false;
+    }
+
+    // output to fits
+    if (!psFitsWriteTable(fits, NULL, rowSet, CAMRUN_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+psMetadata *camRunMetadataFromObject(const camRunRow *object)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "cam_id", PS_DATA_S64, NULL, object->cam_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item cam_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, NULL, object->chip_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item chip_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, "workdir", PS_DATA_STRING, NULL, object->workdir)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir_state", PS_DATA_STRING, NULL, object->workdir_state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir_state");
+        psFree(md);
+        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;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, object->reduction)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, NULL, object->expgroup)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item expgroup");
+        psFree(md);
+        return false;
+    }
+    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;
+    }
+
+
+    return md;
+}
+
+camRunRow *camRunObjectFromMetadata(psMetadata *md)
+{
+
+bool status = false;
+    psS64 cam_id = psMetadataLookupS64(&status, md, "cam_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item cam_id");
+        return false;
+    }
+    psS64 chip_id = psMetadataLookupS64(&status, md, "chip_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item chip_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* workdir = psMetadataLookupPtr(&status, md, "workdir");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item workdir");
+        return false;
+    }
+    char* workdir_state = psMetadataLookupPtr(&status, md, "workdir_state");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item workdir_state");
+        return false;
+    }
+    char* label = psMetadataLookupPtr(&status, md, "label");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item label");
+        return false;
+    }
+    char* reduction = psMetadataLookupPtr(&status, md, "reduction");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item reduction");
+        return false;
+    }
+    char* expgroup = psMetadataLookupPtr(&status, md, "expgroup");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item expgroup");
+        return false;
+    }
+    char* dvodb = psMetadataLookupPtr(&status, md, "dvodb");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dvodb");
+        return false;
+    }
+
+    return camRunRowAlloc(cam_id, chip_id, state, workdir, workdir_state, label, reduction, expgroup, dvodb);
+}
+psArray *camRunSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+    psArray         *returnSet;
+    psU64           i;
+
+    rowSet = psDBSelectRows(dbh, CAMRUN_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++) {
+        camRunRow *object = camRunObjectFromMetadata(rowSet->data[i]);
+        psArrayAdd(returnSet, 0, object);
+        psFree(object);
+    }
+
+    psFree(rowSet);
+
+    return returnSet;
+}
+bool camRunDeleteObject(psDB *dbh, const camRunRow *object)
+{
+    psMetadata *where = camRunMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, CAMRUN_TABLE_NAME, where, 0);
+    psFree(where);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from camRun");
+        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, "camRunRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long camRunDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    for (long long i = 0; i < objects->n; i++) {
+        camRunRow *object = objects->data[i];
+        psMetadata *where = camRunMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, CAMRUN_TABLE_NAME, where, limit);
+        psFree(where);
+        if (count < 0) {
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from camRun");
+            return count;
+        }
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool camRunPrintObjects(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 = camRunMetadataFromObject(objects->data[i]);
+        if (!psMetadataAddMetadata(
+            output,
+            PS_LIST_TAIL,
+            CAMRUN_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 camRunPrintObject(FILE *stream, camRunRow *object, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(object, false);
+
+    psMetadata *md = camRunMetadataFromObject(object);
+
+    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(md);
+    }
+
+    psFree(md);
+
+    return true;
+}
+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 *_object;
+
+    _object = psAlloc(sizeof(camProcessedExpRow));
+    psMemSetDeallocator(_object, (psFreeFunc)camProcessedExpRowFree);
+
+    _object->cam_id = cam_id;
+    _object->chip_id = chip_id;
     _object->uri = psStringCopy(uri);
     _object->bg = bg;
@@ -8162,9 +7604,4 @@
 static void camProcessedExpRowFree(camProcessedExpRow *object)
 {
-    psFree(object->workdir);
-    psFree(object->label);
-    psFree(object->reduction);
-    psFree(object->expgroup);
-    psFree(object->dvodb);
     psFree(object->uri);
     psFree(object->path_base);
@@ -8179,31 +7616,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Primary Key fkey(chip_id) ref chipProcessedExp(chip_id)", 0)) {
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, "Primary Key fkey(cam_id, chip_id) ref camRun(cam_id, chip_id)", 0)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
-        psFree(md);
-        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;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, "key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item expgroup");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "dvodb", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item dvodb");
         psFree(md);
         return false;
@@ -8302,5 +7714,5 @@
 }
 
-bool camProcessedExpInsert(psDB * dbh, psS64 cam_id, psS64 chip_id, const char *workdir, const char *label, const char *reduction, const char *expgroup, const char *dvodb, 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 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)
 {
     psMetadata *md = psMetadataAlloc();
@@ -8312,29 +7724,4 @@
     if (!psMetadataAdd(md, PS_LIST_TAIL, "chip_id", PS_DATA_S64, NULL, chip_id)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item chip_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, workdir)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
-        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;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, reduction)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, NULL, expgroup)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item expgroup");
-        psFree(md);
-        return false;
-    }
-    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;
@@ -8443,5 +7830,5 @@
 bool camProcessedExpInsertObject(psDB *dbh, camProcessedExpRow *object)
 {
-    return camProcessedExpInsert(dbh, object->cam_id, object->chip_id, object->workdir, object->label, object->reduction, object->expgroup, object->dvodb, 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->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);
 }
 
@@ -8526,29 +7913,4 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, object->workdir)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
-        psFree(md);
-        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;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "reduction", PS_DATA_STRING, NULL, object->reduction)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item reduction");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "expgroup", PS_DATA_STRING, NULL, object->expgroup)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item expgroup");
-        psFree(md);
-        return false;
-    }
-    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;
-    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
@@ -8650,29 +8012,4 @@
         return false;
     }
-    char* workdir = psMetadataLookupPtr(&status, md, "workdir");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item workdir");
-        return false;
-    }
-    char* label = psMetadataLookupPtr(&status, md, "label");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item label");
-        return false;
-    }
-    char* reduction = psMetadataLookupPtr(&status, md, "reduction");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item reduction");
-        return false;
-    }
-    char* expgroup = psMetadataLookupPtr(&status, md, "expgroup");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item expgroup");
-        return false;
-    }
-    char* dvodb = psMetadataLookupPtr(&status, md, "dvodb");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item dvodb");
-        return false;
-    }
     char* uri = psMetadataLookupPtr(&status, md, "uri");
     if (!status) {
@@ -8756,5 +8093,5 @@
     }
 
-    return camProcessedExpRowAlloc(cam_id, chip_id, workdir, label, reduction, expgroup, dvodb, 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, sigma_ra, sigma_dec, zp_mean, zp_stdev, fwhm, fwhm_range, n_stars, n_extended, n_cr, n_astrom, path_base, fault);
 }
 psArray *camProcessedExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -13704,5 +13041,5 @@
 static void detInputExpRowFree(detInputExpRow *object);
 
-detInputExpRow *detInputExpRowAlloc(psS64 det_id, psS32 iteration, const char *exp_tag, bool include)
+detInputExpRow *detInputExpRowAlloc(psS64 det_id, psS32 iteration, psS64 exp_id, bool include)
 {
     detInputExpRow  *_object;
@@ -13713,5 +13050,5 @@
     _object->det_id = det_id;
     _object->iteration = iteration;
-    _object->exp_tag = psStringCopy(exp_tag);
+    _object->exp_id = exp_id;
     _object->include = include;
 
@@ -13721,5 +13058,4 @@
 static void detInputExpRowFree(detInputExpRow *object)
 {
-    psFree(object->exp_tag);
 }
 
@@ -13737,6 +13073,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key", 64)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -13760,5 +13096,5 @@
 }
 
-bool detInputExpInsert(psDB * dbh, psS64 det_id, psS32 iteration, const char *exp_tag, bool include)
+bool detInputExpInsert(psDB * dbh, psS64 det_id, psS32 iteration, psS64 exp_id, bool include)
 {
     psMetadata *md = psMetadataAlloc();
@@ -13773,6 +13109,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -13806,5 +13142,5 @@
 bool detInputExpInsertObject(psDB *dbh, detInputExpRow *object)
 {
-    return detInputExpInsert(dbh, object->det_id, object->iteration, object->exp_tag, object->include);
+    return detInputExpInsert(dbh, object->det_id, object->iteration, object->exp_id, object->include);
 }
 
@@ -13889,6 +13225,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -13918,7 +13254,7 @@
         return false;
     }
-    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
         return false;
     }
@@ -13929,5 +13265,5 @@
     }
 
-    return detInputExpRowAlloc(det_id, iteration, exp_tag, include);
+    return detInputExpRowAlloc(det_id, iteration, exp_id, include);
 }
 psArray *detInputExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -14041,5 +13377,5 @@
 static void detProcessedImfileRowFree(detProcessedImfileRow *object);
 
-detProcessedImfileRow *detProcessedImfileRowAlloc(psS64 det_id, const char *exp_tag, const char *class_id, const char *uri, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
+detProcessedImfileRow *detProcessedImfileRowAlloc(psS64 det_id, psS64 exp_id, const char *class_id, const char *uri, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
 {
     detProcessedImfileRow *_object;
@@ -14049,5 +13385,5 @@
 
     _object->det_id = det_id;
-    _object->exp_tag = psStringCopy(exp_tag);
+    _object->exp_id = exp_id;
     _object->class_id = psStringCopy(class_id);
     _object->uri = psStringCopy(uri);
@@ -14072,5 +13408,4 @@
 static void detProcessedImfileRowFree(detProcessedImfileRow *object)
 {
-    psFree(object->exp_tag);
     psFree(object->class_id);
     psFree(object->uri);
@@ -14087,6 +13422,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key", 64)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -14185,5 +13520,5 @@
 }
 
-bool detProcessedImfileInsert(psDB * dbh, psS64 det_id, const char *exp_tag, const char *class_id, const char *uri, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
+bool detProcessedImfileInsert(psDB * dbh, psS64 det_id, psS64 exp_id, const char *class_id, const char *uri, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
 {
     psMetadata *md = psMetadataAlloc();
@@ -14193,6 +13528,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -14301,5 +13636,5 @@
 bool detProcessedImfileInsertObject(psDB *dbh, detProcessedImfileRow *object)
 {
-    return detProcessedImfileInsert(dbh, object->det_id, object->exp_tag, object->class_id, object->uri, object->recipe, object->bg, object->bg_stdev, object->bg_mean_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->path_base, object->fault);
+    return detProcessedImfileInsert(dbh, object->det_id, object->exp_id, object->class_id, object->uri, object->recipe, object->bg, object->bg_stdev, object->bg_mean_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->path_base, object->fault);
 }
 
@@ -14379,6 +13714,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -14478,7 +13813,7 @@
         return false;
     }
-    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
         return false;
     }
@@ -14564,5 +13899,5 @@
     }
 
-    return detProcessedImfileRowAlloc(det_id, exp_tag, class_id, uri, recipe, bg, bg_stdev, bg_mean_stdev, fringe_0, fringe_1, fringe_2, user_1, user_2, user_3, user_4, user_5, path_base, fault);
+    return detProcessedImfileRowAlloc(det_id, exp_id, class_id, uri, recipe, bg, bg_stdev, bg_mean_stdev, fringe_0, fringe_1, fringe_2, user_1, user_2, user_3, user_4, user_5, path_base, fault);
 }
 psArray *detProcessedImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -14676,5 +14011,5 @@
 static void detProcessedExpRowFree(detProcessedExpRow *object);
 
-detProcessedExpRow *detProcessedExpRowAlloc(psS64 det_id, const char *exp_tag, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
+detProcessedExpRow *detProcessedExpRowAlloc(psS64 det_id, psS64 exp_id, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
 {
     detProcessedExpRow *_object;
@@ -14684,5 +14019,5 @@
 
     _object->det_id = det_id;
-    _object->exp_tag = psStringCopy(exp_tag);
+    _object->exp_id = exp_id;
     _object->recipe = psStringCopy(recipe);
     _object->bg = bg;
@@ -14705,5 +14040,4 @@
 static void detProcessedExpRowFree(detProcessedExpRow *object)
 {
-    psFree(object->exp_tag);
     psFree(object->recipe);
     psFree(object->path_base);
@@ -14718,6 +14052,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key", 64)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -14806,5 +14140,5 @@
 }
 
-bool detProcessedExpInsert(psDB * dbh, psS64 det_id, const char *exp_tag, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
+bool detProcessedExpInsert(psDB * dbh, psS64 det_id, psS64 exp_id, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
 {
     psMetadata *md = psMetadataAlloc();
@@ -14814,6 +14148,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -14912,5 +14246,5 @@
 bool detProcessedExpInsertObject(psDB *dbh, detProcessedExpRow *object)
 {
-    return detProcessedExpInsert(dbh, object->det_id, object->exp_tag, object->recipe, object->bg, object->bg_stdev, object->bg_mean_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->path_base, object->fault);
+    return detProcessedExpInsert(dbh, object->det_id, object->exp_id, object->recipe, object->bg, object->bg_stdev, object->bg_mean_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->path_base, object->fault);
 }
 
@@ -14990,6 +14324,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -15079,7 +14413,7 @@
         return false;
     }
-    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
         return false;
     }
@@ -15155,5 +14489,5 @@
     }
 
-    return detProcessedExpRowAlloc(det_id, exp_tag, recipe, bg, bg_stdev, bg_mean_stdev, fringe_0, fringe_1, fringe_2, user_1, user_2, user_3, user_4, user_5, path_base, fault);
+    return detProcessedExpRowAlloc(det_id, exp_id, recipe, bg, bg_stdev, bg_mean_stdev, fringe_0, fringe_1, fringe_2, user_1, user_2, user_3, user_4, user_5, path_base, fault);
 }
 psArray *detProcessedExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -17250,5 +16584,5 @@
 static void detResidImfileRowFree(detResidImfileRow *object);
 
-detResidImfileRow *detResidImfileRowAlloc(psS64 det_id, psS32 iteration, const char *exp_tag, const char *class_id, const char *uri, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
+detResidImfileRow *detResidImfileRowAlloc(psS64 det_id, psS32 iteration, psS64 exp_id, const char *class_id, const char *uri, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
 {
     detResidImfileRow *_object;
@@ -17259,5 +16593,5 @@
     _object->det_id = det_id;
     _object->iteration = iteration;
-    _object->exp_tag = psStringCopy(exp_tag);
+    _object->exp_id = exp_id;
     _object->class_id = psStringCopy(class_id);
     _object->uri = psStringCopy(uri);
@@ -17283,5 +16617,4 @@
 static void detResidImfileRowFree(detResidImfileRow *object)
 {
-    psFree(object->exp_tag);
     psFree(object->class_id);
     psFree(object->uri);
@@ -17303,6 +16636,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key", 64)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -17406,5 +16739,5 @@
 }
 
-bool detResidImfileInsert(psDB * dbh, psS64 det_id, psS32 iteration, const char *exp_tag, const char *class_id, const char *uri, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
+bool detResidImfileInsert(psDB * dbh, psS64 det_id, psS32 iteration, psS64 exp_id, const char *class_id, const char *uri, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, psS16 fault)
 {
     psMetadata *md = psMetadataAlloc();
@@ -17419,6 +16752,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -17532,5 +16865,5 @@
 bool detResidImfileInsertObject(psDB *dbh, detResidImfileRow *object)
 {
-    return detResidImfileInsert(dbh, object->det_id, object->iteration, object->exp_tag, object->class_id, object->uri, object->recipe, object->bg, object->bg_stdev, object->bg_mean_stdev, object->bin_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->path_base, object->fault);
+    return detResidImfileInsert(dbh, object->det_id, object->iteration, object->exp_id, object->class_id, object->uri, object->recipe, object->bg, object->bg_stdev, object->bg_mean_stdev, object->bin_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->path_base, object->fault);
 }
 
@@ -17615,6 +16948,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -17724,7 +17057,7 @@
         return false;
     }
-    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
         return false;
     }
@@ -17815,5 +17148,5 @@
     }
 
-    return detResidImfileRowAlloc(det_id, iteration, exp_tag, class_id, uri, recipe, bg, bg_stdev, bg_mean_stdev, bin_stdev, fringe_0, fringe_1, fringe_2, user_1, user_2, user_3, user_4, user_5, path_base, fault);
+    return detResidImfileRowAlloc(det_id, iteration, exp_id, class_id, uri, recipe, bg, bg_stdev, bg_mean_stdev, bin_stdev, fringe_0, fringe_1, fringe_2, user_1, user_2, user_3, user_4, user_5, path_base, fault);
 }
 psArray *detResidImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -17927,5 +17260,5 @@
 static void detResidExpRowFree(detResidExpRow *object);
 
-detResidExpRow *detResidExpRowAlloc(psS64 det_id, psS32 iteration, const char *exp_tag, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, bool accept, psS16 fault)
+detResidExpRow *detResidExpRowAlloc(psS64 det_id, psS32 iteration, psS64 exp_id, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, bool accept, psS16 fault)
 {
     detResidExpRow  *_object;
@@ -17936,5 +17269,5 @@
     _object->det_id = det_id;
     _object->iteration = iteration;
-    _object->exp_tag = psStringCopy(exp_tag);
+    _object->exp_id = exp_id;
     _object->recipe = psStringCopy(recipe);
     _object->bg = bg;
@@ -17959,5 +17292,4 @@
 static void detResidExpRowFree(detResidExpRow *object)
 {
-    psFree(object->exp_tag);
     psFree(object->recipe);
     psFree(object->path_base);
@@ -17977,6 +17309,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, "Primary Key", 64)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -18075,5 +17407,5 @@
 }
 
-bool detResidExpInsert(psDB * dbh, psS64 det_id, psS32 iteration, const char *exp_tag, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, bool accept, psS16 fault)
+bool detResidExpInsert(psDB * dbh, psS64 det_id, psS32 iteration, psS64 exp_id, const char *recipe, psF64 bg, psF64 bg_stdev, psF64 bg_mean_stdev, psF64 bin_stdev, psF64 fringe_0, psF64 fringe_1, psF64 fringe_2, psF64 user_1, psF64 user_2, psF64 user_3, psF64 user_4, psF64 user_5, const char *path_base, bool accept, psS16 fault)
 {
     psMetadata *md = psMetadataAlloc();
@@ -18088,6 +17420,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -18196,5 +17528,5 @@
 bool detResidExpInsertObject(psDB *dbh, detResidExpRow *object)
 {
-    return detResidExpInsert(dbh, object->det_id, object->iteration, object->exp_tag, object->recipe, object->bg, object->bg_stdev, object->bg_mean_stdev, object->bin_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->path_base, object->accept, object->fault);
+    return detResidExpInsert(dbh, object->det_id, object->iteration, object->exp_id, object->recipe, object->bg, object->bg_stdev, object->bg_mean_stdev, object->bin_stdev, object->fringe_0, object->fringe_1, object->fringe_2, object->user_1, object->user_2, object->user_3, object->user_4, object->user_5, object->path_base, object->accept, object->fault);
 }
 
@@ -18279,6 +17611,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_id", PS_DATA_S64, NULL, object->exp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
         psFree(md);
         return false;
@@ -18383,7 +17715,7 @@
         return false;
     }
-    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
+    psS64 exp_id = psMetadataLookupS64(&status, md, "exp_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_id");
         return false;
     }
@@ -18469,5 +17801,5 @@
     }
 
-    return detResidExpRowAlloc(det_id, iteration, exp_tag, recipe, bg, bg_stdev, bg_mean_stdev, bin_stdev, fringe_0, fringe_1, fringe_2, user_1, user_2, user_3, user_4, user_5, path_base, accept, fault);
+    return detResidExpRowAlloc(det_id, iteration, exp_id, recipe, bg, bg_stdev, bg_mean_stdev, bin_stdev, fringe_0, fringe_1, fringe_2, user_1, user_2, user_3, user_4, user_5, path_base, accept, fault);
 }
 psArray *detResidExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
