ff61568e30e9390cd4d261aa73b2e9f058601af7 braney Mon Feb 27 10:29:37 2023 -0800 merge cart hashes if we're merging sessions diff --git src/hg/lib/cart.c src/hg/lib/cart.c index 2f03f02..47e6f55 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -155,56 +155,69 @@ if (!sqlTableExists(conn, userDbTable())) { fprintf(stderr, "cartTablesOk failed on %s.%s pid=%ld\n", sqlGetDatabase(conn), userDbTable(), (long)getpid()); return FALSE; } if (!sqlTableExists(conn, sessionDbTable())) { fprintf(stderr, "cartTablesOk failed on %s.%s pid=%ld\n", sqlGetDatabase(conn), sessionDbTable(), (long)getpid()); return FALSE; } return TRUE; } -void cartParseOverHash(struct cart *cart, char *contents) -/* Parse cgi-style contents into a hash table. This will *not* +void cartParseOverHashExt(struct cart *cart, char *contents, boolean merge) +/* Parse cgi-style contents into a hash table. If merge is FALSE, this will *not* * replace existing members of hash that have same name, so we can * support multi-select form inputs (same var name can have multiple - * values which will be in separate hashEl's). */ + * values which will be in separate hashEl's). If merge is TRUE, we + * replace existing values with new values */ { struct hash *hash = cart->hash; char *namePt, *dataPt, *nextNamePt; namePt = contents; while (namePt != NULL && namePt[0] != 0) { dataPt = strchr(namePt, '='); if (dataPt == NULL) errAbort("Mangled input string %s", namePt); *dataPt++ = 0; nextNamePt = strchr(dataPt, '&'); if (nextNamePt == NULL) nextNamePt = strchr(dataPt, ';'); /* Accomodate DAS. */ if (nextNamePt != NULL) *nextNamePt++ = 0; cgiDecode(dataPt,dataPt,strlen(dataPt)); + if (!merge) hashAdd(hash, namePt, cloneString(dataPt)); + else + hashReplace(hash, namePt, cloneString(dataPt)); namePt = nextNamePt; } } +void cartParseOverHash(struct cart *cart, char *contents) +/* Parse cgi-style contents into a hash table. This will *not* + * replace existing members of hash that have same name, so we can + * support multi-select form inputs (same var name can have multiple + * values which will be in separate hashEl's). */ +{ +cartParseOverHashExt(cart, contents, FALSE); +} + static boolean looksCorrupted(struct cartDb *cdb) /* Test for db corruption by checking format of firstUse field. */ { if (cdb == NULL) return FALSE; else { char *words[3]; int wordCount = 0; boolean isCorr = FALSE; char *fu = cloneString(cdb->firstUse); wordCount = chopByChar(fu, '-', words, ArraySize(words)); if (wordCount < 3) isCorr = TRUE; else @@ -577,32 +590,36 @@ if ((row = sqlNextRow(sr)) != NULL) { boolean shared = atoi(row[0]); if (shared || (userName && sameString(sessionOwner, userName))) { char *sessionVar = cartSessionVarName(); char *hgsid = cartSessionId(cart); char *sessionTableString = cartOptionalString(cart, hgSessionTableState); sessionTableString = cloneString(sessionTableString); char *pubSessionsTableString = cartOptionalString(cart, hgPublicSessionsTableState); pubSessionsTableString = cloneString(pubSessionsTableString); struct sqlConnection *conn2 = hConnectCentral(); sessionTouchLastUse(conn2, encSessionOwner, encSessionName); if (!merge) + { cartRemoveLike(cart, "*"); cartParseOverHash(cart, row[1]); + } + else + cartParseOverHashExt(cart, row[1], TRUE); cartSetString(cart, sessionVar, hgsid); if (sessionTableString != NULL) cartSetString(cart, hgSessionTableState, sessionTableString); if (pubSessionsTableString != NULL) cartSetString(cart, hgPublicSessionsTableState, pubSessionsTableString); if (oldVars) hashEmpty(oldVars); /* Overload settings explicitly passed in via CGI (except for the * command that sent us here): */ loadCgiOverHash(cart, oldVars); if (isNotEmpty(actionVar)) cartRemove(cart, actionVar); hDisconnectCentral(&conn2); } else