b33e4b8402b46121cf4eab8eb9281c6b28576c25
chmalee
  Wed Jul 24 16:49:19 2024 -0700
Make knownGene handled like regular tracks by hgSearch, refs #33774

diff --git src/hg/lib/hgFind.c src/hg/lib/hgFind.c
index 677a1cb..5003ff1 100644
--- src/hg/lib/hgFind.c
+++ src/hg/lib/hgFind.c
@@ -2935,31 +2935,30 @@
 struct slName *tbl, *tblList = hTrackDbList();
 for (tbl = tblList; tbl != NULL; tbl = tbl->next)
     {
     char *tdbName, *findSpecName;
     tdbName = tbl->name;
     findSpecName = replaceChars(tbl->name, "trackDb", "hgFindSpec");
     if (hTableExists(database, findSpecName))
         {
         char query[1024];
         sqlSafef(query, sizeof(query), "select distinct "
             "tableName,shortLabel,longLabel,searchDescription,priority "
             "from %s join %s on "
             "%s.searchTable=%s.tableName or "
             "%s.searchName=%s.tableName or "
             "%s.searchTable = concat('all_', %s.tableName) "
-            "where searchTable !='knownGene' and searchName != 'knownGene' "
             "order by priority,shortLabel",
             findSpecName, tdbName, findSpecName, tdbName, findSpecName, tdbName, findSpecName, tdbName);
         struct sqlResult *sr = sqlGetResult(conn, query);
         char **row = NULL;
         struct trackDb *tdb = NULL;
         while ( (row = sqlNextRow(sr)) != NULL)
             {
             if ( (tdb = hashFindVal(hgFindTrackHash, row[0])) != NULL)
                 {
                 struct searchableTrack *track = NULL;
                 AllocVar(track);
                 track->track = cloneString(row[0]);
                 track->shortLabel = cloneString(row[1]);
                 track->longLabel = cloneString(row[2]);
                 track->description = cloneString(row[3]);
@@ -3133,44 +3132,52 @@
     struct hashEl *hel, *helList = hashElListHash(hgFindTrackHash);
     for (hel = helList; hel != NULL; hel = hel->next)
         {
         struct trackDb *tdb = hel->val;
         if (isTdbSearchable(tdb) && sameString(tdb->grp, categName))
             {
             struct searchCategory *temp = makeCategoryForTrack(tdb, searchTrack);
             if (temp)
                 slAddHead(&ret, temp);
             }
         }
     }
 else
     {
     // must be a track, ret will contain subtracks if necessary
-    struct trackDb *tdb = hashFindVal(hgFindTrackHash, categName);
+    // sometimes duplicate tracks point to the same (eg knownGeneAlpha and knownGene)
+    // this shouldn't happen anymore due to cartTrackDb.c:hashTdbNames() changes, but
+    // just in case it pops up again this code will stay
+    struct hashEl *hel = hashLookup(hgFindTrackHash, categName);
+    while (hel != NULL)
+        {
+        struct trackDb *tdb = hel->val;
         if (tdb)
-        ret = makeCategoryForTrack(tdb, searchTrack);
+            {
+            struct searchCategory *temp = makeCategoryForTrack(tdb, searchTrack);
+            slAddHead(&ret, temp);
+            }
+        hel = hashLookupNext(hel);
+        }
     }
 return ret;
 }
 
 struct searchCategory *getCategsForNonDb(struct cart *cart, char *db, struct hash *groupHash)
 /* Return the default categories for all databases */
 {
 struct searchCategory *ret = NULL;
-struct searchCategory *kgCategory = makeCategory(cart, "knownGene", NULL, db, groupHash);
-if (kgCategory)
-    slAddHead(&ret, kgCategory);
 struct searchCategory *helpDocCategory = makeCategory(cart, "helpDocs", NULL, db, groupHash);
 if (helpDocCategory)
     slAddHead(&ret, helpDocCategory);
 struct searchCategory *publicHubCategory = makeCategory(cart, "publicHubs", NULL, db, groupHash);
 if (publicHubCategory)
     slAddHead(&ret, publicHubCategory);
 char trackDbIndexName[2048];
 safef(trackDbIndexName, sizeof(trackDbIndexName), "trackDb%s", db);
 struct searchCategory *tdbCategory = makeCategory(cart, trackDbIndexName, NULL, db, groupHash);
 if (tdbCategory)
     slAddHead(&ret, tdbCategory);
 return ret;
 }
 
 static struct searchableTrack *makeGenbankSearchableTrack(struct trackDb *tdb, struct cart *cart)
@@ -3458,31 +3465,31 @@
     {
     boolean foundSpec = hgFindUsingSpec(cart, db, hfs, term, limitResults, hgp, FALSE, 0, 0, multiTerm, measureTiming);
     if (foundSpec)
         hashAdd(foundSpecHash, hfs->searchTable, hfs->searchTable);
     foundIt |= foundSpec;
 
     // for multiTerm searches (like '15q11;15q13'), each individual component
     // must resolve to a single position, so break once we find the first match
     if (multiTerm && foundSpec)
         break;
     }
 if (!(multiTerm) || (multiTerm && !foundIt))
     {
     for (hfs = longList; hfs != NULL; hfs = hfs->next)
         {
-        if (hashFindVal(foundSpecHash, hfs->searchTable) != NULL && !sameString(hfs->searchTable, "knownGene"))
+        if (hashFindVal(foundSpecHash, hfs->searchTable) != NULL)
             continue;
         foundIt |= hgFindUsingSpec(cart, db, hfs, term, limitResults, hgp, FALSE, 0, 0, multiTerm, measureTiming);
         }
     // lastly search any included track hubs, or in the case of an assembly hub, any of the tracks
     if (hubCategoryList)
         foundIt |= findBigBedPosInTdbList(cart, db, hubCategoryList, term, hgp, NULL, measureTiming);
     }
 
 // multiTerm searches must resolve to a single range on a chromosome, so don't
 // do these non positional searches if a multiTerm was requested
 if (!multiTerm)
     {
     getLabelsForHubs();
     struct searchCategory *category;
     for (category = categories; category != NULL; category = category->next)