be92120f95e214b96f28d78bed322ecb150844d9
tdreszer
  Wed Nov 24 10:05:15 2010 -0800
Removed three obsolete files that were replaced by metaDb(mdb) long ago.
diff --git src/hg/lib/metaTbl.c src/hg/lib/metaTbl.c
deleted file mode 100644
index 78e84e5..0000000
--- src/hg/lib/metaTbl.c
+++ /dev/null
@@ -1,1852 +0,0 @@
-/* metaTbl.c was originally generated by the autoSql program, which also
- * generated metaTbl.h and metaTbl.sql.  This module links the database and
- * the RAM representation of objects. */
-
-#include "common.h"
-#include "linefile.h"
-#include "dystring.h"
-#include "jksql.h"
-#include "metaTbl.h"
-
-static char const rcsid[] = "$Id: metaTbl.c,v 1.13 2010/05/11 01:43:30 kent Exp $";
-
-void metaTblStaticLoad(char **row, struct metaTbl *ret)
-/* Load a row from metaTbl table into ret.  The contents of ret will
- * be replaced at the next call to this function. */
-{
-
-ret->objName = row[0];
-ret->objType = row[1];
-ret->var = row[2];
-ret->varType = row[3];
-ret->val = row[4];
-}
-
-struct metaTbl *metaTblLoadByQuery(struct sqlConnection *conn, char *query)
-/* Load all metaTbl from table that satisfy the query given.
- * Where query is of the form 'select * from example where something=something'
- * or 'select example.* from example, anotherTable where example.something =
- * anotherTable.something'.
- * Dispose of this with metaTblFreeList(). */
-{
-struct metaTbl *list = NULL, *el;
-struct sqlResult *sr;
-char **row;
-
-sr = sqlGetResult(conn, query);
-while ((row = sqlNextRow(sr)) != NULL)
-    {
-    el = metaTblLoad(row);
-    slAddHead(&list, el);
-    }
-slReverse(&list);
-sqlFreeResult(&sr);
-return list;
-}
-
-void metaTblSaveToDb(struct sqlConnection *conn, struct metaTbl *el, char *tableName, int updateSize)
-/* Save metaTbl as a row to the table specified by tableName.
- * As blob fields may be arbitrary size updateSize specifies the approx size
- * of a string that would contain the entire query. Arrays of native types are
- * converted to comma separated strings and loaded as such, User defined types are
- * inserted as NULL. Note that strings must be escaped to allow insertion into the database.
- * For example "autosql's features include" --> "autosql\'s features include"
- * If worried about this use metaTblSaveToDbEscaped() */
-{
-struct dyString *update = newDyString(updateSize);
-dyStringPrintf(update, "insert into %s values ( '%s','%s','%s','%s',%s)",
-	tableName,  el->objName,  el->objType,  el->var,  el->varType,  el->val);
-sqlUpdate(conn, update->string);
-freeDyString(&update);
-}
-
-void metaTblSaveToDbEscaped(struct sqlConnection *conn, struct metaTbl *el, char *tableName, int updateSize)
-/* Save metaTbl as a row to the table specified by tableName.
- * As blob fields may be arbitrary size updateSize specifies the approx size.
- * of a string that would contain the entire query. Automatically
- * escapes all simple strings (not arrays of string) but may be slower than metaTblSaveToDb().
- * For example automatically copies and converts:
- * "autosql's features include" --> "autosql\'s features include"
- * before inserting into database. */
-{
-struct dyString *update = newDyString(updateSize);
-char  *objName, *objType, *var, *varType, *val;
-objName = sqlEscapeString(el->objName);
-objType = sqlEscapeString(el->objType);
-var = sqlEscapeString(el->var);
-varType = sqlEscapeString(el->varType);
-val = sqlEscapeString(el->val);
-
-dyStringPrintf(update, "insert into %s values ( '%s','%s','%s','%s','%s')",
-	tableName,  objName,  objType,  var,  varType,  val);
-sqlUpdate(conn, update->string);
-freeDyString(&update);
-freez(&objName);
-freez(&objType);
-freez(&var);
-freez(&varType);
-freez(&val);
-}
-
-struct metaTbl *metaTblLoad(char **row)
-/* Load a metaTbl from row fetched with select * from metaTbl
- * from database.  Dispose of this with metaTblFree(). */
-{
-struct metaTbl *ret;
-
-AllocVar(ret);
-ret->objName = cloneString(row[0]);
-ret->objType = cloneString(row[1]);
-ret->var = cloneString(row[2]);
-ret->varType = cloneString(row[3]);
-ret->val = cloneString(row[4]);
-return ret;
-}
-
-struct metaTbl *metaTblLoadAll(char *fileName)
-/* Load all metaTbl from a whitespace-separated file.
- * Dispose of this with metaTblFreeList(). */
-{
-struct metaTbl *list = NULL, *el;
-struct lineFile *lf = lineFileOpen(fileName, TRUE);
-char *row[5];
-
-while (lineFileRow(lf, row))
-    {
-    el = metaTblLoad(row);
-    slAddHead(&list, el);
-    }
-lineFileClose(&lf);
-slReverse(&list);
-return list;
-}
-
-struct metaTbl *metaTblLoadAllByChar(char *fileName, char chopper)
-/* Load all metaTbl from a chopper separated file.
- * Dispose of this with metaTblFreeList(). */
-{
-struct metaTbl *list = NULL, *el;
-struct lineFile *lf = lineFileOpen(fileName, TRUE);
-char *row[5];
-
-while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
-    {
-    el = metaTblLoad(row);
-    slAddHead(&list, el);
-    }
-lineFileClose(&lf);
-slReverse(&list);
-return list;
-}
-
-struct metaTbl *metaTblCommaIn(char **pS, struct metaTbl *ret)
-/* Create a metaTbl out of a comma separated string.
- * This will fill in ret if non-null, otherwise will
- * return a new metaTbl */
-{
-char *s = *pS;
-
-if (ret == NULL)
-    AllocVar(ret);
-ret->objName = sqlStringComma(&s);
-ret->objType = sqlStringComma(&s);
-ret->var = sqlStringComma(&s);
-ret->varType = sqlStringComma(&s);
-ret->val = sqlStringComma(&s);
-*pS = s;
-return ret;
-}
-
-void metaTblFree(struct metaTbl **pEl)
-/* Free a single dynamically allocated metaTbl such as created
- * with metaTblLoad(). */
-{
-struct metaTbl *el;
-
-if ((el = *pEl) == NULL) return;
-freeMem(el->objName);
-freeMem(el->objType);
-freeMem(el->var);
-freeMem(el->varType);
-freeMem(el->val);
-freez(pEl);
-}
-
-void metaTblFreeList(struct metaTbl **pList)
-/* Free a list of dynamically allocated metaTbl's */
-{
-struct metaTbl *el, *next;
-
-for (el = *pList; el != NULL; el = next)
-    {
-    next = el->next;
-    metaTblFree(&el);
-    }
-*pList = NULL;
-}
-
-void metaTblOutput(struct metaTbl *el, FILE *f, char sep, char lastSep)
-/* Print out metaTbl.  Separate fields with sep. Follow last field with lastSep. */
-{
-if (sep == ',') fputc('"',f);
-fprintf(f, "%s", el->objName);
-if (sep == ',') fputc('"',f);
-fputc(sep,f);
-if (sep == ',') fputc('"',f);
-fprintf(f, "%s", el->objType);
-if (sep == ',') fputc('"',f);
-fputc(sep,f);
-if (sep == ',') fputc('"',f);
-fprintf(f, "%s", el->var);
-if (sep == ',') fputc('"',f);
-fputc(sep,f);
-if (sep == ',') fputc('"',f);
-fprintf(f, "%s", el->varType);
-if (sep == ',') fputc('"',f);
-fputc(sep,f);
-if (sep == ',') fputc('"',f);
-fprintf(f, "%s", el->val);
-if (sep == ',') fputc('"',f);
-fputc(lastSep,f);
-}
-
-/* -------------------------------- End autoSql Generated Code -------------------------------- */
-
-#include "ra.h"
-#include "hgConfig.h"
-#include "obscure.h"
-
-// ------- (static) convert from autoSql -------
-static void metaVarFree(struct metaVar **metaVarPtr)
-// Frees a single metaVar struct
-{
-    freeMem((*metaVarPtr)->val);
-    freeMem((*metaVarPtr)->var);
-    freez(metaVarPtr);
-}
-
-static void metaLeafObjFree(struct metaLeafObj **leafObjPtr)
-// Frees a single metaVar struct
-{
-    freeMem((*leafObjPtr)->obj);
-    freez(leafObjPtr);
-}
-
-static void metaLimbValFree(struct metaLimbVal **limbValPtr)
-// Frees a single metaVar struct
-{
-struct metaLimbVal *limbVal = *limbValPtr;
-
-    // Free hash first (shared memory)
-    hashFree(&(limbVal->objHash));
-
-    struct metaLeafObj *leafObj = NULL;
-    while((leafObj = slPopHead(&(limbVal->objs))) != NULL)
-        metaLeafObjFree(&leafObj);
-
-    freeMem(limbVal->val);
-    freez(limbValPtr);
-}
-
-static struct metaObj *metaObjsLoadFromMemory(struct metaTbl **metaTblPtr,boolean buildHashes)
-// Load all metaObjs from in memory metaTbl struct, cannibalize strings.  Expects sorted order.
-{
-struct metaObj *metaObj  = NULL;
-struct metaObj *metaObjs = NULL;
-struct metaVar *metaVar;
-struct metaTbl *thisRow;
-while((thisRow = slPopHead(metaTblPtr)) != NULL)
-    {
-    if (metaObj == NULL || differentString(thisRow->objName,metaObj->obj) )
-        {
-        // Finish last object before starting next!
-        if(metaObj!= NULL)
-            slReverse(&(metaObjs->vars));
-        // Start new object
-        AllocVar(metaObj);
-        metaObj->obj     = thisRow->objName;
-        metaObj->objType = metaObjTypeStringToEnum(thisRow->objType);
-        freeMem(thisRow->objType);
-        if ( buildHashes )
-            metaObj->varHash = hashNew(0);
-        slAddHead(&metaObjs,metaObj);
-        }
-    else
-        {
-        freeMem(thisRow->objName);  // Already got this from prev row
-        freeMem(thisRow->objType);
-        }
-    AllocVar(metaVar);
-    metaVar->var     = thisRow->var;
-    metaVar->varType = metaVarTypeStringToEnum(thisRow->varType);
-    metaVar->val     = thisRow->val;
-    slAddHead(&(metaObj->vars),metaVar);
-    if ( buildHashes )
-        hashAddUnique(metaObj->varHash, metaVar->var, metaVar); // pointer to struct to resolve type
-
-    freeMem(thisRow);
-    }
-
-// Finish very last object
-if(metaObjs && metaObjs->vars)
-    slReverse(&(metaObjs->vars));
-if(metaObjs)
-    slReverse(&metaObjs);
-
-return metaObjs;
-}
-
-static struct metaByVar *metaByVarsLoadFromMemory(struct metaTbl **metaTblPtr,boolean buildHashes)
-// Load all metaVars from in memorys metaTbl struct, cannibalize strings.  Expects sorted order.
-{
-struct metaByVar *rootVars = NULL;
-struct metaByVar *rootVar  = NULL;
-struct metaLimbVal *limbVal  = NULL;
-struct metaLeafObj *leafObj;
-struct metaTbl *thisRow;
-while((thisRow = slPopHead(metaTblPtr)) != NULL)
-    {
-    // Start at root
-    if (rootVar == NULL || differentString(thisRow->var,rootVar->var) )
-        {
-        // Finish last var before starting next!
-        if(rootVars && rootVars->vals && rootVars->vals->objs)
-            slReverse(&(rootVars->vals->objs));
-        if(rootVars && rootVars->vals)
-            slReverse(&(rootVars->vals));
-        // Start new var
-        AllocVar(rootVar);
-        limbVal = NULL;  // Very important!
-        rootVar->var     = thisRow->var;
-        rootVar->varType = metaVarTypeStringToEnum(thisRow->varType);
-        freeMem(thisRow->varType);
-        if ( buildHashes )
-            rootVar->valHash = hashNew(0);
-        slAddHead(&rootVars,rootVar);
-        }
-    else
-        {
-        freeMem(thisRow->var);  // Already got this from prev row
-        freeMem(thisRow->varType);
-        }
-
-    // Continue with limb
-    if (limbVal == NULL || differentString(thisRow->val,limbVal->val) )
-        {
-        // Finish last val before starting next!
-        if(limbVal != NULL && limbVal->objs != NULL)
-            slReverse(&(limbVal->objs));
-        // Start new val
-        AllocVar(limbVal);
-        limbVal->val     = thisRow->val;     // FIXME: binary?
-        if ( buildHashes )
-            {
-            hashAddUnique(rootVar->valHash, limbVal->val, limbVal); // Pointer to struct to get to objHash
-            limbVal->objHash = hashNew(0);
-            }
-        slAddHead(&(rootVar->vals),limbVal);
-        }
-    else
-        freeMem(thisRow->val);  // Already got this from prev row
-
-    // End with leaf
-    AllocVar(leafObj);
-    leafObj->obj     = thisRow->objName;
-    leafObj->objType = metaObjTypeStringToEnum(thisRow->objType);
-    freeMem(thisRow->objType);
-    if ( buildHashes )
-        hashAddUnique(limbVal->objHash, leafObj->obj, leafObj); // Pointer to struct to resolve type!
-    slAddHead(&(limbVal->objs),leafObj);
-
-    freeMem(thisRow);
-    }
-
-// Finish very last object
-if(rootVars && rootVars->vals && rootVars->vals->objs)
-    slReverse(&(rootVars->vals->objs));
-if(rootVars && rootVars->vals)
-    slReverse(&(rootVars->vals));
-if(rootVars && rootVars->vals)
-    slReverse(&rootVars);
-
-return rootVars;
-}
-
-
-static int metaObjCRC(struct metaObj *metaObjs)
-// returns a summ of all individual CRC values of all metObj strings
-{
-int crc = 0;
-struct metaObj *metaObj = NULL;
-for(metaObj=metaObjs;metaObj!=NULL;metaObj=metaObj->next)
-    {
-    if(metaObj->obj != NULL)
-        crc += hashCrc(metaObj->obj);
-
-    struct metaVar *metaVar = NULL;
-    for(metaVar=metaObj->vars;metaVar!=NULL;metaVar=metaVar->next)
-        {
-        if(metaVar->var != NULL)
-            crc += hashCrc(metaVar->var);
-        if(metaVar->varType == vtTxt && metaVar->val != NULL)
-            crc += hashCrc(metaVar->val);
-        }
-    }
-
-return crc;
-}
-
-// -------------- Sort primitives --------------
-int metaObjCmp(const void *va, const void *vb)
-/* Compare to sort on label. */
-{
-const struct metaObj *a = *((struct metaObj **)va);
-const struct metaObj *b = *((struct metaObj **)vb);
-return strcasecmp(a->obj, b->obj);
-}
-
-int metaVarCmp(const void *va, const void *vb)
-/* Compare to sort on label. */
-{
-const struct metaVar *a = *((struct metaVar **)va);
-const struct metaVar *b = *((struct metaVar **)vb);
-return strcasecmp(a->var, b->var);
-}
-
-
-// -------------- Enum to Strings --------------
-enum metaObjType metaObjTypeStringToEnum(char *objType)
-// Convert metadata objType string to enum
-{
-if(sameWord(objType,"table"))
-    return otTable;
-if(sameWord(objType,"file"))
-    return otFile;
-return otUnknown;
-}
-
-char *metaObjTypeEnumToString(enum metaObjType objType)
-// Convert metadata objType enum string
-{
-switch (objType)
-    {
-    case otTable:  return "table";
-    case otFile:   return "file";
-    default:       return "unknown";
-    }
-}
-
-enum metaVarType metaVarTypeStringToEnum(char *varType)
-// Convert metadata varType string to enum
-{
-if(sameWord(varType,"txt"))
-    return vtTxt;
-if(sameWord(varType,"binary"))
-    return vtBinary;
-return vtUnknown;
-}
-
-char *metaVarTypeEnumToString(enum metaVarType varType)
-// Convert metadata varType enum string
-{
-switch (varType)
-    {
-    case vtTxt:    return "txt";
-    case vtBinary: return "binary";
-    default:       return "unknown";
-    }
-}
-
-// ------ Parsing lines ------
-
-struct metaObj *metaObjAddVarPairs(struct metaObj *oldObj,char *varPairs)
-// Parses line of var=val pairs adding to a metaObj.  Creates metaObj if NULL
-{
-struct metaObj *metaObj = oldObj;
-struct metaVar *metaVar;
-char *cloneVars = cloneString(varPairs);
-
-    // initial chop and determine if this looks like metadata
-    int count = chopByWhiteRespectDoubleQuotes(cloneVars,NULL,0);
-    char **words = needMem(sizeof(char *) * count);
-    count = chopByWhiteRespectDoubleQuotes(cloneVars,words,count);
-    if(count < 1 || words[0] == NULL)
-        {
-        errAbort("This is not formatted var=val pairs:\n\t%s\n",varPairs);
-        }
-
-    verbose(3, "metaObjAddVarPairs() word count:%d\n\t%s\n",count,varPairs);
-
-    if(metaObj == NULL)
-        AllocVar(metaObj);
-    if(metaObj->varHash == NULL)
-        metaObj->varHash = hashNew(0);
-
-    int ix;
-    for(ix = 0;ix<count;ix++)
-        {
-        if(strchr(words[ix], '=') == NULL)
-            errAbort("This is not formatted var=val pairs: '%s'\n\t%s\n",words[ix],varPairs);
-
-        AllocVar(metaVar);
-        metaVar->var = cloneNextWordByDelimiter(&(words[ix]),'=');
-        metaVar->varType = vtTxt;                               // FIXME: binary?
-        metaVar->val = cloneString(words[ix]);
-        verbose(3, "metaObjAddVarPairs() var=val: %s=%s\n",metaVar->var,metaVar->val);
-        struct metaVar *oldVar = (struct metaVar *)hashFindVal(metaObj->varHash, metaVar->var);
-        if(oldVar)
-            {
-            verbose(1, "The same variable appears twice: %s=%s and %s=%s.  Ignoring second value.\n\t%s\n",
-                oldVar->var,oldVar->val,metaVar->var,metaVar->val,varPairs);
-            metaVarFree(&metaVar);
-            }
-        else
-            {
-            hashAdd(metaObj->varHash, metaVar->var, metaVar); // pointer to struct to resolve type
-            slAddHead(&(metaObj->vars),metaVar);
-            }
-        }
-    freeMem(words);
-    freeMem(cloneVars);
-
-    // Special for old style ENCODE metadata
-#define ENCODE_ALN  "Alignments"
-#define ENCODE_RSIG "RawSignal"
-    if(metaObj->obj == NULL)
-        {
-        char * tableName = NULL;
-        char * fileName = NULL;
-        for(metaVar  = metaObj->vars;
-            metaVar != NULL && (tableName == NULL || fileName == NULL);
-            metaVar  = metaVar->next)
-            {
-            if(sameString(metaVar->var,"tableName"))
-                tableName = metaVar->val;
-            else if(sameString(metaVar->var,"fileName"))
-                fileName = metaVar->val;
-            }
-        if(tableName != NULL)
-            {
-            verbose(3, "tableName:%s\n",tableName);
-            if(fileName == NULL || startsWithWordByDelimiter(tableName,'.',fileName))
-                {
-                metaObj->obj     = cloneString(tableName);
-                metaObj->objType = otTable;
-                }
-            else if(stringIn(ENCODE_ALN,fileName) && stringIn(ENCODE_RSIG,tableName))// Messier case where the file has "Alignment" but the table has "RawSignal"
-                {
-                char *tmpFilName = cloneString(fileName);
-                strSwapStrs(tmpFilName, strlen(tmpFilName),ENCODE_ALN, ENCODE_RSIG);
-                if(startsWithWordByDelimiter(tableName,'.',tmpFilName))
-                    {
-                    metaObj->obj     = cloneString(tableName);
-                    metaObj->objType = otTable;
-                    }
-                freeMem(tmpFilName);
-                }
-            }
-        else if(fileName != NULL)
-            {
-            verbose(3, "fileName:%s\n",fileName);
-            // NOTE: that the file object is the root of the name, so both file.fastq.gz and file.fastq are same obj!
-            metaObj->obj     = cloneFirstWordByDelimiter(fileName,'.');
-            metaObj->objType = otFile;
-            }
-        }
-
-if(metaObj->obj == NULL) // NOTE: Should this be a hard error!
-    errAbort("No obj found. This is not properly formatted metadata:\n\t%s\n",varPairs);
-
-if(metaObj->objType == otUnknown) // NOTE: defaulting to table
-    metaObj->objType = otTable;
-
-    //slReverse(&(metaObj->vars)); Could have added vars so sort instead
-    slSort(&(metaObj->vars),&metaVarCmp); // Should be in determined order
-    verbose(3, "metaObjAddVarPairs() obj=%s(%s) %s(%s)=%s\n",
-    metaObj->obj, metaObjTypeEnumToString(metaObj->objType),metaObj->vars->var,metaVarTypeEnumToString(metaObj->vars->varType),metaObj->vars->val);
-return metaObj;
-}
-
-struct metaObj *metadataLineParse(char *line)
-/* Parses a single formatted metadata line into metaObj for updates or queries. */
-{
-char *fromTheTop = line;
-char*nibbledWord = cloneNextWordByDelimiter(&line,' ');
-if(nibbledWord == NULL || differentWord(nibbledWord,"metadata"))
-    errAbort("This is not a formatted metadata line:\n\t%s\n",fromTheTop);
-freeMem(nibbledWord);
-
-struct metaObj *metaObj = NULL;
-char*varPairs = line;
-nibbledWord = cloneNextWordByDelimiter(&line,' ');;
-if(nibbledWord == NULL)
-    errAbort("This is not a formatted metadata line:\n\t%s\n",fromTheTop);
-if(strchr(nibbledWord, '=') == NULL) // If this is not a var=val then it should be objName
-    {
-    AllocVar(metaObj);
-    metaObj->obj = nibbledWord;
-    verbose(3, "metadataLineParse() obj=%s\n",metaObj->obj);
-    varPairs = line;
-    while(strlen(line) > 0)
-        {
-        nibbledWord = cloneNextWordByDelimiter(&line,' ');;
-        if(nibbledWord == NULL)
-            errAbort("This is not a formatted metadata line:\n\t%s\n",fromTheTop);
-        if(strchr(nibbledWord, '=') != NULL) // If this is start of var=val pairs
-            break;
-
-        if(sameWord(nibbledWord,"delete"))
-            metaObj->deleteThis = TRUE;
-        else
-            metaObj->objType = metaObjTypeStringToEnum(nibbledWord);
-        varPairs = line;
-        freeMem(nibbledWord);
-        }
-    }
-if(strlen(varPairs) > 0)
-	metaObj = metaObjAddVarPairs(metaObj,varPairs);
-else if(metaObj->deleteThis == FALSE)
-    errAbort("This is not a formatted metadata line:\n\t%s\n",fromTheTop);
-return metaObj;
-}
-
-struct metaByVar *metaByVarsLineParse(char *line)
-/* Parses a line of "var1=val1 var2=val2 into a metaByVar object for queries. */
-{
-int thisWord = 0;
-struct metaByVar   *metaByVars = NULL;
-struct metaByVar   *rootVar = NULL;
-struct metaLimbVal *limbVal = NULL;
-char *cloneLine = cloneString(line);
-struct hash* varHash;     // There must not be multiple occurrances of the same var
-
-    // initial chop and determine if this looks like metadata
-    int count = chopByWhiteRespectDoubleQuotes(cloneLine,NULL,0);
-    char **words = needMem(sizeof(char *) * count);
-    count = chopByWhiteRespectDoubleQuotes(cloneLine,words,count);
-
-    verbose(3, "metaByVarsLineParse() word count:%d\n\t%s\n",count,line);
-    // Get obj and figure out if this is a delete line
-    varHash = hashNew(0);
-
-    // All words are expected to be var=val pairs!
-    for(thisWord=0;thisWord<count;thisWord++)
-        {
-        if(strchr(words[thisWord], '=') == NULL)
-            {
-            errAbort("Expected 'var=val' but found '%s'.  This is not properly formatted metadata:\n\t%s\n",words[thisWord],line);
-            //metaObjsFree(&metaObj);
-            //return NULL;
-            }
-        AllocVar(rootVar);
-        rootVar->var = cloneNextWordByDelimiter(&(words[thisWord]),'=');
-        rootVar->notEqual = (rootVar->var[strlen(rootVar->var)-1] == '!'); // requested not equal
-        if(rootVar->notEqual)
-            rootVar->var[strlen(rootVar->var)-1] = 0;
-        char *val = cloneString(words[thisWord]);
-        if(sameWord(val,"?"))  // "var=?" or "var=" will query by var name only
-            freez(&val);
-
-        struct metaByVar *oldVar = (struct metaByVar *)hashFindVal(varHash, rootVar->var);
-        if(oldVar)
-            {  // FIXME: Could build this for 'or' queries!
-            verbose(1, "The same variable appears twice: %s=%s and %s=%s.  Ignoring second value.\n",
-                oldVar->var,oldVar->vals->val,rootVar->var,val);
-            freeMem(rootVar->var);
-            freeMem(rootVar);
-            freeMem(val);
-            }
-        else
-            {
-            AllocVar(limbVal);
-            limbVal->val = val;
-            rootVar->vals = limbVal;
-            hashAdd(varHash, rootVar->var, rootVar);
-            slAddHead(&metaByVars,rootVar);
-            }
-        }
-    freeMem(words);
-    slReverse(&metaByVars);
-    verbose(3, "metaByVarsLineParse() parsed:%d first: %s=%s.\n",
-        slCount(metaByVars->vals),metaByVars->var,metaByVars->vals->val);
-return metaByVars;
-}
-
-// ------ Loading from args, hashes and tdb ------
-struct metaByVar*metaByVarCreate(char *var, char *varType,char *val)
-/* Creates a singular var=val pair struct for metadata queries. */
-{
-struct metaByVar *metaByVar = NULL;
-
-    if(var == NULL)
-        errAbort("Need variable to create metaByVar query object.\n");
-
-    AllocVar(metaByVar);
-    metaByVar->var = cloneString(var);
-    metaByVar->varType = (varType==NULL?vtUnknown:metaVarTypeStringToEnum(varType));
-
-    if(val != NULL)
-        {
-        struct metaLimbVal * limbVal;
-        AllocVar(limbVal);
-
-        limbVal->val    = cloneString(val);
-        metaByVar->vals = limbVal; // Only one
-        }
-
-return metaByVar;
-}
-
-struct metaObj *metaObjCreate(char *obj,char *type,char *var, char *varType,char *val)
-/* Creates a singular metaObj query object based on obj and all other optional params. */
-{
-struct metaObj *metaObj = NULL;
-
-    if(obj == NULL)
-        errAbort("Need obj to create metaObj query object.\n");
-
-    AllocVar(metaObj);
-    metaObj->obj     = cloneString(obj);
-    metaObj->objType = (type==NULL?otUnknown:metaObjTypeStringToEnum(type));
-
-    if(var != NULL)
-        {
-        struct metaVar * metaVar;
-        AllocVar(metaVar);
-
-        metaVar->var     = cloneString(var);
-        metaVar->varType = (varType==NULL?vtUnknown:metaVarTypeStringToEnum(varType));
-        if(val != NULL)
-            metaVar->val     = cloneString(val);
-        metaObj->vars = metaVar; // Only one
-        }
-return metaObj;
-}
-
-struct metaObj *metaObjsLoadFromHashes(struct hash *objsHash)
-// Load all metaObjs from a file containing metadata formatted lines
-{
-struct metaObj *metaObjs = NULL;
-struct hashEl* objEl = NULL;
-
-struct hashCookie objCookie = hashFirst(objsHash);
-while((objEl = hashNext(&objCookie)) != NULL)
-    {
-    struct metaObj *metaObj;
-    AllocVar(metaObj);
-    metaObj->obj     = cloneString(objEl->name);
-    metaObj->varHash = hashNew(0);
-    struct hash *hashedVars = objEl->val;
-    struct hashCookie varCookie = hashFirst(hashedVars);
-    struct hashEl* varEl = NULL;
-    while((varEl = hashNext(&varCookie)) != NULL)
-        {
-        if(sameString(varEl->name,"metaObject"))
-            continue;
-        if(sameString(varEl->name,"objType"))
-            metaObj->objType = metaObjTypeStringToEnum(varEl->val);
-        else
-            {
-            struct metaVar * metaVar;
-            AllocVar(metaVar);
-            metaVar->var     = cloneString(varEl->name);
-            metaVar->varType = vtTxt;                    // FIXME: binary?
-            metaVar->val     = cloneString(varEl->val);
-            hashAdd(metaObj->varHash, metaVar->var, metaVar); // pointer to struct to resolve type
-            slAddHead(&(metaObj->vars),metaVar);
-            }
-
-        }
-        slSort(&(metaObj->vars),&metaVarCmp); // Should be in determined order
-        slAddHead(&metaObjs,metaObj);
-    }
-    slSort(&metaObjs,&metaObjCmp); // Should be in determined order
-    return metaObjs;
-}
-
-// ------ Loading from files ------
-struct metaObj *metaObjsLoadFromFormattedFile(char *fileName,boolean *validated)
-// Load all metaObjs from a file containing metadata formatted lines
-{
-struct metaObj *metaObjs = NULL;
-struct lineFile *lf = lineFileOpen(fileName, TRUE);
-char *line;
-
-while (lineFileNext(lf, &line,NULL))
-    {
-    if(startsWithWord("metaObject",line))
-        {
-        // This is the RA style file!!
-        lineFileClose(&lf);
-        return metaObjsLoadFromRAFile(fileName,validated);
-        }
-    struct metaObj *metaObj = metadataLineParse(line);
-    if(metaObj == NULL)
-        {
-        metaObjsFree(&metaObjs);
-        return NULL;
-        }
-    slAddHead(&metaObjs,metaObj);
-    }
-    lineFileClose(&lf);
-    slReverse(&metaObjs);  // Go ahead and keep this in file order
-    if(validated)
-        *validated = FALSE;
-    return metaObjs;
-}
-
-#define METATBL_MAGIC_PREFIX "# MAGIC: "
-struct metaObj *metaObjsLoadFromRAFile(char *fileName,boolean *validated)
-// Load all metaObjs from a file containing RA formatted 'metaObjects'
-{
-struct hash *mdHash = raReadAll(fileName, "metaObject");
-if(mdHash == NULL)
-    {
-    verbose(1,"Missing, empty or badly formated RA file:%s\n",fileName);
-    return NULL;
-    }
-struct metaObj *metaObjs = metaObjsLoadFromHashes(mdHash);
-hashFree(&mdHash);
-
-// Try to validate file
-if(validated)
-    {
-    *validated = FALSE;
-    struct lineFile *lf = lineFileOpen(fileName, TRUE);
-    char *line = lineFileSkipToLineStartingWith(lf,METATBL_MAGIC_PREFIX,1000000);
-    if(line != NULL)
-        {
-        int fileMagic = atoi(line+strlen(METATBL_MAGIC_PREFIX));
-        int objsMagic = metaObjCRC(metaObjs);
-        verbose(3,"Objects magic: %d  Files magic: %d (%s)\n",objsMagic,fileMagic,line+strlen(METATBL_MAGIC_PREFIX));
-        *validated = (fileMagic == objsMagic);
-        }
-    else
-        verbose(3,"Can't find magic number on this file.\n");
-    }
-return metaObjs;
-}
-
-// ------ Table name and creation ------
-#define METATBL_SPEC_LOCATION "/cluster/bin/sqlCreate/metaTbl.sql"
-
-void metaTblReCreate(struct sqlConnection *conn,char *tblName,boolean testOnly)
-// Creates ore Recreates the named metaTbl.
-{
-if(sqlTableExists(conn,tblName))
-    verbose(2, "Table '%s' already exists.  It will be recreated.\n",tblName);
-
-char *sql = NULL;
-readInGulp(METATBL_SPEC_LOCATION, &sql, NULL);
-char *pos = strchr(sql, ';');
-if ( pos != NULL)
-    *pos = 0;
-char *oldSql = cloneString(sql);
-pos = stringIn("CREATE TABLE ", oldSql);
-if (pos == NULL)
-    errAbort("Can't find CREATE TABLE in %s\n", METATBL_SPEC_LOCATION);
-nextWord(&pos);
-nextWord(&pos);
-char *oldName = nextWord(&pos);
-if(differentWord(oldName, tblName))
-    {
-    char *saveSql = cloneString(sql);
-    freeMem(sql);
-    sql = replaceChars(saveSql, oldName, tblName);
-    freeMem(saveSql);
-    }
-freeMem(oldSql);
-verbose(2, "Requesting table creation:\n\t%s;\n", sql);
-if(!testOnly)
-    sqlRemakeTable(conn,tblName, sql);
-freeMem(sql);
-}
-
-char*metaTblName(struct sqlConnection *conn,boolean mySandBox)
-// returns the metaTbl name or NULL if conn supplied but the table doesn't exist
-{
-char *tblName = NULL;
-char *root = NULL;
-char *sand = NULL;
-char *name = cfgOption("db.metaTbl");
-if(name == NULL)
-    {
-    name = cfgOption("db.trackDb");
-    if(name == NULL)
-        root = cloneString(METATBL_DEFAULT_NAME);
-    }
-
-// Divide name into root and sand
-if(root == NULL)
-    {
-    char delimit = '_';
-    if((sand = strchr(name,delimit)) == NULL)
-        {
-        delimit = '-';
-        if((sand = strchr(name,delimit)) == NULL)
-            root = cloneString(name);  // No sandBox portion
-        }
-
-    if(root == NULL)  // There should be a sandbox portion
-        {
-        root = cloneNextWordByDelimiter(&name,delimit);
-        if(mySandBox && *name != 0)
-            sand = name;
-        }
-    }
-
-// Since db.trackDb was used, make sure to swap it
-if(sameWord("trackDb",root))
-    {
-    freeMem(root);
-    root = cloneString(METATBL_DEFAULT_NAME);
-    }
-
-if(!mySandBox || sand == NULL)
-    tblName = root;
-else
-    {
-    int size = strlen(root) + strlen(sand) + 2;
-    tblName = needMem(size);
-    safef(tblName,size,"%s_%s",root,sand);
-    }
-
-// Test for table
-if(conn != NULL && !sqlTableExists(conn,tblName))
-    {
-    if(sand == NULL || sameWord(tblName,root)) // Then try the root
-        return NULL;
-    freeMem(tblName);
-    tblName = root;
-    if(!sqlTableExists(conn,tblName))
-        return NULL;
-    }
-
-return tblName;
-}
-
-// -------------- Updating the DB --------------
-int metaObjsSetToDb(struct sqlConnection *conn,char *tableName,struct metaObj *metaObjs,boolean replace,boolean testOnly)
-// Adds or updates metadata obj/var pairs into the named table.  Returns total rows affected
-{
-char query[8192];
-struct metaObj *metaObj;
-struct metaVar *metaVar;
-int count = 0;
-
-if(tableName == NULL)
-    tableName = METATBL_DEFAULT_NAME;
-
-if(!sqlTableExists(conn,tableName))
-    errAbort("metaObjsSetToDb attempting to update non-existent table named '%s'.\n",tableName);
-
-for(metaObj = metaObjs;metaObj != NULL; metaObj = metaObj->next)
-    {
-    // Handle delete requests first
-    if(metaObj->deleteThis)
-        {
-        if(metaObj->vars == NULL) // deletes all
-            {
-            safef(query, sizeof(query),"%s where objName = '%s'",tableName,metaObj->obj);
-            int delCnt = sqlRowCount(conn,query);
-
-            if(delCnt>0)
-                {
-                safef(query, sizeof(query),
-                    "delete from %s where objName = '%s'",tableName,metaObj->obj);
-                verbose(2, "Requesting delete of %d rows:\n\t%s;\n",delCnt, query);
-                if(!testOnly)
-                    sqlUpdate(conn, query);
-                count += delCnt;
-                }
-            }
-        else  // deletes selected vars
-            {
-            for(metaVar = metaObj->vars;metaVar != NULL; metaVar = metaVar->next)
-                {
-                safef(query, sizeof(query),
-                    "select objName from %s where objName = '%s' and var = '%s'",
-                    tableName,metaObj->obj,metaVar->var);
-                if(sqlExists(conn,query))
-                    {
-                    safef(query, sizeof(query),
-                        "delete from %s where objName = '%s' and var = '%s'",
-                        tableName,metaObj->obj,metaVar->var);
-                    verbose(2, "Requesting delete of 1 row:\n\t%s;\n",query);
-                    if(!testOnly)
-                        sqlUpdate(conn, query);
-                    count++;
-                    }
-                }
-            }
-        continue;  // Done with this metaObj
-        }
-    else if (replace)  // If replace then clear out deadwood before inserting new vars
-        {
-        safef(query, sizeof(query),"%s where objName = '%s'",tableName,metaObj->obj);
-        int delCnt = sqlRowCount(conn,query);
-
-        if(delCnt>0)
-            {
-            safef(query, sizeof(query),
-                "delete from %s where objName = '%s'",tableName,metaObj->obj);
-            verbose(2, "Requesting replacement of %d rows:\n\t%s;\n",delCnt, query);
-            if(!testOnly)
-                sqlUpdate(conn, query);
-            count += delCnt;
-            }
-        }
-
-    // Now it is time for update or add!
-    for(metaVar = metaObj->vars;metaVar != NULL; metaVar = metaVar->next)
-        {
-        // Be sure to check for var existence first, then update
-        if (!replace)
-            {
-            struct metaObj *objExists = metaObjQueryByObj(conn,tableName,metaObj->obj,metaVar->var);
-            if(objExists)
-                {
-                if(differentString(metaVar->val,objExists->vars->val)
-                || metaVar->varType != objExists->vars->varType)
-                    {
-                    safef(query, sizeof(query),
-                        "update %s set varType = '%s', val = '%s' where objName = '%s' and var = '%s'",
-                            tableName,
-                            metaVarTypeEnumToString(metaVar->varType),sqlEscapeString(metaVar->val), // FIXME: binary val?
-                            metaObj->obj,metaVar->var);
-                    verbose(2, "Requesting update of 1 row:\n\t%s;\n",query);
-                    if(!testOnly)
-                        sqlUpdate(conn, query);
-                    count++;
-                    }
-                metaObjsFree(&objExists);
-                continue;  // The object was found/updated so done with it
-                }
-            }
-        // Finally ready to insert new vars
-        safef(query, sizeof(query),
-            "insert into %s values ( '%s','%s','%s','%s','%s')",
-                tableName,metaObj->obj,metaObjTypeEnumToString(metaObj->objType),
-                          metaVar->var,metaVarTypeEnumToString(metaVar->varType),
-                          sqlEscapeString(metaVar->val)); // FIXME: binary val?
-        verbose(2, "Requesting insert of one row:\n\t%s;\n",query);
-        if(!testOnly)
-            sqlUpdate(conn, query);
-        count++;
-        }
-    }
-return count;
-}
-
-// ------------------ Querys -------------------
-struct metaObj *metaObjQuery(struct sqlConnection *conn,char *table,struct metaObj *metaObj)
-// Query the metadata table by obj and optional vars and vals in metaObj struct.  If metaObj is NULL query all.
-// Returns new metaObj struct fully populated and sorted in obj,var order.
-{
-//  select objName,var,val where (var= [and val=]) or ([var= and] val=) order by objName,var
-    boolean buildHash = TRUE;
-
-    if(table == NULL)
-        table = METATBL_DEFAULT_NAME;
-
-    if(!sqlTableExists(conn,table))
-        return NULL;
-
-    struct dyString *dy = newDyString(4096);
-    dyStringPrintf(dy, "select objName,objType,var,varType,val from %s", table);
-    if(metaObj != NULL && metaObj->obj != NULL)
-        {
-        dyStringPrintf(dy, " where objName %s '%s'",
-            (strchr(metaObj->obj,'%')?"like":"="),metaObj->obj);
-
-        struct metaVar *metaVar;
-        for(metaVar=metaObj->vars;metaVar!=NULL;metaVar=metaVar->next)
-            {
-            if(metaVar==metaObj->vars)
-                dyStringPrintf(dy, " and (");
-            else
-                dyStringPrintf(dy, " or ");
-            if(metaVar->var != NULL)
-                {
-                if(metaVar->val != NULL)
-                    dyStringPrintf(dy, "(");
-                dyStringPrintf(dy, "var %s '%s'",
-                    (strchr(metaVar->var,'%')?"like":"="),metaVar->var);
-                }
-            if(metaVar->val != NULL)
-                {
-                if(metaVar->var != NULL)
-                    dyStringPrintf(dy, " and ");
-                dyStringPrintf(dy, "val %s '%s'",
-                    (strchr(metaVar->val,'%')?"like":"="), sqlEscapeString(metaVar->val));
-                if(metaVar->var != NULL)
-                    dyStringPrintf(dy, ")");
-                }
-            if(metaVar->var == NULL && metaVar->val)
-                errAbort("metaObjQuery has empty metaVar struct.\n");
-            buildHash = FALSE;  // too few variables
-            }
-        if(metaObj->vars != NULL)
-            dyStringPrintf(dy, ")");
-        }
-    dyStringPrintf(dy, " order by objName, var");
-    verbose(2, "Requesting query:\n\t%s;\n",dyStringContents(dy));
-
-    struct metaTbl *metaTbl = metaTblLoadByQuery(conn, dyStringCannibalize(&dy));
-    struct metaObj *metaObjs = metaObjsLoadFromMemory(&metaTbl,buildHash);
-    verbose(3, "Returned %d object(s) with %d var(s).\n",
-        metaObjCount(metaObjs,TRUE),metaObjCount(metaObjs,FALSE));
-    return metaObjs;
-}
-
-struct metaObj *metaObjQueryByObj(struct sqlConnection *conn,char *table,char *obj,char *var)
-// Query a single metadata object and optional var from a table (default metaTbl).
-{
-if(obj == NULL)
-    return metaObjQuery(conn,table,NULL);
-
-struct metaObj *queryObj  = metaObjCreate(obj,NULL,var,NULL,NULL);
-struct metaObj *resultObj = metaObjQuery(conn,table,queryObj);
-metaObjsFree(&queryObj);
-return resultObj;
-}
-
-struct metaByVar *metaByVarsQuery(struct sqlConnection *conn,char *table,struct metaByVar *metaByVars)
-// Query the metadata table by one or more var=val pairs to find the distinct set of objs that satisfy ANY conditions.
-// Returns new metaByVar struct fully populated and sorted in var,val,obj order.
-{
-//  select objName,var,val where (var= [and val in (val1,val2)]) or (var= [and val in (val1,val2)]) order by var,val,objName
-
-    if(table == NULL)
-        table = METATBL_DEFAULT_NAME;
-    if(!sqlTableExists(conn,table))
-        return NULL;
-
-    struct dyString *dy = newDyString(4096);
-    dyStringPrintf(dy, "select distinct objName,objType,var,varType,val from %s", table);
-
-    struct metaByVar *rootVar;
-    for(rootVar=metaByVars;rootVar!=NULL;rootVar=rootVar->next)
-        {
-        if(rootVar==metaByVars)
-            dyStringPrintf(dy, " where (var ");
-        else
-            dyStringPrintf(dy, " OR (var ");
-        if(rootVar->notEqual && rootVar->vals == NULL)
-            dyStringPrintf(dy, "NOT ");
-
-        dyStringPrintf(dy, "%s '%s'",
-            (strchr(rootVar->var,'%')?"like":"="), rootVar->var);
-
-        struct metaLimbVal *limbVal;
-        boolean multiVals = FALSE;
-        for(limbVal=rootVar->vals;limbVal!=NULL;limbVal=limbVal->next)
-            {
-            if(limbVal->val == NULL || strlen(limbVal->val) < 1)
-                continue;
-
-            if(!multiVals)
-                {
-                dyStringPrintf(dy, " and val ");
-                if(rootVar->notEqual)
-                    dyStringPrintf(dy, "NOT ");
-                if(limbVal->next == NULL) // only one val
-                    {
-                    dyStringPrintf(dy, "%s '%s'",
-                        (strchr(limbVal->val,'%')?"like":"="), sqlEscapeString(limbVal->val));
-                    break;
-                    }
-                else
-                    dyStringPrintf(dy, "in (");
-                multiVals=TRUE;
-                }
-            else
-                dyStringPrintf(dy, ",");
-            dyStringPrintf(dy, "'%s'", sqlEscapeString(limbVal->val));
-            }
-        if(multiVals)
-            dyStringPrintf(dy, ")");
-        dyStringPrintf(dy, ")");
-        }
-    dyStringPrintf(dy, " order by var, val, objName");
-    verbose(2, "Requesting query:\n\t%s;\n",dyStringContents(dy));
-
-    struct metaTbl *metaTbl = metaTblLoadByQuery(conn, dyStringCannibalize(&dy));
-    verbose(3, "rows (vars) returned: %d\n",slCount(metaTbl));
-    struct metaByVar *metaByVarsFromMem = metaByVarsLoadFromMemory(&metaTbl,TRUE);
-    verbose(3, "Returned %d vars(s) with %d val(s) with %d object(s).\n",
-        metaByVarCount(metaByVarsFromMem,TRUE ,FALSE),
-        metaByVarCount(metaByVarsFromMem,FALSE,TRUE ),
-        metaByVarCount(metaByVarsFromMem,FALSE,FALSE));
-    return metaByVarsFromMem;
-}
-
-struct metaByVar *metaByVarQueryByVar(struct sqlConnection *conn,char *table,char *varName,char *val)
-// Query a single metadata variable and optional val from a table (default metaTbl) for searching val->obj.
-{
-if(varName == NULL)
-    return metaByVarsQuery(conn,table,NULL);
-
-struct metaByVar *queryVar  = metaByVarCreate(varName,NULL,val);
-struct metaByVar *resultVar = metaByVarsQuery(conn,table,queryVar);
-metaByVarsFree(&queryVar);
-return resultVar;
-}
-
-struct metaObj *metaObjsQueryByVars(struct sqlConnection *conn,char *table,struct metaByVar *metaByVars)
-// Query the metadata table by one or more var=val pairs to find the distinct set of objs that satisfy ALL conditions.
-// Returns new metaObj struct fully populated and sorted in obj,var order.
-{
-//  select objName,var,val where (var= [and val in (val1,val2)]) or (var= [and val in (val1,val2)]) order by objName,var
-
-    if(table == NULL)
-        table = METATBL_DEFAULT_NAME;
-    if(!sqlTableExists(conn,table))
-        return NULL;
-
-    struct dyString *dy = newDyString(4096);
-    dyStringPrintf(dy, "select distinct objName,objType,var,varType,val from %s", table);
-
-    struct metaByVar *rootVar;
-    boolean gotVar = FALSE;
-    for(rootVar=metaByVars;rootVar!=NULL;rootVar=rootVar->next)
-        {
-        if(!gotVar)
-            {
-            dyStringPrintf(dy, " where objName in ");
-            gotVar=TRUE;
-            }
-        else
-            dyStringPrintf(dy, " AND objName in ");
-        dyStringPrintf(dy, "(select objName from %s where var ",table);
-
-        if(rootVar->notEqual && rootVar->vals == NULL)
-            dyStringPrintf(dy, "NOT ");
-
-        dyStringPrintf(dy, "%s '%s'",
-            (strchr(rootVar->var,'%')?"like":"="), rootVar->var);
-
-        struct metaLimbVal *limbVal;
-        boolean multiVals = FALSE;
-        for(limbVal=rootVar->vals;limbVal!=NULL;limbVal=limbVal->next)
-            {
-            if(limbVal->val == NULL || strlen(limbVal->val) < 1)
-                continue;
-
-            if(!multiVals)
-                {
-                dyStringPrintf(dy, " and val ");
-                if(rootVar->notEqual)
-                    dyStringPrintf(dy, "NOT ");
-                if(limbVal->next == NULL) // only one val
-                    {
-                    dyStringPrintf(dy, "%s '%s'",
-                        (strchr(limbVal->val,'%')?"like":"="), sqlEscapeString(limbVal->val));
-                    break;
-                    }
-                else
-                    dyStringPrintf(dy, "in (");
-                multiVals=TRUE;
-                }
-            else
-                dyStringPrintf(dy, ",");
-            dyStringPrintf(dy, "'%s'", sqlEscapeString(limbVal->val));
-            }
-        if(multiVals)
-            dyStringPrintf(dy, ")");
-        dyStringPrintf(dy, ")");
-        }
-    dyStringPrintf(dy, " order by objName, var");
-    verbose(2, "Requesting query:\n\t%s;\n",dyStringContents(dy));
-
-    struct metaTbl *metaTbl = metaTblLoadByQuery(conn, dyStringCannibalize(&dy));
-    verbose(3, "rows (vars) returned: %d\n",slCount(metaTbl));
-    struct metaObj *metaObjs = metaObjsLoadFromMemory(&metaTbl,TRUE);
-    verbose(3, "Returned %d object(s) with %d var(s).\n",
-        metaObjCount(metaObjs,TRUE),metaObjCount(metaObjs,FALSE));
-    return metaObjs;
-}
-
-
-// ----------- Printing and Counting -----------
-void metaObjPrint(struct metaObj *metaObjs,boolean raStyle)
-// prints objs and var=val pairs as formatted metadata lines or ra style
-{
-// Single line:
-//   metadata iLoveLucy table lucy=ricky ethyl=fred
-// ra style
-//   metadata iLoveLucy table
-//       lucy ricky
-//       ethy fred
-// TODO: Expand for mutilple var types; strip quotes from vals on ra style
-struct metaObj *metaObj = NULL;
-for(metaObj=metaObjs;metaObj!=NULL;metaObj=metaObj->next)
-    {
-    if(metaObj->obj == NULL)
-        continue;
-
-    printf("%s %s",(raStyle?"metaObject":"metadata"),metaObj->obj);
-    if(metaObj->deleteThis)
-        printf(" delete");
-    else
-        {
-        if(raStyle)
-            printf("\n    objType %s",metaObjTypeEnumToString(metaObj->objType));
-        else
-            printf(" %s",metaObjTypeEnumToString(metaObj->objType));
-        }
-
-    struct metaVar *metaVar = NULL;
-    for(metaVar=metaObj->vars;metaVar!=NULL;metaVar=metaVar->next)
-        {
-        if(metaVar->var != NULL)
-            {
-            if(raStyle)
-                printf("\n    %s ",metaVar->var);
-            else
-                printf(" %s=",metaVar->var);
-            if(metaVar->val != NULL)
-                {
-                if(metaVar->varType == vtBinary)
-                    printf("binary");
-                else
-                    printf("%s",metaVar->val);
-                }
-            }
-        }
-    printf("%s",(raStyle?"\n\n":"\n"));
-    }
-if(raStyle) // NOTE: currently only supporting validation of RA files
-    printf("%s%d\n",METATBL_MAGIC_PREFIX,metaObjCRC(metaObjs));
-}
-
-void metaByVarPrint(struct metaByVar *metaByVars,boolean raStyle)
-// prints var=val pairs and objs that go with them single lines or ra style
-{
-// Single line:
-//   metaVariable lucy=ethyl bestFriends lifePartners
-//   metaVariable lucy=ricky iLoveLucy divorces
-// NOT QUITE ra style
-//   metaVariable lucy
-//       ethyl
-//           bestFriends
-//           lifePartners
-//       ricky
-//           iLoveLucy
-//           divorces
-// TODO: Expand for mutilple var types; strip quotes from vals on ra style
-struct metaByVar *rootVar = NULL;
-for(rootVar=metaByVars;rootVar!=NULL;rootVar=rootVar->next)
-    {
-    if(rootVar->var == NULL)
-        continue;
-
-    boolean first = TRUE;
-    struct metaLimbVal *limbVal = NULL;
-    for(limbVal=rootVar->vals;limbVal!=NULL;limbVal=limbVal->next)
-        {
-        if(limbVal->val == NULL)
-            continue;
-
-        if(first) // first val for this var
-            {
-            printf("metaVariable %s",rootVar->var);
-            first = FALSE;
-            }
-
-        if(rootVar->varType == vtBinary)
-            printf("%sbinary",(raStyle ? "\n    ":"="));
-        else
-            printf("%s%s",(raStyle ? "\n    ":"="),limbVal->val);
-
-        struct metaLeafObj *leafObj = NULL;
-        for(leafObj=limbVal->objs;leafObj!=NULL;leafObj=leafObj->next)
-            {
-            if(leafObj->obj == NULL)
-                continue;
-
-            printf("%s%s",(raStyle?"\n        ":" "),leafObj->obj);
-            }
-        printf("\n");
-        }
-    }
-}
-
-
-int metaObjCount(struct metaObj *metaObjs,boolean objs)
-// returns the count of vars belonging to this obj or objs;
-{
-int count = 0;
-struct metaObj *metaObj = NULL;
-for(metaObj=metaObjs;metaObj!=NULL;metaObj=metaObj->next)
-    {
-    if(metaObj->obj == NULL)
-        continue;
-    if(objs)
-        count++;
-    else
-        {
-        struct metaVar *metaVar = NULL;
-        for(metaVar=metaObj->vars;metaVar!=NULL;metaVar=metaVar->next)
-            {
-            if(metaVar->var != NULL && metaVar->val != NULL)
-                count++;
-            }
-        }
-    }
-
-return count;
-}
-
-int metaByVarCount(struct metaByVar *metaByVars,boolean vars, boolean vals)
-// returns the count of objs belonging to this set of vars;
-{
-int count = 0;
-struct metaByVar *rootVar = NULL;
-for(rootVar=metaByVars;rootVar!=NULL;rootVar=rootVar->next)
-    {
-    if(rootVar->var == NULL)
-        continue;
-    if(vars)
-        count++;
-    else
-        {
-        struct metaLimbVal *limbVal = NULL;
-        for(limbVal=rootVar->vals;limbVal!=NULL;limbVal=limbVal->next)
-            {
-            if(limbVal->val == NULL)
-                continue;
-            if(vals)
-                count++;
-            else
-                {
-                struct metaLeafObj *leafObj = NULL;
-                for(leafObj=limbVal->objs;leafObj!=NULL;leafObj=leafObj->next)
-                    {
-                    if(leafObj->obj != NULL)
-                        count++;
-                    }
-                }
-            }
-        }
-    }
-return count;
-}
-
-// ----------------- Utilities -----------------
-
-char *metaObjFindValue(struct metaObj *metaObj, char *var)
-// Finds the val associated with the var or retruns NULL
-{
-if (metaObj == NULL)
-    return NULL;
-
-struct metaVar *metaVar = NULL;
-if(metaObj->varHash != NULL)
-    metaVar = hashFindVal(metaObj->varHash,var);
-else
-    {
-    for(metaVar=metaObj->vars;metaVar!=NULL;metaVar=metaVar->next)
-        {
-        if(sameOk(var,metaVar->var))
-            break;
-        }
-    }
-if(metaVar == NULL)
-    return NULL;
-
-return metaVar->val;
-}
-
-boolean metaObjContains(struct metaObj *metaObj, char *var, char *val)
-// Returns TRUE if object contains var, val or both
-{
-if (metaObj == NULL)
-    return FALSE;
-
-if(var != NULL)
-    {
-    char *foundVal = metaObjFindValue(metaObj,var);
-    if(foundVal == NULL)
-        return FALSE;
-    if(val == NULL)
-        return TRUE;
-    return sameOk(foundVal,val);
-    }
-struct metaVar *metaVar = NULL;
-for(metaVar=metaObj->vars;metaVar!=NULL;metaVar=metaVar->next)
-    {
-    if(differentStringNullOk(var,metaVar->var) != 0)
-        continue;
-    if(differentStringNullOk(val,metaVar->val) != 0)
-        continue;
-    return TRUE;
-    }
-
-return FALSE;
-}
-
-boolean metaByVarContains(struct metaByVar *metaByVar, char *val, char *obj)
-// Returns TRUE if var contains val, obj or both
-{
-if (metaByVar != NULL)
-    {
-    struct metaLimbVal *limbVal = NULL;
-    struct metaLeafObj *leafObj = NULL;
-    if(metaByVar->valHash != NULL && val != NULL)
-        {
-        limbVal = hashFindVal(metaByVar->valHash,val);
-        if(limbVal == NULL || limbVal->val == NULL)
-            return FALSE;
-        if(limbVal->objHash != NULL && obj != NULL)
-            {
-            leafObj = hashFindVal(limbVal->objHash,obj);
-            if(leafObj == NULL)
-                return FALSE;
-            return sameOk(leafObj->obj,obj);
-            }
-        }
-    for(limbVal=metaByVar->vals;limbVal!=NULL;limbVal=limbVal->next)
-        {
-        if(differentStringNullOk(val,limbVal->val) != 0)
-            continue;
-
-        for(leafObj=limbVal->objs;leafObj!=NULL;leafObj=leafObj->next)
-            {
-            if(differentStringNullOk(obj,leafObj->obj) != 0)
-                continue;
-            return TRUE;
-            }
-        }
-    }
-return FALSE;
-}
-
-void metaObjReorderVars(struct metaObj *metaObjs, char *vars,boolean back)
-// Reorders vars list based upon list of vars "cell antibody treatment".  Send to front or back.
-{
-//char *words[48];
-char *cloneLine = cloneString(vars);
-int count = chopByWhite(cloneLine,NULL,0);
-char **words = needMem(sizeof(char *) * count);
-count = chopByWhite(cloneLine,words,count);
-//int count = chopLine(cloneLine,words);
-
-struct metaObj *metaObj = NULL;
-for( metaObj=metaObjs; metaObj!=NULL; metaObj=metaObj->next )
-    {
-    int ix;
-    struct metaVar *orderedVars = NULL;
-    struct metaVar **varsToReorder = needMem(sizeof(struct metaVar *) * count);
-
-    struct metaVar *metaVar = NULL;
-    while((metaVar = slPopHead(&(metaObj->vars))) != NULL)
-        {
-        ix = stringArrayIx(metaVar->var,words,count);
-        if(ix < 0)
-            slAddHead(&orderedVars,metaVar);
-        else
-            varsToReorder[ix] = metaVar;
-        }
-
-    if(back) // add to front of backward list
-        {
-        for( ix=0; ix<count; ix++ )
-            {
-            if(varsToReorder[ix] != NULL)
-                slAddHead(&orderedVars,varsToReorder[ix]);
-            }
-        }
-    slReverse(&orderedVars);
-
-    if(!back)  // Add to front of forward list
-        {
-        for( ix=count-1; ix>=0; ix-- )
-            {
-            if(varsToReorder[ix] != NULL)
-                slAddHead(&orderedVars,varsToReorder[ix]);
-            }
-        }
-
-    metaObj->vars = orderedVars;
-    freeMem(varsToReorder);
-    }
-    freeMem(words);
-}
-
-void metaObjRemoveVars(struct metaObj *metaObjs, char *vars)
-// Prunes list of vars for an object, freeing the memory.  Doesn't touch DB.
-{
-char *cloneLine = NULL;
-int count = 0;
-char **words = NULL;
-if(vars != NULL)
-    {
-    cloneLine = cloneString(vars);
-    count = chopByWhite(cloneLine,NULL,0);
-    words = needMem(sizeof(char *) * count);
-    count = chopByWhite(cloneLine,words,count);
-    }
-struct metaObj *metaObj = NULL;
-for( metaObj=metaObjs; metaObj!=NULL; metaObj=metaObj->next )
-    {
-    int ix;
-    struct metaVar *keepTheseVars = NULL;
-
-    if(count == 0 && metaObj->varHash != NULL)
-        hashFree(&metaObj->varHash);
-
-    struct metaVar *metaVar = NULL;
-    while((metaVar = slPopHead(&(metaObj->vars))) != NULL)
-        {
-        if(count == 0)
-            ix = 1;
-        else
-            ix = stringArrayIx(metaVar->var,words,count);
-        if(ix < 0)
-            slAddHead(&keepTheseVars,metaVar);
-        else
-            {
-            if(count != 0 && metaObj->varHash != NULL)
-                hashRemove(metaObj->varHash, metaVar->var);
-
-            metaVarFree(&metaVar);
-            }
-        }
-
-    if(keepTheseVars != NULL)
-        slReverse(&keepTheseVars);
-    metaObj->vars = keepTheseVars;
-    }
-    if(words != NULL)
-        freeMem(words);
-}
-
-void metaObjSwapVars(struct metaObj *metaObjs, char *vars,boolean deleteThis)
-// Replaces objs' vars with var=vap pairs provided, preparing for DB update.
-{
-struct metaObj *metaObj = NULL;
-for( metaObj=metaObjs; metaObj!=NULL; metaObj=metaObj->next )
-    {
-    metaObj->deleteThis = deleteThis;
-
-    if(metaObj->varHash != NULL)
-        hashFree(&metaObj->varHash);
-
-    struct metaVar *metaVar = NULL;
-    while((metaVar = slPopHead(&(metaObj->vars))) != NULL)
-        metaVarFree(&metaVar);
-
-    metaObjAddVarPairs(metaObj,vars);
-    }
-}
-
-void metaObjTransformToUpdate(struct metaObj *metaObjs, char *var, char *varType,char *val,boolean deleteThis)
-// Turns one or more metaObjs into the stucture needed to add/update or delete.
-{
-struct metaObj *metaObj = NULL;
-for( metaObj=metaObjs; metaObj!=NULL; metaObj=metaObj->next )
-    {
-    metaObj->deleteThis = deleteThis;
-
-    if(metaObj->varHash != NULL)
-        hashFree(&metaObj->varHash);
-
-    struct metaVar *metaVar = NULL;
-    while((metaVar = slPopHead(&(metaObj->vars))) != NULL)
-        metaVarFree(&metaVar);
-
-    if(var != NULL)
-        {
-        AllocVar(metaVar);
-
-        metaVar->var     = cloneString(var);
-        metaVar->varType = (varType==NULL?vtUnknown:metaVarTypeStringToEnum(varType));
-        if(val != NULL)
-            metaVar->val     = cloneString(val);
-        metaObj->vars = metaVar; // Only one
-        }
-    }
-}
-
-struct metaObj *metaObjClone(const struct metaObj *metaObj)
-// Clones a single metaObj, including hash and maintining order
-{
-if(metaObj == NULL)
-    return NULL;
-
-struct metaObj *newObj;
-AllocVar(newObj);
-
-if(metaObj->obj != NULL)
-    newObj->obj    = cloneString(metaObj->obj);
-newObj->objType    = metaObj->objType;
-newObj->deleteThis = metaObj->deleteThis;
-if(metaObj->vars != NULL)
-    {
-    if(metaObj->varHash != NULL)
-        newObj->varHash = hashNew(0);
-
-    struct metaVar *metaVar = NULL;
-    for(metaVar = metaObj->vars; metaVar != NULL; metaVar = metaVar->next )
-        {
-        struct metaVar *newVar = NULL;
-        AllocVar(newVar);
-        if(metaVar->var != NULL)
-            newVar->var = cloneString(metaVar->var);
-        if(metaVar->val != NULL)
-            newVar->val = cloneString(metaVar->val);
-        newVar->varType    = metaVar->varType;
-        if(newVar->var != NULL && newVar->val != NULL)
-            hashAdd(newObj->varHash, newVar->var, newVar); // pointer to struct to resolve type
-        slAddHead(&(newObj->vars),newVar);
-        }
-    slReverse(&(newObj->vars));
-    }
-return newObj;
-}
-
-// --------------- Free at last ----------------
-void metaObjsFree(struct metaObj **metaObjsPtr)
-// Frees one or more metadata objects and any contained metaVars.  Will free any hashes as well.
-{
-
-if(metaObjsPtr != NULL && *metaObjsPtr != NULL)
-    {
-    // free all roots
-    struct metaObj *metaObj = NULL;
-    while((metaObj = slPopHead(metaObjsPtr)) != NULL)
-        {
-        // Free hash first (shared memory)
-        hashFree(&(metaObj->varHash));
-
-        // free all leaves
-        struct metaVar *metaVar = NULL;
-        while((metaVar = slPopHead(&(metaObj->vars))) != NULL)
-            metaVarFree(&metaVar);
-
-        // The rest of root
-        freeMem(metaObj->obj);
-        freeMem(metaObj);
-        }
-    freez(metaObjsPtr);
-    }
-}
-
-void metaByVarsFree(struct metaByVar **metaByVarsPtr)
-// Frees one or more metadata vars and any contained vals and objs.  Will free any hashes as well.
-{
-if(metaByVarsPtr != NULL && *metaByVarsPtr != NULL)
-    {
-    // free all roots
-    struct metaByVar *rootVar = NULL;
-    while((rootVar = slPopHead(metaByVarsPtr)) != NULL)
-        {
-        // Free hash first (shared memory)
-        hashFree(&(rootVar->valHash));
-
-        // free all limbs
-        struct metaLimbVal *limbVal = NULL;
-        while((limbVal = slPopHead(&(rootVar->vals))) != NULL)
-            metaLimbValFree(&limbVal);
-
-        // The rest of root
-        if(rootVar->var)
-            freeMem(rootVar->var);
-        freeMem(rootVar);
-        }
-    freez(metaByVarsPtr);
-    }
-}
-
-// ----------------- CGI specific routines for use with tdb -----------------
-#define METATBL_NOT_FOUND ((struct metaObj *)-666)
-#define METADATA_NOT_FOUND ((struct metaObj *)-999)
-#define METATBL_OBJ_KEY "metaObj"
-static struct metaObj *metadataForTableFromTdb(struct trackDb *tdb)
-// Returns the metadata for a table from a tdb setting.
-{
-char *setting = trackDbSetting(tdb, "metadata");
-if(setting == NULL)
-    return NULL;
-struct metaObj *metaObj;
-AllocVar(metaObj);
-metaObj->obj     = cloneString(tdb->table);
-metaObj->objType = otTable;
-return metaObjAddVarPairs(metaObj,setting);
-}
-
-const struct metaObj *metadataForTable(char *db,struct trackDb *tdb,char *table)
-// Returns the metadata for a table.  NEVER FREE THIS STRUCT!
-{
-struct metaObj *metaObj = NULL;
-
-// See of the metaObj was already built
-if(tdb != NULL)
-    {
-    metaObj = tdbExtrasGetOrDefault(tdb, METATBL_OBJ_KEY,NULL);
-    if(metaObj == METADATA_NOT_FOUND) // NOT in mtatbl, not in tdb metadata setting!
-        return NULL;
-    else if(metaObj == METATBL_NOT_FOUND) // looked metaTbl already and not found!
-        return metadataForTableFromTdb(tdb);
-    else if(metaObj != NULL)
-        {
-        return metaObj;  // No reason to query the table again!
-        }
-    }
-
-struct sqlConnection *conn = sqlConnect(db);
-char *metaTbl = metaTblName(conn,TRUE);  // Look for sandbox name first
-if(tdb != NULL && tdb->table != NULL)
-    table = tdb->table;
-if(metaTbl != NULL)
-    metaObj = metaObjQueryByObj(conn,metaTbl,table,NULL);
-sqlDisconnect(&conn);
-
-// save the metaObj for next time
-if(tdb)
-    {
-    if(metaObj != NULL)
-        tdbExtrasAddOrUpdate(tdb,METATBL_OBJ_KEY,metaObj);
-    else
-        {
-        tdbExtrasAddOrUpdate(tdb,METATBL_OBJ_KEY,METATBL_NOT_FOUND);
-        return metadataForTableFromTdb(tdb);  // FIXME: metadata setting in TDB is soon to be obsolete
-        }
-    }
-
-// FIXME: Temporary to distinguish metaTbl metadata from trackDb metadata:
-metaObjRemoveVars(metaObj,"tableName");
-
-
-return metaObj;
-}
-
-const char *metadataFindValue(struct trackDb *tdb, char *var)
-// Finds the val associated with the var or retruns NULL
-{
-struct metaObj *metaObj = tdbExtrasGetOrDefault(tdb, METATBL_OBJ_KEY,NULL);
-if(metaObj == METATBL_NOT_FOUND) // Note, only we if already looked for metaTbl (which requires db)
-    metaObj = metadataForTableFromTdb(tdb);
-if (metaObj == NULL || metaObj == METADATA_NOT_FOUND)
-    return NULL;
-
-return metaObjFindValue(metaObj,var);
-
-struct metaVar *metaVar = NULL;
-if(metaObj->varHash != NULL)
-    metaVar = hashFindVal(metaObj->varHash,var);
-else
-    {
-    for(metaVar=metaObj->vars;metaVar!=NULL;metaVar=metaVar->next)
-        {
-        if(sameOk(var,metaVar->var))
-            break;
-        }
-    }
-if(metaVar == NULL)
-    return NULL;
-
-return metaVar->val;
-}
-