e06aca36b8d5f820603188308c7bec8749427fe0 hiram Wed Feb 6 14:32:14 2019 -0800 chrom list from specific track on ucsc database output and jsonErr output refs #18869 diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c index c726cc7..40f8e25 100644 --- src/hg/hubApi/hubApi.c +++ src/hg/hubApi/hubApi.c @@ -583,35 +583,85 @@ /* output the dbDb SQL table */ { struct dbDb *dbList = ucscDbDb(); struct dbDb *el; jsonStartOutput(stdout); printf("\"ucscGenomes\":["); for ( el=dbList; el != NULL; el = el->next ) { dbDbJsonOutput(el, stdout); if (el->next) printf(","); } printf("]}\n"); } +static void jsonErrAbort(char *format, ...) +/* Issue an error message in json format. */ +{ +char errMsg[2048]; +va_list args; +va_start(args, format); +vsnprintf(errMsg, sizeof(errMsg), format, args); +fputc('{',stdout); +jsonStringOut(stdout, "error", errMsg); +fputc('}',stdout); +} + static void chromInfoJsonOutput(char *db, FILE *f, char *track) { if (track) { -; + struct sqlConnection *conn = hAllocConn(db); + if (! sqlTableExists(conn, track)) + jsonErrAbort("ERROR: endpoint: /list/chromosomes?db=%&table=%s ERROR table does not exist", db, track); + if (sqlColumnExists(conn, track, "chrom")) + { + jsonStartOutput(f); + jsonStringOut(f, "genome", db); + fputc(',',f); + jsonStringOut(f, "track", track); + fputc(',',f); + struct slPair *list = NULL; + char query[2048]; + sqlSafef(query, sizeof(query), "select distinct chrom from %s", track); + struct sqlResult *sr = sqlGetResult(conn, query); + char **row; + while ((row = sqlNextRow(sr)) != NULL) + { + int size = hChromSize(db, row[0]); + slAddHead(&list, slPairNew(row[0], intToPt(size))); + } + sqlFreeResult(&sr); + slPairIntSort(&list); + slReverse(&list); + jsonInteger(f, "chromCount", slCount(list)); + fputc(',',f); + struct slPair *el = list; + for ( ; el != NULL; el = el->next ) + { + jsonInteger(f, el->name, ptToInt(el->val)); + if (el->next) + fputc(',',f); + } + fputc('}',f); + } + else + { + jsonErrAbort("ERROR: table '%s' is not a position table, no chromosomes for genome: '%s'", track, db); + } + hFreeConn(&conn); } else { struct chromInfo *ciList = createChromInfoList(NULL, db); struct chromInfo *el = ciList; jsonStartOutput(f); jsonStringOut(f, "genome", db); fputc(',',f); jsonInteger(f, "chromCount", slCount(ciList)); fputc(',',f); for ( ; el != NULL; el = el->next ) { jsonInteger(f, el->chrom, el->size); if (el->next) fputc(',',f); @@ -650,143 +700,139 @@ fprintf(f, "]}\n"); } /* static void trackDbJsonOutput(char *db, FILE *f) */ #define MAX_PATH_INFO 32 static void apiList(char *words[MAX_PATH_INFO]) /* 'list' function words[1] is the subCommand */ { if (sameWord("publicHubs", words[1])) jsonPublicHubs(); else if (sameWord("ucscGenomes", words[1])) jsonDbDb(); else if (sameWord("hubGenomes", words[1])) { char *hubUrl = cgiOptionalString("hubUrl"); if (isEmpty(hubUrl)) - errAbort("# must supply hubUrl='http:...' some URL to a hub for /list/genomes\n"); + jsonErrAbort("ERROR: must supply hubUrl='http:...' some URL to a hub for /list/genomes\n"); struct trackHub *hub = trackHubOpen(hubUrl, ""); if (hub->genomeList) { jsonStartOutput(stdout); jsonStringOut(stdout, "hubUrl", hubUrl); fputc(',',stdout); printf("\"genomes\":["); struct slName *theList = genomeList(hub, NULL, NULL); slNameSort(&theList); struct slName *el = theList; for ( ; el ; el = el->next ) { char *a = jsonStringEscape(el->name); printf("\"%s\"", a); freeMem(a); if (el->next) fputc(',',stdout); } printf("]}\n"); } } else if (sameWord("tracks", words[1])) { char *hubUrl = cgiOptionalString("hubUrl"); char *genome = cgiOptionalString("genome"); char *db = cgiOptionalString("db"); if (isEmpty(hubUrl) && isEmpty(db)) - { - errAbort("# ERROR: must supply hubUrl or db name to return track list"); - } + jsonErrAbort("ERROR: must supply hubUrl or db name to return track list"); if (isEmpty(hubUrl)) // missing hubUrl implies UCSC database { trackDbJsonOutput(db, stdout); // only need db for this function return; } if (isEmpty(genome) || isEmpty(hubUrl)) { if (isEmpty(genome)) warn("# must supply genome='someName' the name of a genome in a hub for /list/tracks\n"); if (isEmpty(hubUrl)) - warn("# must supply hubUrl='http:...' some URL to a hub for /list/genomes\n"); - errAbort("# ERROR exit"); + jsonErrAbort("ERROR: must supply hubUrl='http:...' some URL to a hub for /list/genomes\n"); } struct trackHub *hub = trackHubOpen(hubUrl, ""); if (hub->genomeList) { struct slName *dbTrackList = NULL; (void) genomeList(hub, &dbTrackList, genome); jsonStartOutput(stdout); jsonStringOut(stdout, "hubUrl", hubUrl); fputc(',',stdout); jsonStringOut(stdout, "genome", genome); fputc(',',stdout); slNameSort(&dbTrackList); struct slName *el = dbTrackList; for ( ; el != NULL; el = el->next ) { char *a = jsonStringEscape(el->name); printf("\"%s\"", a); freeMem(a); if (el->next) fputc(',',stdout); } printf("]}\n"); } } else if (sameWord("chromosomes", words[1])) { char *hubUrl = cgiOptionalString("hubUrl"); // char *genome = cgiOptionalString("genome"); char *db = cgiOptionalString("db"); if (isEmpty(hubUrl) && isEmpty(db)) - { - errAbort("# ERROR: must supply hubUrl or db name to return chromosome list"); - } + jsonErrAbort("ERROR: must supply hubUrl or db name to return chromosome list"); + if (isEmpty(hubUrl)) // missing hubUrl implies UCSC database { chromListJsonOutput(db, stdout); // only need db for this function return; } } else - errAbort("# ERROR: do not recognize endpoint '/list/%s' function\n", words[1]); + jsonErrAbort("ERROR: do not recognize endpoint '/list/%s' function\n", words[1]); } static struct hash *apiFunctionHash = NULL; static void setupFunctionHash() /* initialize the apiFunctionHash */ { if (apiFunctionHash) return; apiFunctionHash = hashNew(0); hashAdd(apiFunctionHash, "list", &apiList); } static void apiFunctionSwitch(char *pathInfo) /* given a pathInfo string: /command/subCommand/etc... * parse that and decide on which function to acll */ { hPrintDisable(); /* turn off all normal HTML output, doing JSON output */ /* the leading slash has been removed from the pathInfo, therefore, the * chop will have the first word in words[0] */ char *words[MAX_PATH_INFO];/*expect no more than MAX_PATH_INFO number of words*/ int wordCount = chopByChar(pathInfo, '/', words, ArraySize(words)); if (wordCount < 2) - errAbort("ERROR: no commands found in path info\n"); + jsonErrAbort("ERROR: no endpoint commands found ?\n"); void (*apiFunction)(char **) = hashMustFindVal(apiFunctionHash, words[0]); (*apiFunction)(words); } /* static void apiFunctionSwitch(char *pathInfo) */ static void tracksForUcscDb(char * ucscDb) { hPrintf("
Tracks in UCSC genome: '%s'
\n", ucscDb);
struct trackDb *tdbList = hTrackDb(ucscDb);
struct trackDb *track;
hPrintf("
\n"); cartDump(cart); hPrintf("\n"); hPrintf("