05094dabf3d005ab35a998ff225443fc4255611f galt Mon Feb 4 23:07:42 2019 -0800 Adding ability to backup and restore the cart and its custom tracks in hgSession. diff --git src/hg/lib/cart.c src/hg/lib/cart.c index 4d5f22d..da01c6b 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -1500,44 +1500,61 @@ struct cart *cart = *pCart; if (cart != NULL) { saveState(cart); struct sqlConnection *conn = cartDefaultConnector(); cartTrace(cart, "checkout", conn); cartDefaultDisconnector(&conn); cartDbFree(&cart->userInfo); cartDbFree(&cart->sessionInfo); freeHash(&cart->hash); freeHash(&cart->exclude); freez(pCart); } } +void cartSaveState(struct cart *cart) +/* Free up cart and save it to database. + * Intended for updating cart before background CGI runs. + * Use cartCheckout() instead. */ +{ +if (cart != NULL) + { + saveState(cart); + } +} + char *cartSessionVarName() /* Return name of CGI session ID variable. */ { return sessionVar; } char *cartSessionId(struct cart *cart) /* Return session id. */ { static char buf[256]; cartDbSecureId(buf, sizeof buf, cart->sessionInfo); return buf; } +unsigned cartSessionRawId(struct cart *cart) +/* Return raw session id without security key. */ +{ +return cart->sessionInfo->id; +} + char *cartSidUrlString(struct cart *cart) /* Return session id string as in hgsid=N . */ { static char buf[64]; safef(buf, sizeof(buf), "%s=%s", cartSessionVarName(), cartSessionId(cart)); return buf; } char *cartUserId(struct cart *cart) /* Return session id. */ { static char buf[256]; cartDbSecureId(buf, sizeof buf, cart->userInfo); return buf; } @@ -3389,93 +3406,123 @@ } anythingChanged = (anythingChanged || (clensed > 0)); return anythingChanged; } void cgiExitTime(char *cgiName, long enteredMainTime) /* single stderr print out called at end of CGI binaries to record run * time in apache error_log */ { if (sameWord("yes", cfgOptionDefault("browser.cgiTime", "yes")) ) fprintf(stderr, "CGI_TIME: %s: Overall total time: %ld millis\n", cgiName, clock1000() - enteredMainTime); } +// TODO This should probably be moved to customFactory.c +// Only used by hgSession +#include "errCatch.h" void cartCheckForCustomTracks(struct cart *cart, struct dyString *dyMessage) /* Scan cart for ctfile_ variables. Tally up the databases that have * live custom tracks and those that have expired custom tracks. */ /* While we're at it, also look for saved blat results. */ { struct hashEl *helList = cartFindPrefix(cart, CT_FILE_VAR_PREFIX); if (helList != NULL) { struct hashEl *hel; - boolean gotLiveCT = FALSE, gotExpiredCT = FALSE; - struct slName *liveDbList = NULL, *expiredDbList = NULL, *sln = NULL; + boolean gotLiveCT = FALSE, gotExpiredCT = FALSE, gotErrorCT = FALSE; + struct slName *liveDbList = NULL, *expiredDbList = NULL, *errorDbList = NULL, *sln = NULL; for (hel = helList; hel != NULL; hel = hel->next) { char *db = hel->name + strlen(CT_FILE_VAR_PREFIX); - boolean thisGotLiveCT = FALSE, thisGotExpiredCT = FALSE; + boolean thisGotLiveCT = FALSE, thisGotExpiredCT = FALSE, thisGotErrorCT = FALSE; + char errMsg[4096]; /* If the file doesn't exist, just remove the cart variable so it * doesn't get copied from session to session. If it does exist, * leave it up to customFactoryTestExistence to parse the file for * possible customTrash table references, some of which may exist * and some not. */ if (!fileExists(hel->val)) { cartRemove(cart, hel->name); thisGotExpiredCT = TRUE; } else { - customFactoryTestExistence(db, hel->val, - &thisGotLiveCT, &thisGotExpiredCT); + /* protect against errAbort */ + struct errCatch *errCatch = errCatchNew(); + if (errCatchStart(errCatch)) + { + customFactoryTestExistence(db, hel->val, &thisGotLiveCT, &thisGotExpiredCT, NULL); + } + errCatchEnd(errCatch); + if (errCatch->gotError) // tends to abort if db not found or hub not attached. + { + thisGotErrorCT = TRUE; + safef(errMsg, sizeof errMsg, "%s {%s}", db, errCatch->message->string); + } + errCatchFree(&errCatch); } if (thisGotLiveCT) slNameAddHead(&liveDbList, db); if (thisGotExpiredCT) slNameAddHead(&expiredDbList, db); + if (thisGotErrorCT) + slNameAddHead(&errorDbList, errMsg); gotLiveCT |= thisGotLiveCT; gotExpiredCT |= thisGotExpiredCT; + gotErrorCT |= thisGotErrorCT; } if (gotLiveCT) { slSort(&liveDbList, slNameCmp); dyStringPrintf(dyMessage, "

Note: the session has at least one active custom " "track (in database "); for (sln = liveDbList; sln != NULL; sln = sln->next) dyStringPrintf(dyMessage, "%s%s", cartSidUrlString(cart), sln->name, sln->name, (sln->next ? sln->next->next ? ", " : " and " : "")); dyStringAppend(dyMessage, "; click on the database link " "to manage custom tracks). "); } if (gotExpiredCT) { slSort(&expiredDbList, slNameCmp); dyStringPrintf(dyMessage, "

Note: the session has at least one expired custom " "track (in database "); for (sln = expiredDbList; sln != NULL; sln = sln->next) dyStringPrintf(dyMessage, "%s%s", sln->name, (sln->next ? sln->next->next ? ", " : " and " : "")); dyStringPrintf(dyMessage, "), so it may not appear as originally intended. "); } + if (gotErrorCT) + { + slSort(&errorDbList, slNameCmp); + dyStringPrintf(dyMessage, + "

Note: the session has at least one custom " + "track with errors (in database "); + for (sln = errorDbList; sln != NULL; sln = sln->next) + dyStringPrintf(dyMessage, "%s%s", + sln->name, (sln->next ? sln->next->next ? ", " : " and " : "")); + dyStringPrintf(dyMessage, + "), so it may not appear as originally intended. "); + } dyStringPrintf(dyMessage, "These custom tracks should not expire, however, " "the UCSC Genome Browser is not a data storage service; " "please keep a local backup of your sessions contents " "and custom track data.

"); slNameFreeList(&liveDbList); slNameFreeList(&expiredDbList); } /* Check for saved blat results (quasi custom track). */ char *ss = cartOptionalString(cart, "ss"); if (isNotEmpty(ss)) { char buf[1024]; char *words[2]; int wordCount;