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("<BR>"); } } } } -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("<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) - { +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("<td>%s</td></tr>\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("<td>"); 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("<a href=\"%s\" target=\"_blank\">%s</a>", idUrl, itemName); } printf("</td></tr>\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;