fd526976ba5971d4bae14235cf2f735751a5e548
angie
Wed May 15 14:26:41 2019 -0700
Adding doReSaveSession to streamline loading and saving a session in one CGI request, for converting old session trash paths and customTrash tables to userdata and customData. refs #22440
diff --git src/hg/hgSession/hgSession.c src/hg/hgSession/hgSession.c
index c07a0d5..1532a6a 100644
--- src/hg/hgSession/hgSession.c
+++ src/hg/hgSession/hgSession.c
@@ -745,44 +745,34 @@
}
}
if (tdb->visibility != tvHide)
outIfNotPresent(cart, dy, tdb->track, tdb->visibility);
}
// Put a variable in the cart that says we put the default
// visibilities in it.
if (dy)
dyStringPrintf(dy,"&%s=on", CART_HAS_DEFAULT_VISIBILITY);
else
printf("%s on", CART_HAS_DEFAULT_VISIBILITY);
}
#define INITIAL_USE_COUNT 0
-char *doNewSession(char *userName)
-/* Save current settings in a new named session.
- * Return a message confirming what we did. */
-{
-if (userName == NULL)
- return "Unable to save session -- please log in and try again.";
-struct dyString *dyMessage = dyStringNew(2048);
-char *sessionName = trimSpaces(cartString(cart, hgsNewSessionName));
-char *encSessionName = cgiEncodeFull(sessionName);
-boolean shareSession = cartBoolean(cart, hgsNewSessionShare);
-char *encUserName = cgiEncodeFull(userName);
-struct sqlConnection *conn = hConnectCentral();
-
-if (sqlTableExists(conn, namedSessionTable))
+static int saveCartAsSession(struct sqlConnection *conn, char *encUserName, char *encSessionName,
+ boolean shareSession)
+/* Save all settings in cart, either adding a new session or overwriting an existing session.
+ * Return useCount so that the caller can distinguish between adding and overWriting. */
{
struct sqlResult *sr = NULL;
struct dyString *dy = dyStringNew(16 * 1024);
char **row;
char *firstUse = "now()";
int useCount = INITIAL_USE_COUNT;
char firstUseBuf[32];
/* If this session already existed, preserve its firstUse and useCount. */
sqlDyStringPrintf(dy, "SELECT firstUse, useCount FROM %s "
"WHERE userName = '%s' AND sessionName = '%s';",
namedSessionTable, encUserName, encSessionName);
sr = sqlGetResult(conn, dy->string);
if ((row = sqlNextRow(sr)) != NULL)
{
@@ -813,31 +803,49 @@
cartEncodeState(cart, encoded);
// Now add all the default visibilities to output.
outDefaultTracks(cart, encoded);
sqlDyAppendEscaped(dy, encoded->string);
dyStringFree(&encoded);
dyStringAppend(dy, "', ");
dyStringPrintf(dy, "%d, ", (shareSession ? 1 : 0));
dyStringPrintf(dy, "%s, now(), %d, '');", firstUse, useCount);
sqlUpdate(conn, dy->string);
dyStringFree(&dy);
/* Prevent modification of custom track collections just saved to namedSessionDb: */
cartCopyCustomComposites(cart);
+return useCount;
+}
+char *doNewSession(char *userName)
+/* Save current settings in a new named session.
+ * Return a message confirming what we did. */
+{
+if (userName == NULL)
+ return "Unable to save session -- please log in and try again.";
+struct dyString *dyMessage = dyStringNew(2048);
+char *sessionName = trimSpaces(cartString(cart, hgsNewSessionName));
+char *encSessionName = cgiEncodeFull(sessionName);
+boolean shareSession = cartBoolean(cart, hgsNewSessionShare);
+char *encUserName = cgiEncodeFull(userName);
+struct sqlConnection *conn = hConnectCentral();
+
+if (sqlTableExists(conn, namedSessionTable))
+ {
+ int useCount = saveCartAsSession(conn, encUserName, encSessionName, shareSession);
if (useCount > INITIAL_USE_COUNT)
dyStringPrintf(dyMessage,
"Overwrote the contents of session %s "
"(that %s be shared with other users). "
"%s %s",
htmlEncode(sessionName), (shareSession ? "may" : "may not"),
getSessionLink(encUserName, encSessionName),
getSessionEmailLink(encUserName, encSessionName));
else
dyStringPrintf(dyMessage,
"Added a new session %s that %s be shared with other users. "
"%s %s",
htmlEncode(sessionName), (shareSession ? "may" : "may not"),
getSessionLink(encUserName, encSessionName),
getSessionEmailLink(encUserName, encSessionName));
@@ -1522,30 +1530,80 @@
namedSessionTable, dyRa->string, encUserName, encSessionName);
sqlUpdate(conn, dyQuery->string);
dyStringPrintf(dyMessage, "Updated description of %s.\n", sessionName);
}
}
if (isEmpty(dyMessage->string))
dyStringPrintf(dyMessage, "No changes to session %s.\n", sessionName);
dyStringPrintf(dyMessage, "%s %s",
getSessionLink(encUserName, encSessionName),
getSessionEmailLink(encUserName, encSessionName));
if (shared)
printShareMessage(dyMessage, encUserName, encSessionName, FALSE);
return dyStringCannibalize(&dyMessage);
}
+static boolean isSessionShared(struct sqlConnection *conn, char *encUserName, char *encSessionName)
+/* Return the value of 'shared' from the namedSessionDb row for user & session;
+ * errAbort if there is no such session. */
+{
+char query[2048];
+sqlSafef(query, sizeof(query), "select shared from %s where userName='%s' and sessionName = '%s';",
+ namedSessionTable, encUserName, encSessionName);
+char buf[256];
+char *sharedStr = sqlQuickQuery(conn, query, buf, sizeof buf);
+if (sharedStr == NULL)
+ errAbort("Unable to find session for userName='%s' and sessionName='%s'; no result from query '%s'",
+ encUserName, encSessionName, query);
+return atoi(sharedStr);
+}
+
+char *doReSaveSession(char *userName, char *actionVar)
+/* Load a session (which may have old trash and customTrash references) and re-save it
+ * so that customTrash tables will be moved to customData* databases and trash paths
+ * will be replaced with userdata (hg.conf sessionDataDir) paths.
+ * NOTE: this is not intended to be reachable by the UI; it is for a script to update
+ * old sessions to use the new sessionData locations. */
+{
+if (userName == NULL)
+ return "Unable to re-save session -- please log in and try again.";
+struct sqlConnection *conn = hConnectCentral();
+char *sessionName = cloneString(trimSpaces(cartString(cart, hgsNewSessionName)));
+char *encUserName = cgiEncodeFull(userName);
+char *encSessionName = cgiEncodeFull(sessionName);
+boolean shareSession = isSessionShared(conn, encUserName, encSessionName);
+cartLoadUserSession(conn, userName, sessionName, cart, NULL, actionVar);
+// Don't cartCopyCustomComposites because we're not going to make any track collection changes
+hubConnectLoadHubs(cart);
+cartHideDefaultTracks(cart);
+struct dyString *dyMessage = dyStringNew(1024);
+dyStringPrintf(dyMessage,
+ "Re-saved settings from user %s's session %s "
+ "that %s be shared with others. %s %s",
+ userName, htmlEncode(sessionName), (shareSession ? "may" : "may not"),
+ getSessionLink(userName, encSessionName),
+ getSessionEmailLink(encUserName, encSessionName));
+cartCheckForCustomTracks(cart, dyMessage);
+int useCount = saveCartAsSession(conn, encUserName, encSessionName, shareSession);
+if (useCount <= INITIAL_USE_COUNT)
+ errAbort("Expected useCount of at least %d after re-saving session for "
+ "userName='%s', sessionName='%s', but got %d",
+ INITIAL_USE_COUNT+1, encUserName, encSessionName, useCount);
+hDisconnectCentral(&conn);
+return dyStringCannibalize(&dyMessage);
+}
+
// ======================================
void prepBackGroundCall(char **pBackgroundProgress, char *cleanPrefix)
/* fix cart and save state */
{
*pBackgroundProgress = cloneString(cgiUsualString("backgroundProgress", NULL));
cartRemove(cart, "backgroundExec");
cartRemove(cart, "backgroundProgress");
cartRemovePrefix(cart, cleanPrefix);
cartSaveState(cart); // in case it crashes
}
void launchForeAndBackGround(char *operation)
/* update cart, launch background and foreground */
{
@@ -1718,30 +1776,35 @@
doMainPage(userName, message);
}
else if (cartVarExists(cart, hgsOldSessionName))
{
char *message1 = doSessionChange(userName, cartString(cart, hgsOldSessionName));
char *message2 = doUpdateSessions(userName);
char *message = message2;
if (!startsWith("No changes to session", message1))
{
size_t len = (sizeof message1[0]) * (strlen(message1) + strlen(message2) + 1);
message = needMem(len);
safef(message, len, "%s%s", message1, message2);
}
doMainPage(userName, message);
}
+else if (cartVarExists(cart, hgsDoReSaveSession))
+ {
+ char *message = doReSaveSession(userName, hgsDoReSaveSession);
+ printf("\n%s\n\n", message);
+ }
else
{
char *message = doUpdateSessions(userName);
doMainPage(userName, message);
}
cleanHgSessionFromCart(cart);
/* Save the cart state: */
cartCheckout(&cart);
}
int main(int argc, char *argv[])
/* Process command line. */
{
long enteredMainTime = clock1000();