3846f517009c43abc65d227a4695645c9b5f3e8a
braney
  Fri Feb 15 18:31:21 2013 -0800
changes necessary to support assembly hubs (#8072)
diff --git src/hg/hgTables/hgTables.c src/hg/hgTables/hgTables.c
index cb77776..e34c788 100644
--- src/hg/hgTables/hgTables.c
+++ src/hg/hgTables/hgTables.c
@@ -19,30 +19,31 @@
 #include "botDelay.h"
 #include "grp.h"
 #include "customTrack.h"
 #include "pipeline.h"
 #include "hgFind.h"
 #include "hgTables.h"
 #include "joiner.h"
 #include "bedCart.h"
 #include "hgMaf.h"
 #include "gvUi.h"
 #include "wikiTrack.h"
 #include "trackHub.h"
 #include "hubConnect.h"
 #include "hgConfig.h"
 #include "udc.h"
+#include "chromInfo.h"
 #if ((defined USE_BAM || defined USE_TABIX) && defined KNETFILE_HOOKS)
 #include "knetUdc.h"
 #endif//def (USE_BAM || USE_TABIX) && KNETFILE_HOOKS
 
 void usage()
 /* Explain usage and exit. */
 {
 errAbort(
   "hgTables - Get table data associated with tracks and intersect tracks\n"
   "usage:\n"
   "   hgTables XXX\n"
   "options:\n"
   "   -xxx=XXX\n"
   );
 }
@@ -311,34 +312,39 @@
 
     struct trackHub *hub = hubStatus->trackHub;
     if (hub != NULL)
 	{
 	hub->name = cloneString(hubName);
 	struct trackHubGenome *hubGenome = trackHubFindGenome(hub, database);
 	if (hubGenome != NULL)
 	    {
 	    struct trackDb *tdbList = trackHubTracksForGenome(hub, hubGenome);
 	    tdbList = trackDbLinkUpGenerations(tdbList);
 	    tdbList = trackDbPolishAfterLinkup(tdbList, database);
 	    trackDbPrioritizeContainerItems(tdbList);
 	    if (tdbList != NULL)
 		{
 		list = slCat(list, tdbList);
+		// we don't add the hub group if the database
+		// is a assembly hub since they have their own groups
+		if (!trackHubDatabase(database))
+		    {
 		struct grp *grp = grpFromHub(hubStatus);
 		slAddHead(pHubGroups, grp);
 		}
 	    }
+	    }
 	
 	// clear this so it isn't free'd later
 	hubStatus->trackHub = NULL;
 	}
     }
 slReverse(pHubGroups);
 
 /* Create dummy group for custom tracks if any. Add custom tracks to list */
 ctList = getCustomTracks();
 for (ct = ctList; ct != NULL; ct = ct->next)
     {
     slAddHead(&list, ct->tdb);
     }
 
 return list;
@@ -351,54 +357,82 @@
 return sameString(regionType, "genome");
 }
 
 static int regionCmp(const void *va, const void *vb)
 /* Compare to sort based on chrom,start */
 {
 const struct region *a = *((struct region **)va);
 const struct region *b = *((struct region **)vb);
 int dif;
 dif = chrStrippedCmp(a->chrom, b->chrom);
 if (dif == 0)
     dif = a->start - b->start;
 return dif;
 }
 
-struct region *getRegionsFullGenome()
-/* Get a region list that covers all of each chromosome. */
+static struct region *getRegionsFullGenomeLocal()
+/* get all the chrom ranges for a local database */
 {
 struct sqlConnection *conn = hAllocConn(database);
 struct sqlResult *sr;
 char **row;
 struct region *region, *regionList = NULL;
 
 sr = sqlGetResult(conn, "select chrom,size from chromInfo");
 while ((row = sqlNextRow(sr)) != NULL)
     {
     AllocVar(region);
     region->chrom = cloneString(row[0]);
     region->end = sqlUnsigned(row[1]);
     region->fullChrom = TRUE;
     region->name = NULL;		/* unused for full chrom */
     slAddHead(&regionList, region);
     }
 slSort(&regionList, regionCmp);
 sqlFreeResult(&sr);
 hFreeConn(&conn);
 return regionList;
 }
 
+static struct region *getRegionsFullGenomeHub()
+/* get all the chrom ranges for a hub database */
+{
+struct chromInfo *ci = trackHubAllChromInfo(database);
+struct region *region, *regionList = NULL;
+
+AllocVar(region);
+for(; ci; ci = ci->next)
+    {
+    AllocVar(region);
+    region->chrom = cloneString(ci->chrom);
+    region->end = ci->size;
+    region->fullChrom = TRUE;
+    region->name = NULL;		/* unused for full chrom */
+    slAddHead(&regionList, region);
+    }
+slSort(&regionList, regionCmp);
+return regionList;
+}
+
+struct region *getRegionsFullGenome()
+/* Get a region list that covers all of each chromosome. */
+{
+if (trackHubDatabase(database))
+    return getRegionsFullGenomeHub();
+return getRegionsFullGenomeLocal();
+}
+
 struct region *getEncodeRegions()
 /* Get encode regions from encodeRegions table. */
 {
 struct sqlConnection *conn = hAllocConn(database);
 struct sqlResult *sr;
 char **row;
 struct region *list = NULL, *region;
 
 sr = sqlGetResult(conn, "select chrom,chromStart,chromEnd,name from encodeRegions order by name desc");
 while ((row = sqlNextRow(sr)) != NULL)
     {
     AllocVar(region);
     region->chrom = cloneString(row[0]);
     region->start = atoi(row[1]);
     region->end = atoi(row[2]);
@@ -697,32 +731,36 @@
 return(hti);
 }
 
 struct hTableInfo *getHtiOnDb(char *db, char *table)
 /* Return primary table info. */
 {
 struct sqlConnection *conn = hAllocConn(db);
 struct hTableInfo *hti = getHti(db, table, conn);
 hFreeConn(&conn);
 return hti;
 }
 
 struct hTableInfo *maybeGetHtiOnDb(char *db, char *table)
 /* Return primary table info, but don't abort if table not there. */
 {
-struct sqlConnection *conn = hAllocConn(db);
+struct sqlConnection *conn = NULL;
+
+if (!trackHubDatabase(database))
+    conn = hAllocConn(db);
 struct hTableInfo *hti = maybeGetHti(db, table, conn);
+if (!trackHubDatabase(database))
 hFreeConn(&conn);
 return hti;
 }
 
 
 boolean isPositional(char *db, char *table)
 /* Return TRUE if it looks to be a positional table. */
 {
 boolean result = FALSE;
 struct sqlConnection *conn = hAllocConn(db);
 if (sqlTableExists(conn, "chromInfo"))
     {
     char chromName[64];
     struct hTableInfo *hti;
     sqlQuickQuery(conn, "select chrom from chromInfo limit 1",
@@ -893,54 +931,54 @@
 	if (track == NULL)
 	    internalErr();
 	}
     }
 return track;
 }
 
 struct grp *makeGroupList(struct trackDb *trackList, struct grp **pHubGrpList, boolean allTablesOk)
 /* Get list of groups that actually have something in them. */
 {
 struct grp *groupsAll, *groupList = NULL, *group;
 struct hash *groupsInTrackList = newHash(0);
 struct hash *groupsInDatabase = newHash(0);
 struct trackDb *track;
 
-/* Stream throught track list building up hash of active groups. */
+/* Stream through track list building up hash of active groups. */
 for (track = trackList; track != NULL; track = track->next)
     {
     if (!hashLookup(groupsInTrackList,track->grp))
         hashAdd(groupsInTrackList, track->grp, NULL);
     }
 
 /* Scan through group table, putting in ones where we have data. */
 groupsAll = hLoadGrps(database);
 for (group = slPopHead(&groupsAll); group != NULL; group = slPopHead(&groupsAll))
     {
     if (hashLookup(groupsInTrackList, group->name))
 	{
 	slAddTail(&groupList, group);
 	hashAdd(groupsInDatabase, group->name, group);
 	}
     else
         grpFree(&group);
     }
 
 /* if we have custom tracks, we want to add the track hubs
  * after that group */
 struct grp *addAfter = NULL;
-if (sameString(groupList->name, "user"))
+if ((groupList != NULL) && sameString(groupList->name, "user"))
     addAfter = groupList;
 
 /* Add in groups from hubs. */
 for (group = slPopHead(pHubGrpList); group != NULL; group = slPopHead(pHubGrpList))
     {
     /* check to see if we're inserting hubs rather than
      * adding them to the front of the list */
     if (addAfter != NULL)
 	{
 	group->next = addAfter->next;
 	addAfter->next = group;
 	}
     else
 	slAddHead(&groupList, group);
     hashAdd(groupsInDatabase, group->name, group);
@@ -1407,36 +1445,38 @@
     bamTabOut(db, table, conn, fields, f);
 else if (isVcfTable(table))
     vcfTabOut(db, table, conn, fields, f);
 else if (isCustomTrack(table))
     {
     doTabOutCustomTracks(db, table, conn, fields, f);
     }
 else
     doTabOutDb(db, db, table, table, f, conn, fields);
 }
 
 struct slName *fullTableFields(char *db, char *table)
 /* Return list of fields in db.table.field format. */
 {
 char dtBuf[256];
-struct sqlConnection *conn;
+struct sqlConnection *conn=NULL;
 struct slName *fieldList = NULL, *dtfList = NULL, *field, *dtf;
 if (isBigBed(database, table, curTrack, ctLookupName))
     {
+    if (!trackHubDatabase(database))
     conn = hAllocConn(db);
     fieldList = bigBedGetFields(table, conn);
+    if (!trackHubDatabase(database))
     hFreeConn(&conn);
     }
 else if (isBamTable(table))
     fieldList = bamGetFields(table);
 else if (isVcfTable(table))
     fieldList = vcfGetFields(table);
 else if (isCustomTrack(table))
     {
     struct customTrack *ct = ctLookupName(table);
     char *type = ct->dbTrackType;
     if (type != NULL)
         {
 	conn = hAllocConn(CUSTOM_TRASH);
 	if (startsWithWord("maf", type) || startsWithWord("makeItems", type) || sameWord("bedDetail", type) || sameWord("pgSnp", type))
 	    fieldList = sqlListFields(conn, ct->dbTableName);
@@ -1745,31 +1785,33 @@
     {
     if (doGalaxy() && !cgiOptionalString(hgtaDoGalaxyQuery))
         sendParamsToGalaxy(hgtaDoTopSubmit, "get output");
     else
         doOutChromGraphDataCt(track, table);
     }
 else
     errAbort("Don't know how to handle %s output yet", output);
 }
 
 void dispatch()
 /* Scan for 'do' variables and dispatch to appropriate page-generator.
  * By default head to the main page. */
 {
 struct hashEl *varList;
-struct sqlConnection *conn = curTrack ? hAllocConnTrack(database, curTrack) : hAllocConn(database);
+struct sqlConnection *conn = NULL;
+if (!trackHubDatabase(database))
+    conn = curTrack ? hAllocConnTrack(database, curTrack) : hAllocConn(database);
 pushWarnHandler(earlyAbortHandler);
 /* only allows view table schema function for CGB or GSID servers for the time being */
 if (hIsCgbServer() || hIsGsidServer())
     {
     if (cartVarExists(cart, hgtaDoSchema))
 	{
 	doSchema(conn);
 	}
     else
 	{
         if (cartVarExists(cart, hgtaDoValueRange))
 	    {
     	    doValueRange(cartString(cart, hgtaDoValueRange));
 	    }
 	else
@@ -1920,72 +1962,72 @@
 {
 struct hash *hash = hashNew(0);
 struct trackDb *tdb;
 for (tdb = tdbList; tdb != NULL; tdb = tdb->next)
     {
     hashAdd(hash, tdb->track, tdb);
     }
 return hash;
 }
 
 void initGroupsTracksTables()
 /* Get list of groups that actually have something in them, prepare hashes
  * containing all tracks and all tables. Set global variables that correspond
  * to the group, track, and table specified in the cart. */
 {
-struct hubConnectStatus *hubList = hubConnectStatusListFromCart(cart);
+struct hubConnectStatus *hubList = hubConnectGetHubs();
 struct grp *hubGrpList = NULL;
 fullTrackList = getFullTrackList(hubList, &hubGrpList);
 fullTrackHash = hashTrackList(fullTrackList);
 fullTableToTdbHash = hashNew(0);
 rAddTablesToHash(fullTrackList, fullTableToTdbHash);
 curTrack = findSelectedTrack(fullTrackList, NULL, hgtaTrack);
 fullGroupList = makeGroupList(fullTrackList, &hubGrpList, allowAllTables());
 curGroup = findSelectedGroup(fullGroupList, hgtaGroup);
 if (sameString(curGroup->name, "allTables"))
     curTrack = NULL;
 curTable    = findSelectedTable(curTrack, hgtaTable);
 if (curTrack == NULL)
     {
     struct trackDb *tdb  = hTrackDbForTrack(database, curTable);
     struct trackDb *cTdb = hCompositeTrackDbForSubtrack(database, tdb);
     if (cTdb)
         curTrack = cTdb;
     else
         curTrack = tdb;
     }
 }
 
 void hgTables()
 /* hgTables - Get table data associated with tracks and intersect tracks.
  * Here we set up cart and some global variables, dispatch the command,
  * and put away the cart when it is done. */
 {
 char *clade = NULL;
 
+setUdcCacheDir();
 oldVars = hashNew(10);
 
 /* Sometimes we output HTML and sometimes plain text; let each outputter
  * take care of headers instead of using a fixed cart*Shell(). */
 cart = cartAndCookieNoContent(hUserCookie(), excludeVars, oldVars);
 
 /* Set up global variables. */
 allJoiner = joinerRead("all.joiner");
 getDbGenomeClade(cart, &database, &genome, &clade, oldVars);
 freezeName = hFreezeFromDb(database);
 
-setUdcCacheDir();
 int timeout = cartUsualInt(cart, "udcTimeout", 300);
 if (udcCacheTimeout() < timeout)
     udcSetCacheTimeout(timeout);
 #if ((defined USE_BAM || defined USE_TABIX) && defined KNETFILE_HOOKS)
 knetUdcInstall();
 #endif//def (USE_BAM || USE_TABIX) && KNETFILE_HOOKS
 
 if (lookupPosition())
     {
     /* Init track and group lists and figure out what page to put up. */
     initGroupsTracksTables();
 
     if (cartUsualBoolean(cart, hgtaDoGreatOutput, FALSE))
         doGetGreatOutput(dispatch);
     else