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/hgHubConnect/hgHubConnect.c src/hg/hgHubConnect/hgHubConnect.c index 287e30f..1860562 100644 --- src/hg/hgHubConnect/hgHubConnect.c +++ src/hg/hgHubConnect/hgHubConnect.c @@ -789,105 +789,129 @@ struct tdbOutputStructure *hstToTdbOutput(struct hubSearchText *hst, struct genomeOutputStructure *genomeOut, struct trackHub *hub) /* Convert a hubSearchText entry to a (list of) tdbOutputStructure(s) */ { struct tdbOutputStructure *tdbOut = hashFindVal(genomeOut->tdbOutHash, hst->track); if (tdbOut == NULL) { genomeOut->trackCount++; AllocVar(tdbOut); tdbOut->shortLabel = dyStringNew(0); tdbOut->metaTags = dyStringNew(0); tdbOut->descriptionMatch = dyStringNew(0); tdbOut->configUrl = dyStringNew(0); dyStringPrintf(tdbOut->shortLabel, "%s", hst->label); - + char *hubId = hubNameFromUrl(hub->url); if (isNotEmpty(hst->parents)) { // hst->parents is a comma-sep list like "track1","track1Label","track2","track2Label" int i; int parentCount; + int parentTypesCount; char *parentTrack = NULL; char *parentLabel = NULL; char *parentTrackLabels[16]; // 2 slots per parent, can tracks nest more than 8 deep? + char *parentTypes[16]; // the types of parents, "comp", "super", "view", "other" for each track in parentTrackLabels struct tdbOutputStructure *parentTdbOut = NULL; struct tdbOutputStructure *savedParent = NULL; parentCount = chopByCharRespectDoubleQuotes(cloneString(hst->parents), ',', parentTrackLabels, sizeof(parentTrackLabels)); + parentTypesCount = chopCommas(cloneString(hst->parentTypes), parentTypes); if (parentCount == 0 || parentCount % 2 != 0) { errAbort("error parsing hubSearchText->parents for %s.%s in hub: '%s'", genomeOut->genomeName, hst->track, hub->url); } - dyStringPrintf(tdbOut->configUrl, "../cgi-bin/hgTrackUi?hubUrl=%s&db=%s&g=%s&hgsid=%s&%s", - hub->url, genomeOut->genomeName, parentTrackLabels[0], cartSessionId(cart), - genomeOut->positionString); + if (parentTypesCount != (parentCount / 2)) + { + errAbort("error parsing hubSearchText->parentTypes: '%s' for %s.%s in hub: '%s'", + hst->parentTypes, genomeOut->genomeName, hst->track, hub->url); + } boolean foundParent = FALSE; boolean doAddSaveParent = FALSE; for (i = 0; i < parentCount; i += 2) { parentTrack = stripEnclosingDoubleQuotes(cloneString(parentTrackLabels[i])); parentLabel = stripEnclosingDoubleQuotes(cloneString(parentTrackLabels[i+1])); - parentTdbOut = hashFindVal(genomeOut->tdbOutHash, parentTrack); - if (parentTdbOut != NULL) + // wait until the first valid trackui page for the track hit + if (isEmpty(dyStringContents(tdbOut->configUrl)) && sameString(parentTypes[i/2], "comp")) { - foundParent = TRUE; // don't add this track to the genomeOut->tracks hash again - if (savedParent && doAddSaveParent) - { - parentTdbOut->childCount += 1; - slAddHead(&(parentTdbOut->children), savedParent); + dyStringPrintf(tdbOut->configUrl, "../cgi-bin/hgTrackUi?hubUrl=%s&db=%s&g=%s_%s&hgsid=%s&%s", + hub->url, genomeOut->genomeName, hubId, parentTrack, cartSessionId(cart), + genomeOut->positionString); } - else if (!savedParent) + else if (isEmpty(dyStringContents(tdbOut->configUrl)) && sameString(parentTypes[i/2], "super")) { - parentTdbOut->childCount += 1; - slAddHead(&(parentTdbOut->children), tdbOut); - } - savedParent = parentTdbOut; - doAddSaveParent = FALSE; + dyStringPrintf(tdbOut->configUrl, "../cgi-bin/hgTrackUi?hubUrl=%s&db=%s&g=%s_%s&hgsid=%s&%s", + hub->url, genomeOut->genomeName, hubId, hst->track, cartSessionId(cart), + genomeOut->positionString); } - else + parentTdbOut = hashFindVal(genomeOut->tdbOutHash, parentTrack); + if (parentTdbOut == NULL) { AllocVar(parentTdbOut); parentTdbOut->shortLabel = dyStringNew(0); parentTdbOut->metaTags = dyStringNew(0); parentTdbOut->descriptionMatch = dyStringNew(0); parentTdbOut->configUrl = dyStringNew(0); - dyStringPrintf(tdbOut->configUrl, - "../cgi-bin/hgTrackUi?hubUrl=%s&db=%s&g=%s&hgsid=%s&%s", - hub->url, genomeOut->genomeName, parentTrack, cartSessionId(cart), genomeOut->positionString); + // views will be in the parent list, but the &g parameter to trackUi should be the view's parent + if (sameString(parentTypes[(i/2)], "view")) + dyStringPrintf(parentTdbOut->configUrl, + "../cgi-bin/hgTrackUi?hubUrl=%s&db=%s&g=%s_%s&hgsid=%s&%s", + hub->url, genomeOut->genomeName, hubId, stripEnclosingDoubleQuotes(parentTrackLabels[(i/2)+2]), cartSessionId(cart), genomeOut->positionString); + else // everything else has the correct &g param + dyStringPrintf(parentTdbOut->configUrl, + "../cgi-bin/hgTrackUi?hubUrl=%s&db=%s&g=%s_%s&hgsid=%s&%s", + hub->url, genomeOut->genomeName, hubId, parentTrack, cartSessionId(cart), genomeOut->positionString); dyStringPrintf(parentTdbOut->shortLabel, "%s", parentLabel); parentTdbOut->childCount += 1; if (savedParent) slAddHead(&(parentTdbOut->children), savedParent); else slAddHead(&(parentTdbOut->children), tdbOut); savedParent = parentTdbOut; doAddSaveParent = TRUE; hashAdd(genomeOut->tdbOutHash, parentTrack, parentTdbOut); } + else + { + foundParent = TRUE; // don't add this track to the genomeOut->tracks hash again + if (savedParent && doAddSaveParent) + { + parentTdbOut->childCount += 1; + slAddHead(&(parentTdbOut->children), savedParent); + } + else if (!savedParent) + { + parentTdbOut->childCount += 1; + slAddHead(&(parentTdbOut->children), tdbOut); + } + savedParent = parentTdbOut; + doAddSaveParent = FALSE; + } } if (!foundParent) { slAddHead(&(genomeOut->tracks), parentTdbOut); } } else { - dyStringPrintf(tdbOut->configUrl, "../cgi-bin/hgTrackUi?hubUrl=%s&db=%s&g=%s&hgsid=%s&%s", - hub->url, genomeOut->genomeName, hst->track, cartSessionId(cart), + dyStringPrintf(tdbOut->configUrl, "../cgi-bin/hgTrackUi?hubUrl=%s&db=%s&g=%s_%s&hgsid=%s&%s", + hub->url, genomeOut->genomeName, hubId, hst->track, cartSessionId(cart), genomeOut->positionString); slAddHead(&(genomeOut->tracks), tdbOut); } hashAdd(genomeOut->tdbOutHash, hst->track, tdbOut); } return tdbOut; } struct hubOutputStructure *buildHubSearchOutputStructure(struct trackHub *hub, struct hubSearchText *searchResults) /* Build a structure that contains the data for writing out the hub search results for this hub */ { struct hash *missingGenomes = hashNew(0); struct hubOutputStructure *hubOut = NULL; AllocVar(hubOut);