4d2eb49f84199890ac7e679ba67f094cb49bd124 braney Thu Apr 6 14:29:02 2023 -0700 Change recommended track sets to merge with the current session. refs #28525 diff --git src/hg/lib/cart.c src/hg/lib/cart.c index a3d4185..c845934 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -155,60 +155,80 @@ 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 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). If merge is TRUE, we - * replace existing values with new values */ +static void mergeHash(struct hash *first, struct hash *second) +/* Merge one hash on top of another. */ +{ +struct hashCookie cookie = hashFirst(second); +struct hashEl *hel; +while ((hel = hashNext(&cookie)) != NULL) + hashReplace(first, hel->name, hel->val); +} + +static void loadHash(struct hash *hash, char *contents) +/* Load a hash from a cart-like string. */ { -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 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). If merge is TRUE, we + * replace existing values with new values */ +{ +if (merge) + { + struct hash *newHash = newHash(8); + + loadHash(newHash, contents); + mergeHash(newHash, cart->hash); + cart->hash = newHash; + } +else + loadHash(cart->hash, contents); +} + 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 @@ -322,30 +342,41 @@ "MySQL problem??", id); if (!sameString(sessionKey,"")) freeMem(sessionKey); } *found = result; return cdb; } void cartExclude(struct cart *cart, char *var) /* Exclude var from persistent storage. */ { hashAdd(cart->exclude, var, NULL); } +static char *_cartNamedSessionDbTable = NULL; + +char *cartNamedSessionDbTable() +/* Get the name of the table that lists named sessions. Don't free the result. */ +{ +if (_cartNamedSessionDbTable == NULL) + _cartNamedSessionDbTable = cfgOptionEnvDefault("HGDB_NAMED_SESSION_DB", namedSessionDbTableConfVariable, + defaultNamedSessionDb); +return _cartNamedSessionDbTable; +} + void sessionTouchLastUse(struct sqlConnection *conn, char *encUserName, char *encSessionName) /* Increment namedSessionDb.useCount and update lastUse for this session. */ { struct dyString *dy = dyStringNew(1024); int useCount; sqlDyStringPrintf(dy, "SELECT useCount FROM %s " "WHERE userName = '%s' AND sessionName = '%s';", namedSessionTable, encUserName, encSessionName); useCount = sqlQuickNum(conn, dy->string) + 1; dyStringClear(dy); sqlDyStringPrintf(dy, "UPDATE %s SET useCount = %d, lastUse=now() " "WHERE userName = '%s' AND sessionName = '%s';", namedSessionTable, useCount, encUserName, encSessionName); sqlUpdate(conn, dy->string);