45764c815bb96401f97540ca20ef0b09f67cdcf2
angie
  Fri May 24 13:37:21 2019 -0700
When re-saving session, preserve shared column which is not a boolean but rather {0, 1, 2=public session}.  refs #22440 note-170

diff --git src/hg/hgSession/hgSession.c src/hg/hgSession/hgSession.c
index d2ace25..7eeeccf 100644
--- src/hg/hgSession/hgSession.c
+++ src/hg/hgSession/hgSession.c
@@ -761,31 +761,31 @@
         }
     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
 static int saveCartAsSession(struct sqlConnection *conn, char *encUserName, char *encSessionName,
-                             boolean shareSession)
+                             int sharingLevel)
 /* 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);
@@ -811,31 +811,31 @@
 sqlDyStringPrintf(dy, "INSERT INTO %s ", namedSessionTable);
 dyStringAppend(dy, "(userName, sessionName, contents, shared, "
                "firstUse, lastUse, useCount, settings) VALUES (");
 dyStringPrintf(dy, "'%s', '%s', ", encUserName, encSessionName);
 dyStringAppend(dy, "'");
 cleanHgSessionFromCart(cart);
 struct dyString *encoded = newDyString(4096);
 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, "%d, ", sharingLevel);
 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.";
@@ -1545,82 +1545,82 @@
 			namedSessionTable, dyRa->string, encUserName, encSessionName);
 	sqlUpdate(conn, dyQuery->string);
 	dyStringPrintf(dyMessage, "Updated description of <B>%s</B>.\n", sessionName);
 	}
     }
 if (isEmpty(dyMessage->string))
     dyStringPrintf(dyMessage, "No changes to session <B>%s</B>.\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)
+static int getSharingLevel(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. */
+ * errAbort if there is no such session. (0 = not shared, 1 = shared by link, 2 = public 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);
+int sharingLevel = getSharingLevel(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);
 // Some old sessions reference databases that are no longer present, and that triggers an errAbort
 // when cartHideDefaultTracks calls hgTrackDb.  Don't let that stop the process of updating other
 // stuff in the session.
 struct errCatch *errCatch = errCatchNew();
 if (errCatchStart(errCatch))
     cartHideDefaultTracks(cart);
 errCatchEnd(errCatch);
 if (errCatch->gotError)
     fprintf(stderr, "doReSaveSession: Error from cartHideDefaultTracks: '%s'; Continuing...",
             errCatch->message->string);
 errCatchFree(&errCatch);
 struct dyString *dyMessage = dyStringNew(1024);
 dyStringPrintf(dyMessage,
                "Re-saved settings from user <B>%s</B>'s session <B>%s</B> "
                "that %s be shared with others.  %s %s",
-	       userName, htmlEncode(sessionName), (shareSession ? "may" : "may not"),
+	       userName, htmlEncode(sessionName), (sharingLevel ? "may" : "may not"),
 	       getSessionLink(userName, encSessionName),
 	       getSessionEmailLink(encUserName, encSessionName));
 cartCheckForCustomTracks(cart, dyMessage);
-int useCount = saveCartAsSession(conn, encUserName, encSessionName, shareSession);
+int useCount = saveCartAsSession(conn, encUserName, encSessionName, sharingLevel);
 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");