c6d419ecfb6f122d7a0cb99c37f56c32c089bea3
chmalee
  Thu Jan 22 10:41:38 2026 -0800
HubSpace changes: Allow users to overwrite already uploaded files, but warn them first. When a hub.txt file is being uploaded, don't auto-generate one. Check if the tracks being uploaded already exist in the hub.txt before adding a default stanza for it. Add some more checks in the hook files to prevent faulty uploads. Have the tus client clear localStorage on successful uploads so re-uploads of the same file don't cause confusing errors

diff --git src/hg/lib/hubSpace.c src/hg/lib/hubSpace.c
index dac6e44b15e..35e8fd4d2b3 100644
--- src/hg/lib/hubSpace.c
+++ src/hg/lib/hubSpace.c
@@ -42,35 +42,38 @@
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = hubSpaceLoad(row);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 return list;
 }
 
 void hubSpaceSaveToDb(struct sqlConnection *conn, struct hubSpace *el, char *tableName, int updateSize)
 /* Save hubSpace as a row to the table specified by tableName.
  * As blob fields may be arbitrary size updateSize specifies the approx size
  * of a string that would contain the entire query. Arrays of native types are
  * converted to comma separated strings and loaded as such, User defined types are
- * inserted as NULL. This function automatically escapes quoted strings for mysql. */
+ * inserted as NULL. This function automatically escapes quoted strings for mysql.
+ * Uses ON DUPLICATE KEY UPDATE to handle file overwrites. */
 {
 struct dyString *update = dyStringNew(updateSize);
-sqlDyStringPrintf(update, "insert into %s values ( '%s','%s',%lld,'%s',NULL,'%s','%s','%s','%s','%s')", 
-	tableName,  el->userName,  el->fileName,  el->fileSize,  el->fileType, el->lastModified,  el->db,  el->location,  el->md5sum, el->parentDir);
+sqlDyStringPrintf(update, "insert into %s values ( '%s','%s',%lld,'%s',NULL,'%s','%s','%s','%s','%s') "
+	"ON DUPLICATE KEY UPDATE fileSize=%lld, lastModified='%s', md5sum='%s', location='%s', db='%s'",
+	tableName, el->userName, el->fileName, el->fileSize, el->fileType, el->lastModified, el->db, el->location, el->md5sum, el->parentDir,
+	el->fileSize, el->lastModified, el->md5sum, el->location, el->db);
 fprintf(stderr, "hubSpace row insert:\n\n%s\n\n", update->string);
 fflush(stderr);
 sqlUpdate(conn, update->string);
 dyStringFree(&update);
 fprintf(stderr, "hubSpace update successful\n");
 fflush(stderr);
 }
 
 struct hubSpace *hubSpaceLoad(char **row)
 /* Load a hubSpace from row fetched with select * from hubSpace
  * from database.  Dispose of this with hubSpaceFree(). */
 {
 struct hubSpace *ret;
 
 AllocVar(ret);