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
+