404d5bb6d8c0418d5f06535ef470e36c35d2a237
chmalee
  Thu Apr 16 15:57:56 2026 -0700
Add assembly hub support to hubSpace.

Users can upload a .2bit to create an assembly hub, optionally alongside
their own *.hub.txt (prefix names like araTha1.hub.txt are recognized)
and sibling track files. Uploads run in parallel; hub.txt mutations are
serialized per-hub via flock so arrival order does not matter.

- hubSpace table gains a hubType column ('trackHub' or 'assemblyHub');
ON DUPLICATE KEY UPDATE excludes it so a re-upload cannot revert an
upgraded hub.
- writeHubText can now emit an assembly stanza derived from the 2bit;
upgradeHubTxtForAssembly promotes an existing plain hub.txt in place
when a 2bit arrives after tracks.
- pre-finish decides synthesize vs upgrade vs leave-alone from server
state (existing rows, hub.txt on disk) plus a single client flag
(batchHasHubTxt); client-supplied hubType is no longer trusted.
- Client UI adds 2bit as a file type, locks the genome field when the
hub is authoritative (drilled-in or batch hub.txt), defaults new
uploads to an existing assembly hub at top level, and routes
hgTracks URLs through 'genome=' vs 'db=' by hubType.
- Fix pre-existing nested-path bug in hubPathFromParentDir
(*firstSlash = 0).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

diff --git src/hg/lib/hubSpace.sql src/hg/lib/hubSpace.sql
index 6efd1a172e5..ee643aa81de 100644
--- src/hg/lib/hubSpace.sql
+++ src/hg/lib/hubSpace.sql
@@ -3,27 +3,28 @@
 # an object which can be loaded and saved from RAM in a fairly
 # automatic way.
 
 #file storage table for users to store uploaded tracks
 CREATE TABLE hubSpace (
     userName varchar(255) not null,	# userName of user uploading file
     fileName varchar(10000) not null,	# name of uploaded files or directory. The actual path to this file is different
     fileSize bigint not null,	# size of the uploaded file
     fileType varchar(255) not null,	# track type of file, or subdir if not a track file
     creationTime timestamp default CURRENT_TIMESTAMP(),	# first upload time
     lastModified timestamp,	# last change time
     db varchar(255) not null,	# genome assembly associated with this file
     location varchar(10000) not null,	# file system path or URL to file
     md5sum varchar(255) not null,	# md5sum of file
     parentDir varchar(1024) not null, # parent directory of file
+    hubType varchar(255) not null default 'trackHub', # type of hub this file belongs to: trackHub or assemblyHub
               #Indices
     PRIMARY KEY(userName, fileName(500), parentDir(245)),
     INDEX(userName),
     INDEX(fileName(25)),
     INDEX(fileType),
     INDEX(db),
     INDEX(location(25)),
     INDEX(creationTime),
     INDEX(lastModified),
     INDEX(md5sum),
     INDEX(parentDir)
 );