11c1c560b88d430fd2c6967a86d2e87109806357
max
  Fri Jan 24 09:15:03 2014 -0800
corrections after code review refs #12524. These changes probably don'tneed to reviewed anymore, as Angie has already seen them, I copied them into
the ticket #12524.

diff --git src/hg/lib/hdb.c src/hg/lib/hdb.c
index 684d772..d9d66f3 100644
--- src/hg/lib/hdb.c
+++ src/hg/lib/hdb.c
@@ -1012,44 +1012,44 @@
 static struct twoBitFile *tbf = NULL;  // cache of open file
 if ((tbf == NULL) || !sameString(fileName, tbf->fileName))
     {
     twoBitClose(&tbf);
     tbf = twoBitOpen(fileName);
     }
 struct dnaSeq *seq = twoBitReadSeqFrag(tbf, seqName, start, end);
 return seq;
 }
 
 struct dnaSeq *hFetchSeqMixed(char *fileName, char *seqName, int start, int end)
 /* Fetch mixed case sequence. */
 {
 struct dnaSeq *seq = NULL;
 char *newFileName = NULL;
-newFileName = hCloneRewriteFileName(fileName);
+newFileName = hReplaceGbdb(fileName);
 if (twoBitIsFile(newFileName))
     seq = fetchTwoBitSeq(newFileName, seqName, start, end);
 else
     seq = nibLoadPartMasked(NIB_MASK_MIXED, newFileName, start, end-start);
 freez(&newFileName);
 return seq;
 }
 
 struct dnaSeq *hFetchSeq(char *fileName, char *seqName, int start, int end)
 /* Fetch sequence from file.  If it is a .2bit file then fetch the named sequence.
    If it is .nib then just ignore seqName. */
 {
-fileName = hCloneRewriteFileName(fileName);
+fileName = hReplaceGbdb(fileName);
 struct dnaSeq *seq  = NULL;
 if (twoBitIsFile(fileName))
     {
     seq = fetchTwoBitSeq(fileName, seqName, start, end);
     tolowers(seq->dna);
     }
 else
     seq = nibLoadPart(fileName, start, end-start);
 freez(&fileName);
 return seq;
 }
 
 struct dnaSeq *hChromSeqMixed(char *db, char *chrom, int start, int end)
 /* Return mixed case (repeats in lower case) DNA from chromosome. */
 {
@@ -1253,36 +1253,39 @@
 struct sqlConnection *conn = hAllocConn(db);
 struct sqlResult *sr;
 char **row;
 
 sr = sqlGetResult(conn, "NOSQLINJ select chrom from chromInfo");
 while ((row = sqlNextRow(sr)) != NULL)
     {
     struct slName *el = slNameNew(row[0]);
     slAddHead(&list, el);
     }
 sqlFreeResult(&sr);
 hFreeConn(&conn);
 return list;
 }
 
-char *hCloneRewriteFileName(char* fileName)
- /* Clones and returns a gbdb filename, potentially rewriting it according to hg.conf
+char *hReplaceGbdb(char* fileName)
+ /* Returns a gbdb filename, potentially rewriting it according to hg.conf
   * If the settings gbdbLoc1 and gbdbLoc2 are found, try them in order, by 
   * replacing /gbdb/ with the new locations.
-  * We assume /gbdb/ does not appear somewhere inside a fileName.
+  * If after the replacement of gbdbLoc1 the resulting fileName does not exist,
+  * gbdbLoc2 is used.
   * This function does not guarantee that the filename exists.
+  * We assume /gbdb/ does not appear somewhere inside a fileName.
+  * Result has to be free'd.
  * */
 {
 if (fileName==NULL)
     return fileName;
 
 char* newGbdbLoc = cfgOption("gbdbLoc1");
 char* path;
 
 // if no config option set or not a /gbdb filename, then just return
 // otherwise replace /gbdb/ with the new prefix and return if exists.
 if (newGbdbLoc==NULL || !startsWith("/gbdb/", fileName))
    return cloneString(fileName);
 
 path = replaceChars(fileName, "/gbdb/", newGbdbLoc);
 if (fileExists(path))
@@ -1316,31 +1319,31 @@
 sqlSafef(query, sizeof(query),
 	"select path,size from %s where id = %u", extFileTable, extFileId);
 sr = sqlGetResult(conn, query);
 if ((row = sqlNextRow(sr)) == NULL)
     {
     if (abortOnError)
 	errAbort("Database inconsistency table '%s.%s' no ext file with id %u",
 		 sqlGetDatabase(conn), extFileTable, extFileId);
     else 
 	{
 	sqlFreeResult(&sr);
 	return NULL;
 	}
     }
 
-path = hCloneRewriteFileName(row[0]);
+path = hReplaceGbdb(row[0]);
 
 dbSize = sqlLongLong(row[1]);
 sqlFreeResult(&sr);
 
 // for speed, only do dbSize check if file is local
 if (udcIsLocal(path))
     {
     diskSize = fileSize(path);
     if (dbSize != diskSize)
         {
         if (abortOnError)
             errAbort("External file %s cannot be opened or has wrong size.  "
                      "Old size %lld, new size %lld, error %s",
                      path, dbSize, diskSize, strerror(errno));
         else 
@@ -2358,57 +2361,57 @@
 }
 
 char *hGenomeOrArchive(char *database)
 /* Return genome name associated from the regular or the archive database. */
 {
 char *genome = hGenome(database);
 if (!genome)
     genome = hArchiveDbDbOptionalField(database, "genome");
 return genome;
 }
 
 char *hDbDbNibPath(char *database)
 /* return nibPath from dbDb for database, has to be freed */
 {
 char *rawNibPath = hDbDbOptionalField(database, "nibPath");
-char *nibPath = hCloneRewriteFileName(rawNibPath);
+char *nibPath = hReplaceGbdb(rawNibPath);
 freez(&rawNibPath);
 return nibPath;
 }
 
 char *hGenome(char *database)
 /* Return genome associated with database.
  * use freeMem on this when done. */
 {
 return hDbDbOptionalField(database, "genome");
 }
 
 char *hScientificName(char *database)
 /* Return scientific name for organism represented by this database */
 /* Return NULL if unknown database */
 /* NOTE: must free returned string after use */
 {
 return hDbDbOptionalField(database, "scientificName");
 }
 
 char *hHtmlPath(char *database)
 /* Return /gbdb path name to html description for this database */
 /* Return NULL if unknown database */
 /* NOTE: must free returned string after use */
 {
 char *htmlPath = hDbDbOptionalField(database, "htmlPath");
-char *newPath = hCloneRewriteFileName(htmlPath);
+char *newPath = hReplaceGbdb(htmlPath);
 freez(&htmlPath);
 return newPath;
 }
 
 char *hFreezeDate(char *database)
 /* Return freeze date of database. Use freeMem when done. */
 {
 return hDbDbField(database, "description");
 }
 
 char *hFreezeDateOpt(char *database)
 /* Return freeze date of database or NULL if unknown database
  *  Use freeMem when done. */
 {
 return hDbDbOptionalField(database, "description");
@@ -2788,32 +2791,32 @@
 retScore[0] = 0;
 retStrand[0] = 0;
 retCdsStart[0] = 0;
 retCdsEnd[0] = 0;
 retCount[0] = 0;
 retStarts[0] = 0;
 retEndsSizes[0] = 0;
 retSpan[0] = 0;
 
 char *db;
 db = sqlGetDatabase(conn);
 
 /* Read table description into hash. */
 boolean gotIt = TRUE, binned = FALSE;
 binned = hIsBinned(db, table);
-// XX Do I need to free the slList implicitly created here?
-struct hash *hash = hashFromSlNameList(sqlListFields(conn, table));
+struct slName *tableList = sqlListFields(conn, table);
+struct hash *hash = hashSetFromSlNameList(tableList);
 
 /* Look for bed-style or linkedFeatures names. */
 if (fitFields(hash, "chrom", "chromStart", "chromEnd", retChrom, retStart, retEnd))
     {
     if (!fitField(hash, "name", retName))
 	if (!fitField(hash, "acc", retName))
 	    if (!fitField(hash, "frag", retName))
 		if (!fitField(hash, "contig", retName))
 		    fitField(hash, "sequence", retName); // so that tagAlign can masquerade as BED
     fitField(hash, "score", retScore);
     fitField(hash, "strand", retStrand);
     fitField(hash, "thickStart", retCdsStart);
     fitField(hash, "thickEnd", retCdsEnd);
     if (!fitField(hash, "blockCount", retCount))
 	fitField(hash, "lfCount", retCount);
@@ -2870,31 +2873,34 @@
     strcpy(retStart, "start");
     strcpy(retEnd, "end");
     fitField(hash, "frag", retName);
     fitField(hash, "strand", retStrand);
     }
 else
     {
     if (hashLookup(hash, "acc"))
          strcpy(retName, "acc");
     else if (hashLookup(hash, "id"))
          strcpy(retName, "id");
     else if (hashLookup(hash, "name"))
          strcpy(retName, "name");
     gotIt = FALSE;
     }
+
+slFreeList(&tableList);
 freeHash(&hash);
+
 *retBinned = binned;
 return gotIt;
 }
 
 boolean hFindFieldsAndBinWithConn(struct sqlConnection *conn, char *db, char *table,
 	char retChrom[HDB_MAX_FIELD_STRING],
 	char retStart[HDB_MAX_FIELD_STRING], char retEnd[HDB_MAX_FIELD_STRING],
 	boolean *retBinned)
 /* Given a table return the fields for selecting chromosome, start, end,
  * and whether it's binned . */
 {
 char retName[HDB_MAX_FIELD_STRING];
 char retScore[HDB_MAX_FIELD_STRING];
 char retStrand[HDB_MAX_FIELD_STRING];
 char retCdsStart[HDB_MAX_FIELD_STRING];
@@ -5225,36 +5231,36 @@
     {
     if (checkSeqName)
 	{
 	if (startsWith("chr", seqName))
 	    sqlSafef(query, sizeof(query), "select fileName from %s where seqName = '%s'",
 		  table, seqName+strlen("chr"));
 	else
 	    sqlSafef(query, sizeof(query), "select fileName from %s where seqName = 'chr%s'",
 		  table, seqName);
 	fileName = sqlQuickString(conn, query);
 	}
     else
 	errAbort("Missing fileName in %s table", table);
     }
 
-char *rewrittenFname = hCloneRewriteFileName(fileName);
+char *rewrittenFname = hReplaceGbdb(fileName);
 freez(&fileName);
 return rewrittenFname;
 }
 
 char *bbiNameFromSettingOrTableChrom(struct trackDb *tdb, struct sqlConnection *conn, char *table,
 				     char *seqName)
 /* Return file name from bigDataUrl or little table that might have a seqName column.
  * If table does have a seqName column, return NULL if there is no file for seqName. */
 {
-char *fileName = hCloneRewriteFileName(trackDbSetting(tdb, "bigDataUrl"));
+char *fileName = hReplaceGbdb(trackDbSetting(tdb, "bigDataUrl"));
 if (fileName == NULL)
     fileName = bbiNameFromTableChrom(conn, table, seqName);
 return fileName;
 }
 
 char *bbiNameFromSettingOrTable(struct trackDb *tdb, struct sqlConnection *conn, char *table)
 /* Return file name from bigDataUrl or little table. */
 {
 return bbiNameFromSettingOrTableChrom(tdb, conn, table, NULL);
 }