67774b8e85d05089eb6482e1ea865c4298f4ac36
chmalee
  Tue Sep 19 09:41:09 2023 -0700
When appending pcr results, if we would be writing to a file that is in a saved session, first copy the session pcr results into a new trash file, and then write our new results into that. This keeps the session unchanged, refs #32236

diff --git src/hg/hgPcr/hgPcr.c src/hg/hgPcr/hgPcr.c
index e2d295c..2bfd5b3 100644
--- src/hg/hgPcr/hgPcr.c
+++ src/hg/hgPcr/hgPcr.c
@@ -19,30 +19,31 @@
 #include "cheapcgi.h"
 #include "htmshell.h"
 #include "hdb.h"
 #include "hui.h"
 #include "cart.h"
 #include "dbDb.h"
 #include "blatServers.h"
 #include "targetDb.h"
 #include "pcrResult.h"
 #include "trashDir.h"
 #include "web.h"
 #include "botDelay.h"
 #include "oligoTm.h"
 #include "trackHub.h"
 #include "hubConnect.h"
+#include "obscure.h"
 
 
 struct cart *cart;	/* The user's ui state. */
 struct hash *oldVars = NULL;
 
 /* for earlyBotCheck() function at the beginning of main() */
 #define delayFraction   1.0     /* standard penalty for most CGIs */
 static boolean issueBotWarning = FALSE;
 
 void usage()
 /* Explain usage and exit. */
 {
 errAbort(
   "hgPcr - In-silico PCR CGI for UCSC\n"
   "usage:\n"
@@ -519,39 +520,61 @@
 
 void writePcrResultTrack(struct gfPcrOutput *gpoList, char *db, char *target, boolean appendToResults)
 /* Write trash files and store their name in a cart variable. */
 {
 char *cartVar = pcrResultCartVar(db);
 struct tempName bedTn, primerTn;
 char buf[2048];
 char *pslFile, *txtFile, *cartTarget, *cartResult;
 if ( (cartResult = cartOptionalString(cart, cartVar)) != NULL && appendToResults)
     {
     char *pcrFiles[3];
     chopByWhite(cloneString(cartResult), pcrFiles, 3);
     pslFile = pcrFiles[0];
     txtFile = pcrFiles[1];
     cartTarget = pcrFiles[2];
+    // if the old result is from a saved session, we can't append to it
+    // because we want the session to not change. Copy the old results
+    // into a new file and append these results to it
+    char *sessionDataDir = cfgOption("sessionDataDir");
+    if (sessionDataDir && startsWith(sessionDataDir, pslFile))
+        {
+        trashDirFile(&bedTn, "hgPcr", "hgPcr", ".psl");
+        trashDirFile(&primerTn, "hgPcr", "hgPcr", ".txt");
+        // copy the old to the new
+        copyFile(pslFile, bedTn.forCgi);
+        copyFile(txtFile, primerTn.forCgi);
+        gfPcrOutputWriteAll(gpoList, "psl", NULL, bedTn.forCgi);
+        writePrimers(gpoList, primerTn.forCgi);
+        if (isNotEmpty(target))
+            safef(buf, sizeof(buf), "%s %s %s", bedTn.forCgi, primerTn.forCgi, target);
+        else
+            safef(buf, sizeof(buf), "%s %s", bedTn.forCgi, primerTn.forCgi);
+        cartSetString(cart, cartVar, buf);
+        }
+    else
+        {
         gfPcrOutputWriteAll(gpoList, "psl", NULL, pslFile);
         writePrimers(gpoList, txtFile);
         if (isNotEmpty(target) && isEmpty(cartTarget))
             {
             /* User is adding a targetDb search */
             safef(buf, sizeof(buf), "%s %s %s", pslFile, txtFile, target);
             cartSetString(cart, cartVar, buf);
             }
         }
+    }
 else
     {
     trashDirFile(&bedTn, "hgPcr", "hgPcr", ".psl");
     trashDirFile(&primerTn, "hgPcr", "hgPcr", ".txt");
     gfPcrOutputWriteAll(gpoList, "psl", NULL, bedTn.forCgi);
     writePrimers(gpoList, primerTn.forCgi);
     if (isNotEmpty(target))
         safef(buf, sizeof(buf), "%s %s %s", bedTn.forCgi, primerTn.forCgi, target);
     else
         safef(buf, sizeof(buf), "%s %s", bedTn.forCgi, primerTn.forCgi);
     cartSetString(cart, cartVar, buf);
     }
 }
 
 static void printHelpLinks(struct gfPcrOutput *gpoList) {