ebd00966c64d172c0013f67c5a603e2077d84c3c
kate
Fri May 30 14:35:36 2014 -0700
Cleanup to isolate id/name mapping code. refs #13230
diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index 605952c..d0f911b 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -1472,88 +1472,105 @@
char dbOnly[4096];
diff = comp2->start - (comp1->start + comp1->size);
safef(dbOnly, sizeof(dbOnly), "%s", comp1->src);
chopPrefix(dbOnly);
printf("%-20s %d\n",hOrganism(dbOnly), diff);
}
printf("
");
}
}
}
}
-void printIdOrLinks(struct asColumn *col, struct hash *fieldToUrl, struct trackDb *tdb, char *idList)
-/* 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)
+char **getIdNameMap(struct trackDb *tdb, struct asColumn *col, int *size)
+/* Allocate and fill an array mapping id to name. Currently limited to specific columns. */
{
- printf("
%s | \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)
- {
+if (!idNameTable || differentString("sourceIds", col->name))
+ return NULL;
+
struct sqlResult *sr;
char query[256];
char **row;
+char **idNames;
+
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);
+if (size)
+ *size = maxId+1;
+return idNames;
+}
+
+void printIdOrLinks(struct asColumn *col, struct hash *fieldToUrl, struct trackDb *tdb, char *idList)
+/* 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("%s | \n", idList);
+ return;
}
// split the id into parts and print each part as a link
struct slName *slIds = slNameListFromComma(idList);
struct slName *itemId = NULL;
+
+// handle id->name mapping for multi-source items
+int nameCount;
+char **idNames = getIdNameMap(tdb, col, &nameCount);
+
printf("");
for (itemId = slIds; itemId!=NULL; itemId = itemId->next)
{
if (itemId != slIds)
printf(", ");
char *itemName = itemId->name;
if (idNames)
+ {
+ unsigned int id = sqlUnsigned(itemName);
+ if (id < nameCount)
itemName = idNames[sqlUnsigned(itemName)];
+ }
char *idUrl = replaceInUrl(tdb, url, trimSpaces(itemName), TRUE);
printf("%s", idUrl, itemName);
}
printf(" | \n");
freeMem(slIds);
+//freeMem(idNames);
}
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);
if (as == NULL)
return 0;