8ccceea1c52492b6a869af8de3190a387d4b6550
braney
Tue Mar 12 13:41:09 2024 -0700
added exportedDataHubs dialog and code to deal with quickLifted hubs
diff --git src/hg/lib/hubConnect.c src/hg/lib/hubConnect.c
index d6dff78..5b08b86 100644
--- src/hg/lib/hubConnect.c
+++ src/hg/lib/hubConnect.c
@@ -102,30 +102,51 @@
struct dyString *trackHubs = dyStringNew(0);
struct slPair *hubVar;
boolean firstOne = TRUE;
for (hubVar = hubVarList; hubVar != NULL; hubVar = hubVar->next)
{
if (cartBoolean(cart, hubVar->name))
{
if (firstOne)
firstOne = FALSE;
else
dyStringAppendC(trackHubs, ' ');
dyStringAppend(trackHubs, hubVar->name + prefixLength);
}
}
slPairFreeList(&hubVarList);
+
+ // now see if we should quicklift any hubs
+ struct sqlConnection *conn = hConnectCentral();
+ char query[2048];
+ hubVarList = cartVarsWithPrefix(cart, "quickLift");
+ for (hubVar = hubVarList; hubVar != NULL; hubVar = hubVar->next)
+ {
+ unsigned hubNumber = atoi(hubVar->name + sizeof("quickLift"));
+ sqlSafef(query, sizeof(query), "select path from exportedDataHubs where id='%d'", hubNumber);
+ char *hubUrl = sqlQuickString(conn, query);
+ char *errorMessage;
+ unsigned hubId = hubFindOrAddUrlInStatusTable(cart, hubUrl, &errorMessage);
+
+ if (firstOne)
+ firstOne = FALSE;
+ else
+ dyStringAppendC(trackHubs, ' ');
+ dyStringPrintf(trackHubs, "%d:%s", hubId,(char *)hubVar->val);
+ }
+ hDisconnectCentral(&conn);
+
cartSetString(cart, hubConnectTrackHubsVarName, trackHubs->string);
dyStringFree(&trackHubs);
cartRemove(cart, hgHubConnectRemakeTrackHub);
}
}
struct slName *hubConnectHubsInCart(struct cart *cart)
/* Return list of track hub ids that are turned on. */
{
hubConnectRemakeTrackHubVar(cart);
char *trackHubString = cartOptionalString(cart, hubConnectTrackHubsVarName);
return slNameListFromString(trackHubString, ' ');
}
boolean trackHubHasDatabase(struct trackHub *hub, char *database)
@@ -170,31 +191,33 @@
return tHub;
}
static boolean
hubTimeToCheck(struct hubConnectStatus *hub, char *notOkStatus)
/* check to see if enough time has passed to re-check a hub that
* has an error status. Use udcTimeout as the length of time to wait.*/
{
time_t checkTime = udcCacheTimeout();
return dateIsOlderBy(notOkStatus, "%F %T", checkTime);
}
/* Given a hub ID return associated status. Returns NULL if no such hub. If hub
* exists but has problems will return with errorMessage field filled in. */
-struct hubConnectStatus *hubConnectStatusForId(struct sqlConnection *conn, int id)
+struct hubConnectStatus *hubConnectStatusForIdExt(struct sqlConnection *conn, int id, char *replaceDb, char *newDb, char *quickLiftChain)
+/* Given a hub ID return associated status. For quickLifted hubs, replace the db with our current db and
+ * keep track of the quickLiftChain for updating trackDb later.*/
{
struct hubConnectStatus *hub = NULL;
char query[1024];
sqlSafef(query, sizeof(query),
"select hubUrl,status, errorMessage,lastNotOkTime, shortLabel from %s where id=%d", getHubStatusTableName(), id);
struct sqlResult *sr = sqlGetResult(conn, query);
char **row = sqlNextRow(sr);
if (row != NULL)
{
AllocVar(hub);
hub->id = id;
hub->hubUrl = cloneString(row[0]);
hub->status = sqlUnsigned(row[1]);
hub->errorMessage = cloneString(row[2]);
hub->shortLabel = cloneString(row[4]);
@@ -206,71 +229,116 @@
hub->trackHub->hubStatus = hub;
hub->errorMessage = cloneString(errorMessage);
hubUpdateStatus( hub->errorMessage, hub);
if (!isEmpty(hub->errorMessage))
{
boolean isCollection = (strstr(hub->hubUrl, "hgComposite") != NULL);
if (isCollection)
warn("You created a Track "
"Collection that has expired and been removed. Track Collections "
"expire 48 hours after their last use. "
"Save your session to preserve collections long-term and to allow sharing.");
// commenting this out, but leaving it in the source because we might use it later.
//else
//warn("Could not connect to hub \"%s\": %s", hub->shortLabel, hub->errorMessage);
}
+ if ((hub->trackHub != NULL) && (replaceDb != NULL))
+ {
+ struct trackHubGenome *genome = hub->trackHub->genomeList;
+
+ for(; genome; genome = genome->next)
+ {
+ if (sameString(genome->name, replaceDb))
+ {
+ genome->name = newDb;
+ hashAdd(hub->trackHub->genomeHash, newDb, genome);
+ genome->quickLiftChain = quickLiftChain;
+ }
+ }
+ }
}
}
sqlFreeResult(&sr);
return hub;
}
+struct hubConnectStatus *hubConnectStatusForId(struct sqlConnection *conn, int id)
+{
+return hubConnectStatusForIdExt(conn, id, NULL, NULL, NULL);
+}
+
struct hubConnectStatus *hubConnectStatusListFromCartAll(struct cart *cart)
/* Return list of all track hubs that are referenced by cart. */
{
struct hubConnectStatus *hubList = NULL, *hub;
struct slPair *pair, *pairList = cartVarsWithPrefix(cart, hgHubConnectHubVarPrefix);
struct sqlConnection *conn = hConnectCentral();
for (pair = pairList; pair != NULL; pair = pair->next)
{
// is this hub turned connected??
if (differentString(pair->val, "1"))
continue;
int id = hubIdFromCartName(pair->name);
hub = hubConnectStatusForId(conn, id);
if (hub != NULL)
{
slAddHead(&hubList, hub);
}
}
slFreeList(&pairList);
hDisconnectCentral(&conn);
slReverse(&hubList);
return hubList;
}
struct hubConnectStatus *hubConnectStatusListFromCart(struct cart *cart)
/* Return list of track hubs that are turned on by user in cart. */
{
-struct hubConnectStatus *hubList = NULL, *hub;
+struct hubConnectStatus *hubList = NULL, *hub = NULL;
struct slName *name, *nameList = hubConnectHubsInCart(cart);
struct sqlConnection *conn = hConnectCentral();
for (name = nameList; name != NULL; name = name->next)
{
- int id = sqlSigned(name->name);
+ // items in trackHub statement may need to be quickLifted. This is implied
+ // by the hubStatus id followed by a colon and then a index into the quickLiftChain table
+ char *copy = cloneString(name->name);
+ char *colon = strchr(copy, ':');
+ if (colon)
+ *colon++ = 0;
+ int id = sqlSigned(copy);
+ if (colon == NULL) // not quickLifted
hub = hubConnectStatusForId(conn, id);
+ else
+ {
+ char query[4096];
+ sqlSafef(query, sizeof(query), "select fromDb, toDb, path from %s where id = \"%s\"", "quickLiftChain", colon);
+ struct sqlResult *sr = sqlGetResult(conn, query);
+ char **row;
+ char *replaceDb = NULL;
+ char *quickLiftChain = NULL;
+ char *toDb = NULL;
+ while ((row = sqlNextRow(sr)) != NULL)
+ {
+ replaceDb = cloneString(row[0]);
+ toDb = cloneString(row[1]);
+ quickLiftChain = cloneString(row[2]);
+ break; // there's only one
+ }
+ sqlFreeResult(&sr);
+ hub = hubConnectStatusForIdExt(conn, id, replaceDb, toDb, quickLiftChain);
+ }
if (hub != NULL)
{
if (!isEmpty(hub->errorMessage) && (strstr(hub->hubUrl, "hgComposite") != NULL))
{
// custom collection hub has disappeared. Remove it from cart
cartSetString(cart, hgHubConnectRemakeTrackHub, "on");
char buffer[1024];
safef(buffer, sizeof buffer, "hgHubConnect.hub.%d", id);
cartRemove(cart, buffer);
}
else
slAddHead(&hubList, hub);
}
}
slFreeList(&nameList);
@@ -357,48 +425,65 @@
return p;
}
void hubConnectAddDescription(char *database, struct trackDb *tdb)
/* Fetch tdb->track's html description (or nearest ancestor's non-empty description)
* and store in tdb->html. */
{
unsigned hubId = hubIdFromTrackName(tdb->track);
struct hubConnectStatus *hub = hubFromId(hubId);
struct trackHubGenome *hubGenome = trackHubFindGenome(hub->trackHub, database);
trackHubPolishTrackNames(hub->trackHub, tdb);
trackHubAddDescription(hubGenome->trackDbFile, tdb);
}
+static void assignQuickLift(struct trackDb *tdbList, char *quickLiftChain)
+/* step through a trackDb list and assign a quickLift chain to each track */
+{
+if (tdbList == NULL)
+ return;
+
+struct trackDb *tdb;
+for(tdb = tdbList; tdb; tdb = tdb->next)
+ {
+ assignQuickLift(tdb->subtracks, quickLiftChain);
+
+ hashAdd(tdb->settingsHash, "quickLiftUrl", quickLiftChain);
+ }
+}
+
struct trackDb *hubConnectAddHubForTrackAndFindTdb( char *database,
char *trackName, struct trackDb **pTdbList, struct hash *trackHash)
/* Go find hub for trackName (which will begin with hub_), and load the tracks
* for it, appending to end of list and adding to trackHash. Return the
* trackDb associated with trackName. This will also fill in the html fields,
* but just for that track and it's parents. */
{
unsigned hubId = hubIdFromTrackName(trackName);
struct hubConnectStatus *hub = hubFromId(hubId);
struct trackHubGenome *hubGenome = trackHubFindGenome(hub->trackHub, database);
if (hubGenome == NULL)
errAbort("Cannot find genome %s in hub %s", database, hub->hubUrl);
boolean foundFirstGenome = FALSE;
struct trackDb *tdbList = trackHubTracksForGenome(hub->trackHub, hubGenome, NULL, &foundFirstGenome);
tdbList = trackDbLinkUpGenerations(tdbList);
tdbList = trackDbPolishAfterLinkup(tdbList, database);
//this next line causes warns to print outside of warn box on hgTrackUi
//trackDbPrioritizeContainerItems(tdbList);
+if (hubGenome->quickLiftChain)
+ assignQuickLift(tdbList, hubGenome->quickLiftChain);
trackHubPolishTrackNames(hub->trackHub, tdbList);
char *fixTrackName = cloneString(trackName);
trackHubFixName(fixTrackName);
rAddTrackListToHash(trackHash, tdbList, NULL, FALSE);
if (pTdbList != NULL)
*pTdbList = slCat(*pTdbList, tdbList);
struct trackDb *tdb = hashFindVal(trackHash, fixTrackName);
if (tdb == NULL)
// superTracks aren't in the hash... look in tdbList
tdb = findSuperTrack(tdbList, fixTrackName);
if (tdb == NULL)
errAbort("Can't find track %s in %s", fixTrackName, hub->trackHub->url);
/* Add html for track and parents. */
@@ -789,30 +874,33 @@
return cacheTdb;
}
memCheckPoint(); // we want to know how much memory is used to build the tdbList
}
struct dyString *incFiles = dyStringNew(4096);
tdbList = trackHubTracksForGenome(trackHub, hubGenome, incFiles, foundFirstGenome);
tdbList = trackDbLinkUpGenerations(tdbList);
tdbList = trackDbPolishAfterLinkup(tdbList, database);
trackDbPrioritizeContainerItems(tdbList);
trackHubPolishTrackNames(trackHub, tdbList);
if (doCache)
trackDbHubCloneTdbListToSharedMem(hubGenome->trackDbFile, tdbList, memCheckPoint(), incFiles->string);
+
+ if (hubGenome->quickLiftChain)
+ assignQuickLift(tdbList, hubGenome->quickLiftChain);
}
}
return tdbList;
}
static struct grp *grpFromHub(struct hubConnectStatus *hub)
/* Make up a grp structur from hub */
{
struct grp *grp;
AllocVar(grp);
char name[16];
safef(name, sizeof(name), "hub_%d", hub->id);
grp->name = cloneString(name);
grp->label = cloneString(hub->shortLabel);
return grp;