9b13731e6e466aa0f781179da2d504db2f4c15a9 tdreszer Wed Mar 30 11:28:34 2011 -0700 Made slPairListFromString and slPairListToString optionally handle double quotes. Finally made mdbObjReorderByCv so that priority in cv.ra typeOfTerms is used. diff --git src/hg/lib/mdb.c src/hg/lib/mdb.c index 2f997a6..dcd50a3 100644 --- src/hg/lib/mdb.c +++ src/hg/lib/mdb.c @@ -727,55 +727,56 @@ // Not found so add it struct mdbByVar *newVar = mdbByVarCreate(var, val); newVar->notEqual = notEqual; slAddTail(&mdbByVars,newVar); // Add to tail to avoid changing passed in pointer return TRUE; } struct mdbObj *mdbObjCreate(char *obj,char *var, char *val) /* Creates a singular mdbObj query object based on obj and all other optional params. */ { struct mdbObj *mdbObj = NULL; if(obj == NULL) - errAbort("Need obj to create mdbObj query object.\n"); + errAbort("Need obj to create mdbObj object.\n"); AllocVar(mdbObj); mdbObj->obj = cloneString(obj); if(var != NULL) { struct mdbVar * mdbVar; AllocVar(mdbVar); mdbVar->var = cloneString(var); if(val != NULL) mdbVar->val = cloneString(val); mdbObj->vars = mdbVar; // Only one } return mdbObj; } struct mdbObj *mdbObjNew(char *obj,struct mdbVar *mdbVars) // Returns a new mdbObj with whatever was passed in. // An mdbObj requires and obj, so if one is not supplied it will be "[unknown]" { struct mdbObj *mdbObj = NULL; if (obj == NULL) - obj = "[unknown]"; + errAbort("Need obj to create mdbObj object.\n"); + if (mdbVars == NULL) { AllocVar(mdbObj); mdbObj->obj = cloneString(obj); return mdbObj; } else { mdbObj = mdbObjCreate(obj,mdbVars->var,mdbVars->val); mdbObj->varHash = hashNew(0); hashAddUnique(mdbObj->varHash, mdbVars->var, mdbObj->vars); // pointer to struct to resolve type struct mdbVar *var = mdbVars->next; for(;var != NULL;var = var->next); mdbObjSetVar(mdbObj, var->var,var->val); @@ -1412,31 +1413,31 @@ // var5!=val5 : matches not equal. // var6= : matches that var exists (same as var6=%). var6!= also works. { struct mdbByVar *mdbByVars = mdbByVarsLineParse(varVals); if (mdbByVars == NULL) return NULL; return mdbObjsQueryByVars(conn,tableName,mdbByVars); } struct mdbObj *mdbObjsQueryByVarPairs(struct sqlConnection *conn,char *tableName,struct slPair *varValPairs) // returns mdbObjs matching varValPairs provided. // The != logic of mdbObjsQueryByVarValString() is not possible, but other cases are supported: // as val may be NULL, a comma delimited list, double quoted string, containing wilds: % and ? { // Note: there is a bit of inefficiency creating a string then tearing it down, but it streamlines code -char *varValString = slPairListToString(varValPairs); +char *varValString = slPairListToString(varValPairs,TRUE); // quotes added when spaces found struct mdbObj *mdbObjs = mdbObjsQueryByVarValString(conn,tableName,varValString); freeMem(varValString); return mdbObjs; } struct mdbObj *mdbObjQueryCompositeObj(struct sqlConnection *conn,char *tableName,struct mdbObj *mdbObj) // returns NULL or the composite mdbObj associated with the object passed in. { char *objType = mdbObjFindValue(mdbObj,MDB_OBJ_TYPE); assert(objType != NULL); if (sameWord(objType,MDB_VAR_COMPOSITE)) return mdbObjClone(mdbObj); char *compName = mdbObjFindValue(mdbObj,MDB_VAR_COMPOSITE); if (compName == NULL) return NULL; @@ -1895,30 +1896,64 @@ if(!back) // Add to front of forward list { for( ix=count-1; ix>=0; ix-- ) { if(varsToReorder[ix] != NULL) slAddHead(&orderedVars,varsToReorder[ix]); } } mdbObj->vars = orderedVars; freeMem(varsToReorder); } freeMem(words); } +void mdbObjReorderByCv(struct mdbObj *mdbObjs, boolean includeHidden) +// Reorders vars list based upon cv.ra typeOfTerms priority +{ +struct hash *cvTermTypes = (struct hash *)cvTermTypeHash(); +struct hashEl *el, *elList = hashElListHash(cvTermTypes); + +struct slPair *cvVars = NULL; +for (el = elList; el != NULL; el = el->next) + { + struct hash *varHash = el->val; + if (includeHidden || SETTING_NOT_ON(hashFindVal(varHash, CV_TOT_HIDDEN))) // Skip the hidden ones + { + char *priority = hashFindVal(varHash, CV_TOT_PRIORITY); + if (priority != NULL) // If there is no priority it will randomly fall to the back of the list + slPairAdd(&cvVars,el->name,(char *)sqlUnsignedLong(priority)); + } + } +hashElFreeList(&elList); + +if (cvVars) + { + slPairIntSort(&cvVars); // sorts on the integer val + + // Now convert this to a string of names + char *orderedVars = slPairNameToString(cvVars,' ',FALSE); + slPairFreeList(&cvVars); + if (orderedVars != NULL) + { + mdbObjReorderVars(mdbObjs, orderedVars,FALSE); // Finally we can reorder the vars in the mdbObjs + freeMem(orderedVars); + } + } +} + int mdbObjVarCmp(const void *va, const void *vb) /* Compare to sort on full list of vars and vals. */ { const struct mdbObj *a = *((struct mdbObj **)va); const struct mdbObj *b = *((struct mdbObj **)vb); struct mdbVar* aVar = a->vars; struct mdbVar* bVar = b->vars; for(;aVar != NULL && bVar != NULL;aVar=aVar->next,bVar=bVar->next) { int ret = differentWord(aVar->var, bVar->var); // case insensitive if(ret != 0) { // Look for it by walking vars struct mdbVar* tryVar = bVar->next; for(;tryVar;tryVar=tryVar->next) @@ -1962,30 +1997,38 @@ // This method will use mdbObjsSortOnVars() { if (varValPairs == NULL) return; struct slPair *onePair = varValPairs; struct dyString *dyTerms = dyStringNew(256); dyStringAppend(dyTerms,onePair->name); onePair = onePair->next; for(; onePair != NULL; onePair = onePair->next) dyStringPrintf(dyTerms,",%s",onePair->name); mdbObjsSortOnVars(mdbObjs,dyStringContents(dyTerms)); dyStringFree(&dyTerms); } +void mdbObjsSortOnCv(struct mdbObj **mdbObjs, boolean includeHidden) +// Puts obj->vars in order based upon cv.ra typeOfTerms priority, +// then case-sensitively sorts all objs in list based upon that var order. +{ // NOTE: assumes all var pairs match (e.g. every obj has cell,treatment,antibody,... and missing treatment messes up sort) +mdbObjReorderByCv(*mdbObjs, includeHidden); +slSort(mdbObjs, mdbObjVarCmp); // While sort will not be perfect (given missing values) it does a good job none the less. +} + void mdbObjRemoveVars(struct mdbObj *mdbObjs, 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 mdbObj *mdbObj = NULL; for( mdbObj=mdbObjs; mdbObj!=NULL; mdbObj=mdbObj->next )