f80d53ffd0addcdd946fe86cb8ad7bf62f8bd2f2
kate
  Fri May 30 14:09:55 2014 -0700
Add mapping of ids to names for extra fields. Reusing the extra fields code instead of adding track-specific code.  refs #13230
diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index aefd4a8..605952c 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -1488,42 +1488,69 @@
 /* if trackDb does not contain a "urls" entry for current column name, just print idList as it is.
  * Otherwise treat idList as a comma-sep list of IDs and print one row per id, with a link to url,
  * ($$ in url is OK, wildcards like $P, $p, are also OK)
  * */
 {
 // try to find a fieldName=url setting in the "urls" tdb statement, print id if not found
 char *url = NULL;
 if (fieldToUrl!=NULL)
     url = (char*)hashFindVal(fieldToUrl, col->name);
 if (url==NULL)
     {
     printf("<td>%s</td></tr>\n", idList);
     return;
     }
 
+// handle id->name mapping for multi-source items
+char **idNames = NULL;
+char *idNameTable = trackDbSetting(tdb, "sourceTable");
+if (sameString("sourceIds", col->name) && idNameTable)
+    {
+    struct sqlResult *sr;
+    char query[256];
+    char **row;
+    sqlSafef(query, sizeof(query), "select max(id) from %s", idNameTable);
+    struct sqlConnection *conn = hAllocConnTrack(database, tdb);
+    int maxId = sqlQuickNum(conn, query);
+    AllocArray(idNames, maxId+1);
+    sqlSafef(query, sizeof(query), "select id, name from %s", idNameTable);
+    sr = sqlGetResult(conn, query);
+    int id;
+    while ((row = sqlNextRow(sr)) != NULL)
+        {
+        id = sqlUnsigned(row[0]);
+        if (id > maxId)
+            errAbort("Internal error:  id %d > maxId %d in %s", id, maxId, idNameTable);
+        idNames[id] = cloneString(row[1]);
+        }
+    sqlFreeResult(&sr);
+    hFreeConn(&conn);
+    }
+
 // split the id into parts and print each part as a link
 struct slName *slIds = slNameListFromComma(idList);
 struct slName *itemId = NULL;
 printf("<td>");
 for (itemId = slIds; itemId!=NULL; itemId = itemId->next) 
     {
     if (itemId!=slIds)
         printf(", ");
     char *itemName = itemId->name;
-    itemName = trimSpaces(itemName);
-    char *idUrl = replaceInUrl(tdb, url, itemName, TRUE);
-    printf("<a href=\"%s\" target=\"_blank\">%s</a>", idUrl, itemId->name);
+    if (idNames)
+        itemName = idNames[sqlUnsigned(itemName)];
+    char *idUrl = replaceInUrl(tdb, url, trimSpaces(itemName), TRUE);
+    printf("<a href=\"%s\" target=\"_blank\">%s</a>", idUrl, itemName);
     } 
 printf("</td></tr>\n");
 freeMem(slIds);
 }
 
 int extraFieldsPrint(struct trackDb *tdb,struct sqlResult *sr,char **fields,int fieldCount)
 // Any extra bed or bigBed fields (defined in as and occurring after N in bed N + types.
 // sr may be null for bigBeds.
 // Returns number of extra fields actually printed.
 {
 struct sqlConnection *conn = NULL ;
 if (!trackHubDatabase(database))
     conn = hAllocConnTrack(database, tdb);
 struct asObject *as = asForTdb(conn, tdb);
 hFreeConn(&conn);