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 <a href=\"/cgi-bin/hgCollection\"><b>Track " "Collection</b></a> that has expired and been removed. Track Collections " "expire 48 hours after their last use. <a href=\"/cgi-bin/hgSession\"><b>" "Save your session</b></a> 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;