a48e4a31e870414b9ed4a9731bf4ca694e6ff008
chmalee
  Wed Oct 30 11:36:15 2019 -0700
Fixes to hub searching after code review: Angie noticed that links were broken due to a bug, but it turns out they were broken in a much bigger way as subtrack search hits were not linking out to the right parent tracks. This has been fixed by adding a new column to the hubSearchText table to encode the parent type of the parent tracks (comp, super, etc), and then building the links the correct way, refs #24338

diff --git src/hg/utils/hubCrawl/hubCrawl.c src/hg/utils/hubCrawl/hubCrawl.c
index 5536627..650f286 100644
--- src/hg/utils/hubCrawl/hubCrawl.c
+++ src/hg/utils/hubCrawl/hubCrawl.c
@@ -87,55 +87,73 @@
         char *dbName, FILE *searchFp, struct hash *visitedTracks)
 /* Given a trackDb and the hub genome it comes from, write out hubSearchText lines for all of
  * the tracks in that trackDb */
 {
 if (hashLookup(visitedTracks, tdb->track) == NULL)
     {
     // Visit parent first, so that any parent HTML description is loaded before handling this
     // track.  Otherwise we could write out the HTML description of this track without knowing
     // that it's identical to the parent's.
     hashStore(visitedTracks, tdb->track);
     if (tdb->parent != NULL)
         trackHubCrawlTrack(tdb->parent, genome, hubUrl, dbName, searchFp, visitedTracks);
 
     struct hubSearchText *trackHst = NULL;
     struct dyString *csParents = dyStringNew(0);
+    struct dyString *csParentTypes = dyStringNew(0);
     AllocVar(trackHst);
     trackHst->hubUrl = cloneString(hubUrl);
     trackHst->db = cloneString(dbName);
     trackHst->track = cloneString(trackHubSkipHubName(tdb->track));
     struct trackDb *ptdb = tdb->parent;
     while (ptdb != NULL)
         {
         // start with track
         dyStringPrintf(csParents, "\"%s\",", htmlEncode(trackHubSkipHubName(ptdb->track)));
 
         // now add the label, which may just be the track name again
         dyStringPrintf(csParents, "\"");
         if (isNotEmpty(tdb->longLabel))
             dyStringPrintf(csParents, "%s", htmlEncode(ptdb->longLabel));
         else if (isNotEmpty(tdb->shortLabel))
             dyStringPrintf(csParents, "%s", htmlEncode(ptdb->shortLabel));
         else
             dyStringPrintf(csParents, "%s", htmlEncode(ptdb->track));
         dyStringPrintf(csParents, "\"");
 
+        // now fill in the type of the parent, "comp" for composite/multiWig (ie valid trackUi page),
+        // "super" for super track, and "view" for view, "other" for everything else.
+        // these are used by hgHubConnect for printing the correct links to track ui pages
+        // for search results
+        if (tdbIsComposite(ptdb) || trackDbLocalSetting(ptdb, "container"))
+            dyStringPrintf(csParentTypes, "comp");
+        else if (tdbIsSuper(ptdb))
+            dyStringPrintf(csParentTypes, "super");
+        else if (tdbIsCompositeView(ptdb))
+            dyStringPrintf(csParentTypes, "view");
+        else // handle any extra
+            dyStringPrintf(csParentTypes, "other");
+
         if (ptdb->parent != NULL)
+            {
             dyStringPrintf(csParents, ",");
+            dyStringPrintf(csParentTypes, ",");
+            }
         ptdb = ptdb->parent;
         }
     trackHst->parents = dyStringCannibalize(&csParents);
+    trackHst->parentTypes = dyStringCannibalize(&csParentTypes);
     if (isNotEmpty(tdb->longLabel))
         {
         trackHst->label = cloneString(tdb->longLabel);
         }
     else if (isNotEmpty(tdb->shortLabel))
         {
         trackHst->label = cloneString(tdb->shortLabel);
         }
     else
         trackHst->label = cloneString(trackHubSkipHubName(tdb->track));
 
     trackHst->textLength = hubSearchTextShort;
     trackHst->text = cloneString(trackHubSkipHubName(tdb->track));
     hubSearchTextTabOut(trackHst, searchFp);
 
@@ -165,58 +183,57 @@
         }
 
     // memory leak ditching metadata pairs.  slPairFreeValsAndList would fix that.
     trackHst->textLength = hubSearchTextMeta;
     trackHst->text = (char *) needMem(4096);
     struct slPair *metaPairs = trackDbMetaPairs(tdb);
     while (metaPairs != NULL)
         {
         safef(trackHst->text, 4096, "%s: %s", metaPairs->name, (char *) metaPairs->val);
         hubSearchTextTabOut(trackHst, searchFp);
         metaPairs = metaPairs->next;
         }
 
     // Write out lines for child tracks
     struct trackDb *subtrack = NULL;
-    subtrack = tdb->subtracks;
-    while (subtrack != NULL)
+    for (subtrack = tdb->subtracks; subtrack != NULL; subtrack = subtrack->next)
         {
         trackHubCrawlTrack(subtrack, genome, hubUrl, dbName, searchFp, visitedTracks);
-        subtrack = subtrack->next;
         }
     }
 }
 
 
 void trackHubCrawlGenome(struct trackHubGenome *genome, struct trackHub *hub, FILE *searchFp)
 /* Given a hub genome and the hub it came from, write out hubSearchText lines for that genome.
  * NB: Errors fetching particular trackDb files will not be reported to the calling function. */
 {
 struct hubSearchText *genomeHst = NULL;
 AllocVar(genomeHst);
 genomeHst->hubUrl = cloneString(hub->url);
 genomeHst->db = cloneString(trackHubSkipHubName(genome->name));
 genomeHst->track = cloneString("");
 char label[256];
 if (isNotEmpty(genome->description))
     safef(label, sizeof(label), "%s (%s)", genome->description, trackHubSkipHubName(genome->name));
 else if (isNotEmpty(genome->organism))
     safef(label, sizeof(label), "%s (%s)", trackHubSkipHubName(genome->organism), trackHubSkipHubName(genome->name));
 else
     safef(label, sizeof(label), "%s", trackHubSkipHubName(genome->name));
 genomeHst->label = cloneString(label);
 genomeHst->parents = cloneString("");
+genomeHst->parentTypes = cloneString("");
 genomeHst->textLength = hubSearchTextShort;
 genomeHst->text = cloneString(trackHubSkipHubName(genome->name));
 hubSearchTextTabOut(genomeHst, searchFp);
 
 if (isNotEmpty(genome->organism) && differentString(genome->organism, genome->name))
     {
     genomeHst->text = cloneString(trackHubSkipHubName(genome->organism));
     hubSearchTextTabOut(genomeHst, searchFp);
     }
 if (isNotEmpty(genome->description))
     {
     genomeHst->text = cloneString(genome->description);
     hubSearchTextTabOut(genomeHst, searchFp);
     }
 struct hashEl *hel = NULL;
@@ -272,33 +289,34 @@
     fprintf(stderr, "%s\n", errCatch->message->string);
     }
 errCatchFree(&errCatch);
 
 if (hub == NULL)
     return 1;
 
 FILE *searchFp =stdout;
 struct hubSearchText *hubHst;
 AllocVar(hubHst);
 
 hubHst->hubUrl = cloneString(hub->url);
 hubHst->db = cloneString("");
 hubHst->track = cloneString("");
 hubHst->label = cloneString("");
-hubHst->parents = cloneString("");
 hubHst->textLength = hubSearchTextShort;
 hubHst->text = cloneString(hub->shortLabel);
+hubHst->parents = cloneString("");
+hubHst->parentTypes = cloneString("");
 hubSearchTextTabOut(hubHst, searchFp);
 
 hubHst->text = cloneString(hub->longLabel);
 hubSearchTextTabOut(hubHst, searchFp);
 
 if (hub->descriptionUrl != NULL)
     {
     hubHst->textLength = hubSearchTextLong;
     char *rawHtml = netReadTextFileIfExists(hub->descriptionUrl);
     hubHst->text = cleanHubHtml(rawHtml);
     if (isNotEmpty(hubHst->text))
         hubSearchTextTabOut(hubHst, searchFp);
     }
 
 struct trackHubGenome *genome;