06767e4dcd73d74ff5935fbc141ab44689a03ca3
markd
  Wed Apr 6 23:35:26 2011 -0700
Fix case where databases are split between two servers with a trackDb specifcationpointing to both servers, e.g.:
db.trackDb=localDb:trackDb_markd,db:trackDb

If a given genome databases existed on only one of the servers, then it would
cause an error when checking for a trackDb in that server.  This change
checks for the existance of the database as well as the table.

diff --git src/hg/lib/hdb.c src/hg/lib/hdb.c
index fa69cf0..b05b473 100644
--- src/hg/lib/hdb.c
+++ src/hg/lib/hdb.c
@@ -495,64 +495,92 @@
 {
 if (hdbCc == NULL)
     hdbCc = sqlConnCacheNew();
 return sqlConnCacheMayAlloc(hdbCc, db);
 }
 
 struct sqlConnection *hAllocConnProfile(char *profileName, char *db)
 /* Get free connection, specifying a profile and/or a database. If none
  * is available, allocate a new one. */
 {
 if (hdbCc == NULL)
     hdbCc = sqlConnCacheNew();
 return sqlConnCacheProfileAlloc(hdbCc, profileName, db);
 }
 
+struct sqlConnection *hAllocConnProfileMaybe(char *profileName, char *db)
+/* Get free connection, specifying a profile and/or a database. If none is
+ * available, allocate a new one.  Return NULL if database doesn't exist. */
+{
+if (hdbCc == NULL)
+    hdbCc = sqlConnCacheNew();
+return sqlConnCacheProfileAllocMaybe(hdbCc, profileName, db);
+}
+
 char *getTrackProfileName(struct trackDb *tdb)
 /* get profile is associated with a track, return it, otherwise NULL */
 {
 // FIXME: locicalDb is an old name used by the cancer browser
 char *p =  trackDbSetting(tdb, "dbProfile");
 if (p == NULL)
     p = trackDbSetting(tdb, "logicalDb");
 return p;
 }
 
 struct sqlConnection *hAllocConnTrack(char *db, struct trackDb *tdb)
 /* Get free connection for accessing tables associated with the specified
  * track and database. If none is available, allocate a new one. */
 {
 return hAllocConnProfile(getTrackProfileName(tdb), db);
 }
 
-struct sqlConnection *hAllocConnProfileTbl(char *db, char *spec, char **tableRet)
+static struct sqlConnection *hAllocConnProfileTblInternal(char *db, char *spec, char **tableRet, bool abortOnError)
 /* Allocate a connection to db, spec can either be in the form `table' or
  * `profile:table'.  If it contains profile, connect via that profile.  Also
  * returns pointer to table in spec string. */
 {
 char buf[512], *profile = NULL;
 char *sep = strchr(spec, ':');
 if (sep != NULL)
     {
     *tableRet = sep+1;
     safecpy(buf, sizeof(buf), spec);
     buf[(sep-spec)] = '\0';
     profile = buf;
     }
 else
     *tableRet = spec;
+if (abortOnError)
 return hAllocConnProfile(profile, db);
+else
+    return hAllocConnProfileMaybe(profile, db);
+}
+
+struct sqlConnection *hAllocConnProfileTbl(char *db, char *spec, char **tableRet)
+/* Allocate a connection to db, spec can either be in the form `table' or
+ * `profile:table'.  If it contains profile, connect via that profile.  Also
+ * returns pointer to table in spec string. */
+{
+return hAllocConnProfileTblInternal(db, spec, tableRet, TRUE);
+}
+
+struct sqlConnection *hAllocConnProfileTblMaybe(char *db, char *spec, char **tableRet)
+/* Allocate a connection to db, spec can either be in the form `table' or
+ * `profile:table'.  If it contains profile, connect via that profile.  Also
+ * returns pointer to table in spec string. Return NULL if database doesn't exist */
+{
+return hAllocConnProfileTblInternal(db, spec, tableRet, FALSE);
 }
 
 struct sqlConnection *hAllocConnDbTbl(char *spec, char **tableRet, char *defaultDb)
 /* Allocate a connection to db and table, spec is in form `db.table'; if
  * defaultDb is not NULL, 'table' can also be used.  Also returns pointer to
  * table in spec string. */
 {
 char buf[512], *db = NULL;;
 char *sep = strchr(spec, '.');
 if (sep == NULL)
     {
     if (defaultDb == NULL)
         errAbort("no defaultDb, expected db.table, got %s", spec);
     db = defaultDb;
     *tableRet = spec;
@@ -3349,32 +3377,34 @@
 /* Return TRUE if track exists on this chromosome. */
 {
 boolean chromOk = TRUE;
 if (tdb->restrictCount > 0 && chrom != NULL)
     chromOk =  (stringArrayIx(chrom, tdb->restrictList, tdb->restrictCount)) >= 0;
 return chromOk;
 }
 
 static boolean loadOneTrackDb(char *db, char *where, char *tblSpec,
                               struct trackDb **tdbList, struct hash *loaded)
 /* Load a trackDb table, including handling profiles:tbl. Returns
  * TRUE if table exists */
 {
 char *tbl;
 boolean exists;
-struct sqlConnection *conn = hAllocConnProfileTbl(db, tblSpec, &tbl);
-if ((exists = sqlTableExists(conn, tbl)))
+// when using dbProfiles and a list of trackDb entries, it's possible that the
+// database doesn't exist in one of servers.
+struct sqlConnection *conn = hAllocConnProfileTblMaybe(db, tblSpec, &tbl);
+if ((exists = ((conn != NULL) && sqlTableExists(conn, tbl))))
     {
     struct trackDb *oneTable = trackDbLoadWhere(conn, tbl, where), *oneRow;
     while ((oneRow = slPopHead(&oneTable)) != NULL)
         {
         if (!hashLookup(loaded, oneRow->track))
             {
             hashAdd(loaded, oneRow->track, NULL);
             slAddHead(tdbList, oneRow);
             // record for use in check available tracks
             char *profileName = getTrackProfileName(oneRow);
             if (profileName != NULL)
                 tableListProcessTblProfile(profileName, db);
 	    }
         else
 	    {