108d1fce0f31f8d58cfc0940a5fdb5a1deb7c14e
braney
  Sat Jan 21 15:25:47 2023 -0800
be smarter about how we deal with curated hubs.  Fixes #30510

diff --git src/hg/lib/hubConnect.c src/hg/lib/hubConnect.c
index c109cfa..fff7937 100644
--- src/hg/lib/hubConnect.c
+++ src/hg/lib/hubConnect.c
@@ -14,30 +14,31 @@
 #include "sqlNum.h"
 #include "jksql.h"
 #include "hdb.h"
 #include "net.h"
 #include "trackHub.h"
 #include "hubConnect.h"
 #include "hui.h"
 #include "errCatch.h"
 #include "obscure.h"
 #include "hgConfig.h"
 #include "grp.h"
 #include "udc.h"
 #include "hubPublic.h"
 #include "genark.h"
 #include "asmAlias.h"
+#include "cheapcgi.h"
 
 boolean isHubTrack(char *trackName)
 /* Return TRUE if it's a hub track. */
 {
 return startsWith(hubTrackPrefix, trackName);
 }
 
 static char *hubStatusTableName = NULL;
 static char *_hubPublicTableName = NULL;
 
 static char *getHubStatusTableName()
 /* return the hubStatus table name from the environment, 
  * or hg.conf, or use the default.  Cache the result */
 {
 if (hubStatusTableName == NULL)
@@ -752,31 +753,31 @@
 hDisconnectCentral(&conn);
 }
 
 struct trackDb *hubAddTracks(struct hubConnectStatus *hub, char *database, boolean *foundFirstGenome, struct hash *trackDbNameHash)
 /* Load up stuff from data hub and append to list. The hubUrl points to
  * a trackDb.ra format file. Only the first example of a genome gets to 
  * populate groups, the others get a group for the trackHub.  A particular 
  * trackDb is only read once even if referenced from more than one hub.  */
 {
 struct trackDb *tdbList = NULL;
 struct trackHub *trackHub = hub->trackHub;
 
 if (trackHub != NULL)
     {
     struct trackHubGenome *hubGenome = trackHubFindGenome(trackHub, database);
-    if (hashLookup(trackDbNameHash,  hubGenome->trackDbFile))
+    if ((hubGenome == NULL) || hashLookup(trackDbNameHash,  hubGenome->trackDbFile))
         hubGenome = NULL; // we already saw this trackDb, so ignore this stanza
     else
         hashStore(trackDbNameHash,  hubGenome->trackDbFile);
 
     if (hubGenome != NULL)
 	{
         boolean doCache = trackDbCacheOn();
 
         if (doCache)
             {
             // we have to open the trackDb file to get the udc cache to check for an update
             struct udcFile *checkCache = udcFileMayOpen(hubGenome->trackDbFile, NULL);
             if (checkCache != NULL)
                 {
                 time_t time = udcUpdateTime(checkCache);
@@ -1027,86 +1028,85 @@
         char url[4096];
         safef(url, sizeof url, "%s/%s/hub.txt", path, getCuratedHubPrefix());
         *hubUrl = cloneString(url);
         }
     }
 
 return ret;
 }
 
 boolean hubConnectIsCurated(char *db)
 /* Look in the dbDb table to see if this hub is curated. */
 {
 return hubConnectGetCuratedUrl(db, NULL);
 }
 
-char *dbOveride;  // communicate with the web front end if we load a hub to support db cgivar. */
-
 static int lookForCuratedHubs(struct cart *cart, char *db,  char *curatedHubPrefix)
 /* Check to see if db is a curated hub which will require the hub to be attached. 
  * The variable curatedHubPrefix has the release to use (alpha, beta, public, or a user name ) */
 {
 struct sqlConnection *conn = hConnectCentral();
 char query[4096];
 sqlSafef(query, sizeof query, "SELECT nibPath from %s where name = '%s' AND nibPath like '%s%%'",
           dbDbTable(), db, hubCuratedPrefix);
 
 char *dir = cloneString(sqlQuickString(conn, query));
 hDisconnectCentral(&conn);
 
 if (!isEmpty(dir))
     {
     char *path = &dir[sizeof hubCuratedPrefix - 1];
     char url[4096];
     safef(url, sizeof url, "%s/%s/hub.txt", path, curatedHubPrefix);
 
     struct hubConnectStatus *status = getAndSetHubStatus( cart, url, TRUE);
 
     if (status && isEmpty(status->errorMessage))
         {
+        if (cgiOptionalString("db"))
+            {
+            /* user specified db on URL, we need to decorate and put it back. */
             char buffer[4096];
             safef(buffer, sizeof buffer, "hub_%d_%s", status->id, db);
-        dbOveride = cloneString(buffer);
+            cgiVarSet("db",  cloneString(buffer));
+            }
 
         return status->id;
         }
     else
         {
         if (!isEmpty(status->errorMessage))
             errAbort("Hub error: url %s: error  %s.", url, status->errorMessage);
         else
             errAbort("Cannot open hub %s.", url);
         }
 
     }
 return 0;
 }
 
 
 char *hubConnectLoadHubs(struct cart *cart)
 /* load the track data hubs.  Set a static global to remember them */
 {
-int newCuratedHubId = 0;
 char *dbSpec = cartOptionalString(cart, "db");
 char *curatedHubPrefix = getCuratedHubPrefix();
 if (dbSpec != NULL)
-    newCuratedHubId = lookForCuratedHubs(cart, trackHubSkipHubName(dbSpec), curatedHubPrefix);
+    lookForCuratedHubs(cart, trackHubSkipHubName(dbSpec), curatedHubPrefix);
 
 char *newDatabase = checkForNew( cart);
 newDatabase = asmAliasFind(newDatabase);
-if (newCuratedHubId)
-    newDatabase = dbOveride;
 cartSetString(cart, hgHubConnectRemakeTrackHub, "on");
 struct hubConnectStatus  *hubList =  hubConnectStatusListFromCart(cart);
 
 char *genarkPrefix = cfgOption("genarkHubPrefix");
 if (genarkPrefix && lookForLonelyHubs(cart, hubList, &newDatabase, genarkPrefix))
     hubList = hubConnectStatusListFromCart(cart);
 
 globalHubList = hubList;
 
 return newDatabase;
 }
 
 char *hubNameFromUrl(char *hubUrl)
 /* Given the URL for a hub, return its hub_# name. */
 {