280cbbaf8ebd0fed85ffad886b8aa14de03341ea
max
  Mon Jan 20 04:49:57 2014 -0800
Changing handling of sqlConnect to allow a db that exists onlyon the failover server, not on the main one.

diff --git src/hg/lib/jksql.c src/hg/lib/jksql.c
index c3fd729..d3d1fb1 100644
--- src/hg/lib/jksql.c
+++ src/hg/lib/jksql.c
@@ -271,30 +271,41 @@
  *     - if there is no profile named the same as the database, use
  *       the default profile of "db"
  * return NULL if not found.
  */
 {
 //assert((profileName != NULL) || (database != NULL));
 if (profiles == NULL)
     sqlProfileLoad();
 
 if (profileName != NULL)
     return sqlProfileFindByName(profileName, database);
 else
     return sqlProfileFindByDatabase(database);
 }
 
+static struct sqlProfile* sqlProfileGetFailover(struct sqlProfile* sp, char *database)
+/* try to find a failover slow-x profile for a profile x */
+{
+if (sp==NULL || sp->name==NULL)
+    return NULL;
+char *slowProfName = catTwoStrings("slow-", sp->name);
+struct sqlProfile *slow = sqlProfileGet(slowProfName, database);
+freez(&slowProfName);
+return slow;
+}
+
 static struct sqlProfile* sqlProfileMustGet(char *profileName, char *database)
 /* lookup a profile using the profile resolution algorithm or die trying */
 {
 struct sqlProfile* sp = sqlProfileGet(profileName, database);
 if (sp == NULL)
     {
     if (profileName == NULL)
         errAbort("can't find database %s in hg.conf, should have a default named \"db\"",
                  database);
     else if (database == NULL)
         errAbort("can't find profile %s in hg.conf", profileName);
     else
         errAbort("can't find profile %s for database %s in hg.conf", profileName, database);
     }
 return sp;
@@ -926,46 +937,58 @@
 return sqlConnRemote(host, 0, NULL, user, password, database, TRUE);
 }
 
 struct sqlConnection *sqlMayConnectRemote(char *host, char *user, char *password,
                                           char *database)
 /* Connect to database somewhere as somebody. Database maybe NULL to
  * just connect to the server.  Return NULL can't connect */
 {
 return sqlConnRemote(host, 0, NULL, user, password, database, FALSE);
 }
 
 static struct sqlConnection *sqlConnProfile(struct sqlProfile* sp, char *database, boolean abort)
 /* Connect to database using the profile.  Database maybe NULL to connect to
  * the server. Optionally abort on failure. */
 {
+bool mainAbort = abort;
 struct sqlConnection *sc;
 
-// connect with the default profile
-sc = sqlConnRemote(sp->host, sp->port, sp->socket, sp->user, sp->password, database, abort);
-if (sc!=NULL)
-    sc->profile = sp; // remember the profile
+// get the slow-db profile for the profile, if it exists
+struct sqlProfile *slow = sqlProfileGetFailover(sp, database);
+// if we have a failover profile, don't abort right away
+if (slow!=NULL)
+    mainAbort = FALSE;
 
-// optionally prepare the slower failover connection
-if (sp->name==NULL)
+// connect with the default profile
+sc = sqlConnRemote(sp->host, sp->port, sp->socket, sp->user, sp->password, database, mainAbort);
+if (slow==NULL)
+    // the default case: just return sc, can be NULL
     return sc;
-char *slowProfName = catTwoStrings("slow-", sp->name);
-struct sqlProfile *slow = sqlProfileGet(slowProfName, database);
-freez(&slowProfName);
 
-if (slow==NULL)
+// we still have a failover profile to setup
+if (sc==NULL)
+    {
+    // We have a failover connection configured, but no main connection.
+    // This can happen if the requested database exists only on the failover connection
+    // We only create a failover connection in this case and return it as the main one
+    sc = sqlConnRemote(slow->host, slow->port, slow->socket, slow->user, slow->password, database, abort);
+    if (monitorFlags & JKSQL_TRACE)
+        fprintf(stderr, "SQL_FAILOVER_AT_CONNECT");
     return sc;
+    }
+
+sc->profile = sp; // remember the profile
 
 // don't connect the slow connection yet: lazily connect later when needed; saves 0.5
 // seconds per connection on transatlantic links
 // instead create a "placeholder" sqlConnection with all connection data, but no connection
 struct sqlConnection *slowSc;
 AllocVar(slowSc);
 slowSc->profile = slow; // remember the profile
 slowSc->db = database;
 slowSc->hasTableCache = -1;
 sc->slowConn = slowSc;
 return sc;
 }
 
 struct sqlConnection *sqlMayConnect(char *database)
 /* Connect to database on default host as default user.