08eca70e11b8f438fd9692051fbe2cbf611ae65c braney Mon Mar 18 10:29:20 2013 -0700 if loading a session, don't copy the custom tracks till after the assembly hubs have been loaded since the cart variable for the custom tracks as the database name in it. ref #10396 diff --git src/hg/lib/cart.c src/hg/lib/cart.c index 6c4ea2d..c3649ca 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -404,89 +404,91 @@ hashRemove(hash, hel->name); } hashElFreeList(&helList); assert(hashNumEntries(hash) == 0); } INLINE char *getDb(struct cart *cart, struct hash *oldVars) /* Quick wrapper around getDbGenomeClade for when we only want db. */ { char *db=NULL, *ignoreOrg, *ignoreClade; getDbGenomeClade(cart, &db, &ignoreOrg, &ignoreClade, oldVars); return db; } #ifndef GBROWSE -void cartLoadUserSession(struct sqlConnection *conn, char *sessionOwner, +boolean cartLoadUserSession(struct sqlConnection *conn, char *sessionOwner, char *sessionName, struct cart *cart, struct hash *oldVars, char *actionVar) /* If permitted, load the contents of the given user's session, and then * reload the CGI settings (to support override of session settings). * If non-NULL, oldVars will contain values overloaded when reloading CGI. * If non-NULL, actionVar is a cartRemove wildcard string specifying the * CGI action variable that sent us here. */ +/* Return TRUE if a session was loaded. */ { struct sqlResult *sr = NULL; char **row = NULL; char *userName = wikiLinkUserName(); char *encSessionName = cgiEncodeFull(sessionName); char *encSessionOwner = cgiEncodeFull(sessionOwner); char query[512]; +boolean loadedSession = FALSE; if (isEmpty(sessionOwner)) errAbort("Please go back and enter a wiki user name for this session."); if (isEmpty(sessionName)) errAbort("Please go back and enter a session name to load."); safef(query, sizeof(query), "SELECT shared, contents FROM %s " "WHERE userName = '%s' AND sessionName = '%s';", namedSessionTable, encSessionOwner, encSessionName); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) != NULL) { boolean shared = atoi(row[0]); if (shared || (userName && sameString(sessionOwner, userName))) { char *sessionVar = cartSessionVarName(); unsigned hgsid = cartSessionId(cart); struct sqlConnection *conn2 = hConnectCentral(); sessionTouchLastUse(conn2, encSessionOwner, encSessionName); cartRemoveLike(cart, "*"); cartParseOverHash(cart, row[1]); cartSetInt(cart, sessionVar, hgsid); if (oldVars) hashEmpty(oldVars); /* Overload settings explicitly passed in via CGI (except for the * command that sent us here): */ loadCgiOverHash(cart, oldVars); -#ifndef GBROWSE - cartCopyCustomTracks(cart, getDb(cart, oldVars)); -#endif /* GBROWSE */ if (isNotEmpty(actionVar)) cartRemove(cart, actionVar); hDisconnectCentral(&conn2); + loadedSession = TRUE; } else errAbort("Sharing has not been enabled for user %s's session %s.", sessionOwner, sessionName); } else errAbort("Could not find session %s for user %s.", sessionName, sessionOwner); sqlFreeResult(&sr); freeMem(encSessionName); + +return loadedSession; } #endif /* GBROWSE */ void cartLoadSettings(struct lineFile *lf, struct cart *cart, struct hash *oldVars, char *actionVar) /* Load settings (cartDump output) into current session, and then * reload the CGI settings (to support override of session settings). * If non-NULL, oldVars will contain values overloaded when reloading CGI. * If non-NULL, actionVar is a cartRemove wildcard string specifying the * CGI action variable that sent us here. */ { char *line = NULL; int size = 0; char *sessionVar = cartSessionVarName(); unsigned hgsid = cartSessionId(cart); @@ -507,33 +509,30 @@ struct dyString *dy = dyStringSub(val, "\\n", "\n"); cartAddString(cart, var, dy->string); dyStringFree(&dy); } else if (var != NULL) { cartSetString(cart, var, ""); } } /* not hgsid */ } /* each line */ if (oldVars) hashEmpty(oldVars); /* Overload settings explicitly passed in via CGI (except for the * command that sent us here): */ loadCgiOverHash(cart, oldVars); -#ifndef GBROWSE -cartCopyCustomTracks(cart, getDb(cart, oldVars)); -#endif /* GBROWSE */ if (isNotEmpty(actionVar)) cartRemove(cart, actionVar); } static char *now() /* Return a mysql-formatted time like "2008-05-19 15:33:34". */ { char nowBuf[256]; time_t seconds = clock1(); struct tm *theTime = localtime(&seconds); strftime(nowBuf, sizeof nowBuf, "%Y-%m-%d %H:%M:%S", theTime); return cloneString(nowBuf); } @@ -604,60 +603,69 @@ cart->userInfo = loadDb(conn, "userDb", userId, &userIdFound); cart->sessionInfo = loadDb(conn, "sessionDb", sessionId, &sessionIdFound); if (sessionIdFound) cartParseOverHash(cart, cart->sessionInfo->contents); else if (userIdFound) cartParseOverHash(cart, cart->userInfo->contents); char when[1024]; safef(when, sizeof(when), "open %d %d", userId, sessionId); cartTrace(cart, when, conn); loadCgiOverHash(cart, oldVars); // I think this is the place to justify old and new values cartJustify(cart, oldVars); -/* wire up the assembly hubs so we can operate without sql */ -hubConnectLoadHubs(cart); - #ifndef GBROWSE /* If some CGI other than hgSession been passed hgSession loading instructions, * apply those to cart before we do anything else. (If this is hgSession, * let it handle the settings so it can display feedback to the user.) */ +boolean sessionLoaded = FALSE; if (! (cgiScriptName() && endsWith(cgiScriptName(), "hgSession"))) { if (cartVarExists(cart, hgsDoOtherUser)) { char *otherUser = cartString(cart, hgsOtherUserName); char *sessionName = cartString(cart, hgsOtherUserSessionName); struct sqlConnection *conn2 = hConnectCentral(); - cartLoadUserSession(conn2, otherUser, sessionName, cart, + sessionLoaded = cartLoadUserSession(conn2, otherUser, sessionName, cart, oldVars, hgsDoOtherUser); hDisconnectCentral(&conn2); cartTrace(cart, "after cartLUS", conn); } else if (cartVarExists(cart, hgsDoLoadUrl)) { char *url = cartString(cart, hgsLoadUrlName); struct lineFile *lf = netLineFileOpen(url); + sessionLoaded = TRUE; cartLoadSettings(lf, cart, oldVars, hgsDoLoadUrl); lineFileClose(&lf); cartTrace(cart, "after cartLS", conn); } } #endif /* GBROWSE */ +/* wire up the assembly hubs so we can operate without sql */ +hubConnectLoadHubs(cart); + +#ifndef GBROWSE +// if we loaded a session, we want to copy the custom tracks so +// we don't change them in the session +if (sessionLoaded) + cartCopyCustomTracks(cart, getDb(cart, oldVars)); +#endif /* GBROWSE */ + if (exclude != NULL) { while ((ex = *exclude++)) cartExclude(cart, ex); } cartDefaultDisconnector(&conn); return cart; } static void updateOne(struct sqlConnection *conn, char *table, struct cartDb *cdb, char *contents, int contentSize) /* Update cdb in database. */