69d620fa14cf647c4f2dc45f82aedba7f51c27cd
chmalee
  Mon Mar 3 15:06:42 2025 -0800
Allow hub tracks in hubApi /getData/track function, refs #34627

diff --git src/hg/hubApi/getData.c src/hg/hubApi/getData.c
index 02b69b8d6da..b70c5bb415a 100644
--- src/hg/hubApi/getData.c
+++ src/hg/hubApi/getData.c
@@ -595,42 +595,48 @@
 struct sqlConnection *conn = hAllocConnMaybe(db);
 if (NULL == conn)
     apiErrAbort(err400, err400Msg, "can not find genome 'genome=%s' for endpoint '/getData/track", db);
 
 struct jsonWrite *jw = apiStartOutput();
 jsonWriteString(jw, "genome", db);
 
 // load the tracks
 struct trackDb *tdbList = NULL;
 cartTrackDbInitForApi(NULL, db, &tdbList, NULL, TRUE);
 
 // allow optional comma sep list of tracks
 char *tracks[100];
 int numTracks = chopByChar(trackArg, ',', tracks, sizeof(tracks));
 int i = 0;
+struct hash *trackHash = hashNew(0); // let hub tracks work
 for (i = 0; i < numTracks; i++)
     {
     char *track = cloneString(tracks[i]);
     char *sqlTable = cloneString(track);
 
     if (cartTrackDbIsAccessDenied(db, sqlTable) ||
             (cartTrackDbIsNoGenome(db, sqlTable) && !(chrom && start && end)))
         apiErrAbort(err403, err403Msg, "this data request: 'db=%s;track=%s' is protected data, see also: https://genome.ucsc.edu/FAQ/FAQdownloads.html#download40", db, track);
     struct trackDb *thisTrack = tdbForTrack(db, track, &tdbList);
     if (NULL == thisTrack)
         {
-        if (! sqlTableExists(conn, track))
+        // maybe we have a hub track, try to look it up
+        if (startsWith("hub_", track))
+            {
+            thisTrack = hubConnectAddHubForTrackAndFindTdb(db, track, &tdbList, trackHash);
+            }
+        if (!thisTrack && ! sqlTableExists(conn, track))
             apiErrAbort(err400, err400Msg, "can not find track=%s name for endpoint '/getData/track", track);
         }
     if (thisTrack && ! isSupportedType(thisTrack->type))
         apiErrAbort(err415, err415Msg, "track type '%s' for track=%s not supported at this time", thisTrack->type, track);
     if (trackHasNoData(thisTrack))
         apiErrAbort(err400, err400Msg, "container track '%s' does not contain data, use the children of this container", track);
 
     /* might be a big* track with no table */
     char *bigDataUrl = NULL;
     boolean tableTrack = TRUE;
 
     if (thisTrack)
         {
         bigDataUrl = trackDbSetting(thisTrack, "bigDataUrl");