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("<p>Tracks in UCSC genome: '%s'<br>\n", ucscDb); struct trackDb *tdbList = hTrackDb(ucscDb); struct trackDb *track; hPrintf("<ul>\n"); for (track = tdbList; track != NULL; track = track->next ) { @@ -866,30 +912,31 @@ hPrintf("<em>hub open time: %ld millis</em><br>\n", thisTime - lastTime); } hPrintf("<h3>ucscDb: '%s'</h2>\n", ucscDb); struct trackHubGenome *hubGenome = hub->genomeList; hPrintf("<h2>Example URLs to return json data structures:</h2>\n"); hPrintf("<ul>\n"); hPrintf("<li><a href='/cgi-bin/hubApi/list/publicHubs'>list public hubs</a> <em>/cgi-bin/hubApi/list/publicHubs</em></li>\n"); hPrintf("<li><a href='/cgi-bin/hubApi/list/ucscGenomes'>list database genomes</a> <em>/cgi-bin/hubApi/list/ucscGenomes</em></li>\n"); hPrintf("<li><a href='/cgi-bin/hubApi/list/hubGenomes?hubUrl=%s'>list genomes from specified hub</a> <em>/cgi-bin/hubApi/list/hubGenomes?hubUrl='%s'</em></li>\n", urlInput, urlInput); hPrintf("<li><a href='/cgi-bin/hubApi/list/tracks?hubUrl=%s&genome=%s'>list tracks from specified hub and genome</a> <em>/cgi-bin/hubApi/list/tracks?hubUrl='%s&genome=%s'</em></li>\n", urlInput, hubGenome->name, urlInput, hubGenome->name); hPrintf("<li><a href='/cgi-bin/hubApi/list/tracks?db=%s'>list tracks from specified UCSC database</a> <em>/cgi-bin/hubApi/list/tracks?db='%s'</em></li>\n", ucscDb, ucscDb); hPrintf("<li><a href='/cgi-bin/hubApi/list/chromosomes?db=%s'>list chromosomes from specified UCSC database</a> <em>/cgi-bin/hubApi/list/chromosomes?db='%s'</em></li>\n", ucscDb, ucscDb); +hPrintf("<li><a href='/cgi-bin/hubApi/list/chromosomes?db=%s&track=gap'>list chromosomes from specified track from UCSC databaset</a> <em>/cgi-bin/hubApi/list/chromosomes?db='%s'&track=gap</em></li>\n", ucscDb, ucscDb); hPrintf("</ul>\n"); hPrintf("<h4>cart dump</h4>"); hPrintf("<pre>\n"); cartDump(cart); hPrintf("</pre>\n"); hPrintf("<form action='%s' name='hubApiUrl' id='hubApiUrl' method='GET'>\n\n", "../cgi-bin/hubApi"); hPrintf("<b>Select public hub: </b>"); #define JBUFSIZE 2048 #define SMALLBUF 256 char javascript[JBUFSIZE]; struct slPair *events = NULL; safef(javascript, sizeof(javascript), "this.lastIndex=this.selectedIndex;");