d2800e10690b66bf2ab04804e124958459f0ff0d
chmalee
  Thu Nov 7 11:11:15 2024 -0800
Add a parentDir field to the hubSpace table and make an index on it

diff --git src/hg/lib/userdata.c src/hg/lib/userdata.c
index cb333bd..3d98b71 100644
--- src/hg/lib/userdata.c
+++ src/hg/lib/userdata.c
@@ -118,79 +118,72 @@
 FILE *f = mustOpen(hubFile, "w");
 //fprintf(stderr, "would write \"hub %s\nemail %s\nshortLabel %s\nlongLabel %s\nuseOneFile on\n\ngenome %s\n\n\" to %s", hubName, emailForUserName(userName), hubName, hubName, db, hubFile);
 fprintf(f, "hub %s\n"
     "email %s\n"
     "shortLabel %s\n"
     "longLabel %s\n"
     "useOneFile on\n"
     "\n"
     "genome %s\n"
     "\n",
     encodedHubName, emailForUserName(userName), hubName, hubName, db);
 carefulClose(&f);
 return hubFile;
 }
 
-char *createNewTempHubForUpload(char *requestId, char *userName, char *db, char *trackFileName, char *trackType, char *reqHubName)
+char *createNewTempHubForUpload(char *requestId, char *userName, char *db, char *trackFileName, char *trackType, char *reqHubName, char *parentDir)
 /* Creates a hub.txt for this upload with a random hub name. Returns the full path to the hub
  * for convenience. If the reqHubName argument is non-NULL, use that as the hub name instead of
  * a random string AND do not create a hub.txt, only for use from hubtools up command */
 {
-char *encodedHubName = reqHubName != NULL ? cgiEncodeFull(reqHubName) : cgiEncodeFull(requestId);
 char *hubFileName = NULL;
 char *path = NULL;
-if (reqHubName)
-    {
-    // coming from hubtools command
 struct dyString *hubPath = dyStringNew(0);
-    dyStringPrintf(hubPath, "%s%s/hub.txt", getDataDir(userName), reqHubName);
-    path = hubFileName = dyStringCannibalize(&hubPath);
-    }
-else
-    {
-    path = prefixUserFile(userName, encodedHubName);
-    hubFileName = writeHubText(path, userName, encodedHubName, requestId, db);
+dyStringPrintf(hubPath, "%s%s", getDataDir(userName), reqHubName);
+// the reqHubName was used to make a directory, so it is cgi-encoded and has a '/' at the end
+char *decoded = needMem(strlen(reqHubName));
+cgiDecodeFull(reqHubName, decoded, strlen(reqHubName));
+path = hubFileName = writeHubText(dyStringCannibalize(&hubPath), userName, reqHubName, decoded, db);
 char *encodedTrack = cgiEncodeFull(trackFileName);
 struct dyString *trackFilePath = dyStringCreate("../%s", encodedTrack);
 FILE *f = mustOpen(hubFileName, "a");
 fprintf(f, "track %s\n"
     "bigDataUrl %s\n"
     "type %s\n"
     "shortLabel %s\n"
     "longLabel %s\n"
     "\n",
     encodedTrack, dyStringCannibalize(&trackFilePath),
     trackType, trackFileName, trackFileName);
 carefulClose(&f);
-    }
 
 // we should update the mysql table now with a record of the hub.txt
 struct hubSpace *row = NULL;
 AllocVar(row);
 row->userName = userName;
-row->fileName = hubFileName;
+row->fileName = "hub.txt";
 row->fileSize = fileSize(hubFileName);
 row->fileType = "hub";
 row->creationTime = NULL;
 time_t lastModTime = fileModTime(hubFileName);
 row->lastModified = sqlUnixTimeToDate(&lastModTime, TRUE);
-row->hubNameList = "";
 row->db = db;
 row->location = path;
 row->md5sum = md5HexForFile(hubFileName);
+row->parentDir = parentDir ? parentDir : "";
 addHubSpaceRowForFile(row);
-return encodedHubName;
+return reqHubName;
 }
 
 static void deleteHubSpaceRow(char *fname)
 /* Deletes a row from the hubspace table for a given fname */
 {
 struct sqlConnection *conn = hConnectCentral();
 struct dyString *deleteQuery = sqlDyStringCreate("delete from hubSpace where location='%s'", fname);
 sqlUpdate(conn, dyStringCannibalize(&deleteQuery));
 }
 
 void removeFileForUser(char *fname, char *userName)
 /* Remove a file for this user if it exists */
 {
 // The file to remove must be prefixed by the hg.conf userDataDir
 if (!startsWith(getDataDir(userName), fname))