225c0d55992aefae478461bba278644bdfdda3c5
max
  Wed Jan 15 08:33:57 2014 -0800
library changes for the browser box: This changes mostly hdb and jksql,plus - to a smaller extent - various other places in the code that deal
with /gbdb/ files.  The overall aim is to make it possible to have the
data remote at UCSC while having the CGIs on a machine far away. At up to
180msecs distance from UCSC (Europe,Japan), each query can get slow. So
I tried to reduce the number of queries sent to UCSC while allowing to
keep some mysql tables on localhost.

I changed four things:
- extend larry's table cache to include field names. The code uses
"describe" very often, which is slow from remote. With a table name
cache these queries can be handled locally. This is configured in
hg.conf
- mysql "failover" connections: a mysql connection can have a 2nd
connection that is used if a query fails, configured in hg.conf
(I didn't call it "remote" connections, because we use that term already
in the code)
- mysql lazy connects: don't connect a sqlConnection right away, but
only when needed. a mysql connect takes >500msecs from across the
atlantic.
- move gbdb: patch various places that use absolute "/gbdb/" pathnames
to go through a central function that can change the filename of
gbdb files to something else, as configured in hg.conf

Plus patch 1 or 2 lines for more speed + update the hgMirror script

diff --git src/lib/common.c src/lib/common.c
index 6e478c6..58d22a6 100644
--- src/lib/common.c
+++ src/lib/common.c
@@ -2417,31 +2417,31 @@
     return stdin;
 if (sameString(fileName, "stdout"))
     return stdout;
 if ((f = fopen(fileName, mode)) == NULL)
     {
     char *modeName = "";
     if (mode)
         {
         if (mode[0] == 'r')
             modeName = " to read";
         else if (mode[0] == 'w')
             modeName = " to write";
         else if (mode[0] == 'a')
             modeName = " to append";
         }
-    errAbort("Can't open %s%s: %s", fileName, modeName, strerror(errno));
+    errAbort("mustOpen: Can't open %s%s: %s", fileName, modeName, strerror(errno));
     }
 return f;
 }
 
 void mustWrite(FILE *file, void *buf, size_t size)
 /* Write to a file or squawk and die. */
 {
 if (size != 0 && fwrite(buf, size, 1, file) != 1)
     {
     errAbort("Error writing %lld bytes: %s\n", (long long)size, strerror(ferror(file)));
     }
 }
 
 
 void mustRead(FILE *file, void *buf, size_t size)
@@ -2566,31 +2566,31 @@
 int mode = 00664;
 int fd = open(fileName, flags, mode);
 if (fd < 0)
     {
     char *modeName = "";
     if ((flags & (O_WRONLY | O_CREAT | O_TRUNC)) == (O_WRONLY | O_CREAT | O_TRUNC))
 	modeName = " to create and truncate";
     else if ((flags & (O_WRONLY | O_CREAT)) == (O_WRONLY | O_CREAT))
 	modeName = " to create";
     else if ((flags & O_WRONLY) == O_WRONLY)
 	modeName = " to write";
     else if ((flags & O_RDWR) == O_RDWR)
 	modeName = " to append";
     else
 	modeName = " to read";
-    errnoAbort("Can't open %s%s", fileName, modeName);
+    errnoAbort("mustOpenFd: Can't open %s%s", fileName, modeName);
     }
 return fd;
 }
 
 void mustReadFd(int fd, void *buf, size_t size)
 /* Read size bytes from a file or squawk and die. */
 {
 ssize_t actualSize;
 char *cbuf = buf;
 // using a loop because linux was not returning all data in a single request when request size exceeded 2GB.
 while (size > 0)
     {
     actualSize = read(fd, cbuf, size);
     if (actualSize < 0)
 	errnoAbort("Error reading %lld bytes", (long long)size);