c9b40ed334908a1b791191a3df227ae991b4810e braney Fri Mar 22 18:07:12 2013 -0700 fold back in the changes Angie made in the commit before my last commit. Change cartCopyCustomTracks() to not take a database argument since it's interation over all the "ctfile_*" in the cart anyway.All of this is to fix the problem that now loading a cart and connecting to hubs is what should be an atomic act. As it was, there were some hdb routines called after a new cart was loaded, but before the referenced hubs were loaded. As it is now, hgSession will load new carts without reloading the associated hubs. This would only be a problem with assembly hubs, and I don't think it matters since hgSession isn't displaying hub data anyway. diff --git src/hg/lib/cart.c src/hg/lib/cart.c index c3649ca..d910905 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -228,40 +228,41 @@ struct dyString *dy = dyStringNew(1024); int useCount; dyStringPrintf(dy, "SELECT useCount FROM %s " "WHERE userName = '%s' AND sessionName = '%s';", namedSessionTable, encUserName, encSessionName); useCount = sqlQuickNum(conn, dy->string) + 1; dyStringClear(dy); dyStringPrintf(dy, "UPDATE %s SET useCount = %d, lastUse=now() " "WHERE userName = '%s' AND sessionName = '%s';", namedSessionTable, useCount, encUserName, encSessionName); sqlUpdate(conn, dy->string); dyStringFree(&dy); } #ifndef GBROWSE -void cartCopyCustomTracks(struct cart *cart, char *db) +void cartCopyCustomTracks(struct cart *cart) /* If cart contains any live custom tracks, save off a new copy of them, * to prevent clashes by multiple uses of the same session. */ { struct hashEl *el, *elList = hashElListHash(cart->hash); for (el = elList; el != NULL; el = el->next) { if (startsWith(CT_FILE_VAR_PREFIX, el->name)) { + char *db = &el->name[strlen(CT_FILE_VAR_PREFIX)]; struct slName *browserLines = NULL; struct customTrack *ctList = NULL; char *ctFileName = (char *)(el->val); if (fileExists(ctFileName)) ctList = customFactoryParseAnyDb(db, ctFileName, TRUE, &browserLines); /* Save off only if the custom tracks are live -- if none are live, * leave cart variables in place so hgSession can detect and inform * the user. */ if (ctList) { struct customTrack *ct; static struct tempName tn; char *ctFileVar = el->name; char *ctFileName; for (ct = ctList; ct != NULL; ct = ct->next) @@ -404,91 +405,89 @@ 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 -boolean cartLoadUserSession(struct sqlConnection *conn, char *sessionOwner, +void 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); +#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); @@ -509,30 +508,33 @@ 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); +#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); } @@ -607,65 +609,56 @@ 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); #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(); - sessionLoaded = cartLoadUserSession(conn2, otherUser, sessionName, cart, + 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. */