a1beb926d542ef1afff071ff4cbfc4851af24744 tdreszer Mon Nov 22 11:54:46 2010 -0800 Support for searchable freeText in cv.ra diff --git src/hg/lib/mdb.c src/hg/lib/mdb.c index 1564f1d..9e29f15 100644 --- src/hg/lib/mdb.c +++ src/hg/lib/mdb.c @@ -1998,49 +1998,51 @@ } const char *metadataFindValue(struct trackDb *tdb, char *var) // Finds the val associated with the var or retruns NULL { struct mdbObj *mdbObj = tdbExtrasGetOrDefault(tdb, MDB_OBJ_KEY,NULL); if(mdbObj == MDB_NOT_FOUND) // Note, only we if already looked for mdb (which requires db) mdbObj = metadataForTableFromTdb(tdb); if (mdbObj == NULL || mdbObj == METADATA_NOT_FOUND) return NULL; return mdbObjFindValue(mdbObj,var); } struct slName *mdbObjSearch(struct sqlConnection *conn, char *var, char *val, char *op, int limit, boolean tables, boolean files) -// Search the metaDb table for objs by var and val. Can restrict by op "is" or "like" and accept (non-zero) limited string size +// Search the metaDb table for objs by var and val. Can restrict by op "is", "like", "in" and accept (non-zero) limited string size // Search is via mysql, so it's case-insensitive. Return is sorted on obj. { // TODO: Change this to use normal mdb struct routines? if (!tables && !files) errAbort("mdbObjSearch requests objects for neither tables or files.\n"); char *tableName = mdbTableName(conn,TRUE); // Look for sandBox name first struct dyString *dyQuery = dyStringNew(512); dyStringPrintf(dyQuery,"select distinct obj from %s l1 where ",tableName); if (!tables || !files) { dyStringPrintf(dyQuery,"l1.var='objType' and l1.val='%s' ",tables?"table":"file"); dyStringPrintf(dyQuery,"and exists (select l2.obj from %s l2 where l2.obj = l1.obj and ",tableName); } if(var != NULL) dyStringPrintf(dyQuery,"l2.var = '%s' and l2.val ", var); -if(sameString(op, "contains")) +if(sameString(op, "in")) + dyStringPrintf(dyQuery,"in (%s)", val); // Note, must be a formatted string already: 'a','b','c' or 1,2,3 +else if(sameString(op, "contains") || sameString(op, "like")) dyStringPrintf(dyQuery,"like '%%%s%%'", val); else if (limit > 0 && strlen(val) == limit) dyStringPrintf(dyQuery,"like '%s%%'", val); else dyStringPrintf(dyQuery,"= '%s'", val); if (!tables || !files) dyStringAppendC(dyQuery,')'); dyStringAppend(dyQuery," order by obj"); return sqlQuickList(conn, dyStringCannibalize(&dyQuery)); } struct slName *mdbValSearch(struct sqlConnection *conn, char *var, int limit, boolean tables, boolean files) // Search the metaDb table for vals by var. Can impose (non-zero) limit on returned string size of val @@ -2137,78 +2139,107 @@ freeMem(pair->name); // Allocated when pair was created pair->name = strSwapChar(cloneString(label),'_',' '); // vestigial _ meaning space if (limit > 0 && strlen(pair->name) > limit) pair->name[limit] = '\0'; } } slAddHead(&pairs, pair); } sqlFreeResult(&sr); slPairSortCase(&pairs); return pairs; } struct hash *mdbCvTermTypeHash() // returns a hash of hashes of mdb and controlled vocabulary (cv) term types -// Those terms should contain label,descrition,searchable,cvDefined,hidden +// Those terms should contain label,description,searchable,cvDefined,hidden { static struct hash *cvHashOfTermTypes = NULL; // Establish cv hash of Term Types if it doesn't already exist if (cvHashOfTermTypes == NULL) { cvHashOfTermTypes = raReadWithFilter(cv_file(), "term","type","typeOfTerm"); // Patch up an ugly inconsistency with 'cell' struct hash *cellHash = hashRemove(cvHashOfTermTypes,"cellType"); if (cellHash) { hashAdd(cvHashOfTermTypes,"cell",cellHash); hashReplace(cellHash, "term", cloneString("cell")); // spilling memory of 'cellType' val } } return cvHashOfTermTypes; } struct slPair *mdbCvWhiteList(boolean searchTracks, boolean cvDefined) // returns the official mdb/controlled vocabulary terms that have been whitelisted for certain uses. +// TODO: change to return struct that includes searchable! { struct slPair *whitePairs = NULL; // Get the list of term types from thew cv struct hash *termTypeHash = mdbCvTermTypeHash(); struct hashCookie hc = hashFirst(termTypeHash); struct hashEl *hEl; while ((hEl = hashNext(&hc)) != NULL) { char *setting = NULL; struct hash *typeHash = (struct hash *)hEl->val; //if (!includeHidden) { setting = hashFindVal(typeHash,"hidden"); if(SETTING_IS_ON(setting)) continue; } if (searchTracks) { setting = hashFindVal(typeHash,"searchable"); +#ifdef CV_SEARCH_SUPPORTS_FREETEXT + if (setting == NULL + || (differentWord(setting,"select") && differentWord(setting,"freeText"))) +#else///ifndef CV_SEARCH_SUPPORTS_FREETEXT if (setting == NULL || differentWord(setting,"select")) // TODO: Currently only 'select's are supported +#endif///ndef CV_SEARCH_SUPPORTS_FREETEXT continue; } if (cvDefined) { setting = hashFindVal(typeHash,"cvDefined"); if(SETTING_NOT_ON(setting)) continue; } char *term = hEl->name; char *label = hashFindVal(typeHash,"label"); if (label == NULL) label = term; slPairAdd(&whitePairs, term, cloneString(label)); // Term gets cloned in slPairAdd } if (whitePairs != NULL) slPairValSortCase(&whitePairs); return whitePairs; } + +#ifdef CV_SEARCH_SUPPORTS_FREETEXT +enum mdbCvSearchable mdbCvSearchMethod(char *term) +// returns whether the term is searchable // TODO: replace with mdbCvWhiteList() returning struct +{ +// Get the list of term types from thew cv +struct hash *termTypeHash = mdbCvTermTypeHash(); +struct hash *termHash = hashFindVal(termTypeHash,term); +if (termHash != NULL) + { + char *searchable = hashFindVal(termHash,"searchable"); + if (searchable != NULL) + { + if (sameWord(searchable,"select")) + return cvsSearchBySingleSelect; + if (sameWord(searchable,"freeText")) + return cvsSearchByFreeText; + } + } +return cvsNotSearchable; +} +#endif///ndef CV_SEARCH_SUPPORTS_FREETEXT +