bfca2e5a7f3391f6b02581da7a84524fd8de66fb angie Thu Mar 5 10:05:33 2015 -0800 Since groupedTrackDb is so large for hg19, it can actually arrive after the user has already switched to a different database and received the groupTrackDb for the new database. Prevent clobbering by including the database to which this particular groupedTrackDb belongs. diff --git src/hg/lib/cartJson.c src/hg/lib/cartJson.c index 884b96f..67deacf 100644 --- src/hg/lib/cartJson.c +++ src/hg/lib/cartJson.c @@ -387,64 +387,69 @@ struct slRef *slr = slRefNew(tdb); if (hel) slAddHead(&(hel->val), slr); else hashAdd(hash, tdb->grp, slr); } struct hashCookie cookie = hashFirst(hash); struct hashEl *hel; while ((hel = hashNext(&cookie)) != NULL) slSort(&hel->val, trackDbRefCmp); return hash; } void cartJsonGetGroupedTrackDb(struct cartJson *cj, struct hash *paramHash) /* Translate trackDb list (only a subset of the fields) into JSON array of track group objects; - * each group contains an array of track objects that may have subtracks. */ + * each group contains an array of track objects that may have subtracks. Send it in a wrapper + * object that includes the database from which it was taken; it's possible that by the time + * this reaches the client, the user might have switched to a new db. */ { struct trackDb *fullTrackList = NULL; struct grp *fullGroupList = NULL; cartTrackDbInit(cj->cart, &fullTrackList, &fullGroupList, /* useAccessControl=*/TRUE); struct hash *groupedTrackRefList = hashTracksByGroup(fullTrackList); // If the optional param 'fields' is given, hash the field names that should be returned. char *fields = cartJsonOptionalParam(paramHash, "fields"); struct hash *fieldHash = hashFromCommaString(fields); // Also check for optional parameter 'maxDepth': int maxDepth = -1; char *maxDepthStr = cartJsonOptionalParam(paramHash, "maxDepth"); if (isNotEmpty(maxDepthStr)) maxDepth = atoi(maxDepthStr); struct jsonWrite *jw = cj->jw; +jsonWriteObjectStart(jw, "groupedTrackDb"); +jsonWriteString(jw, "db", cartString(cj->cart, "db")); jsonWriteListStart(jw, "groupedTrackDb"); struct grp *grp; for (grp = fullGroupList; grp != NULL; grp = grp->next) { jsonWriteObjectStart(jw, NULL); jsonWriteString(jw, "name", grp->name); jsonWriteString(jw, "label", grp->label); jsonWriteListStart(jw, "tracks"); struct slRef *tdbRefList = hashFindVal(groupedTrackRefList, grp->name); struct slRef *tdbRef; for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next) { struct trackDb *tdb = tdbRef->val; rWriteTdb(jw, tdb, fieldHash, 1, maxDepth); } jsonWriteListEnd(jw); jsonWriteObjectEnd(jw); } jsonWriteListEnd(jw); +jsonWriteObjectEnd(jw); } static char *hAssemblyDescription(char *db) /* Return a string containing db's description.html, or NULL if not found. */ //#*** LIBIFY: Code lifted from hgFind.c's hgPositionsHelpHtml. { char *htmlPath = hHtmlPath(db); char *htmlString = NULL; if (htmlPath != NULL) { if (fileExists(htmlPath)) readInGulp(htmlPath, &htmlString, NULL); else if (startsWith("http://" , htmlPath) || startsWith("https://", htmlPath) || startsWith("ftp://" , htmlPath))