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;ixvar = 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;thisWordvar = 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=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; -} -