9614cd02adbffc856bc229ae7c88a2440cc616f1 hiram Wed Feb 6 10:26:35 2019 -0800 returning chrom list from ucsc chromInfo table refs #18869 diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c index 3c81333..c726cc7 100644 --- src/hg/hubApi/hubApi.c +++ src/hg/hubApi/hubApi.c @@ -12,30 +12,31 @@ #include "udc.h" #include "knetUdc.h" #include "genbank.h" #include "trackHub.h" #include "hgConfig.h" #include "hCommon.h" #include "hPrint.h" #include "bigWig.h" #include "hubConnect.h" #include "obscure.h" #include "errCatch.h" #include "vcf.h" #include "bedTabix.h" #include "bamFile.h" #include "jsonParse.h" +#include "chromInfo.h" #ifdef USE_HAL #include "halBlockViz.h" #endif /* +------------------+------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------------+------------------+------+-----+---------+-------+ | hubUrl | longblob | NO | PRI | NULL | | | shortLabel | varchar(255) | NO | | NULL | | | longLabel | varchar(255) | NO | | NULL | | | registrationTime | varchar(255) | NO | | NULL | | | dbCount | int(10) unsigned | NO | | NULL | | | dbList | blob | YES | | NULL | | @@ -63,48 +64,56 @@ static long totalTracks = 0; static boolean measureTiming = FALSE; /* set by CGI parameters */ static boolean allTrackSettings = FALSE; /* checkbox setting */ static char **shortLabels = NULL; /* public hub short labels in array */ struct hubPublic *publicHubList = NULL; static int publicHubCount = 0; static char *defaultHub = "Plants"; static char *defaultDb = "ce11"; static long enteredMainTime = 0; /* will become = clock1000() on entry */ /* to allow calculation of when to bail out, taking too long */ static long timeOutSeconds = 100; static boolean timedOut = FALSE; /* ######################################################################### */ -static void jsonInteger(FILE *f, char *tag, int value) +static void jsonInteger(FILE *f, char *tag, long long value) /* output one json interger: "tag":value appropriately quoted and encoded */ { -fprintf(f,"\"%s\":%d",tag, value); +fprintf(f,"\"%s\":%lld",tag, value); } static void jsonStringOut(FILE *f, char *tag, char *value) /* output one json string: "tag":"value" appropriately quoted and encoded */ { fprintf(f,"\"%s\":",tag); char *a = jsonStringEscape(value); if (isEmpty(a)) fprintf(f, "%s", "null"); else fprintf(f, "\"%s\"", a); freeMem(a); } +static void jsonStartOutput(FILE *f) +/* begin json output */ +{ +fputc('{',f); +jsonStringOut(f, "source", "UCSantaCruz"); +fputc(',',f); +} + static void hubPublicJsonOutput(struct hubPublic *el, FILE *f) /* Print out hubPublic element in JSON format. */ { fputc('{',f); jsonStringOut(f, "hubUrl", el->hubUrl); fputc(',',f); jsonStringOut(f, "shortLabel", el->shortLabel); fputc(',',f); jsonStringOut(f, "longLabel", el->longLabel); fputc(',',f); jsonStringOut(f, "registrationTime", el->registrationTime); fputc(',',f); jsonInteger(f, "dbCount", el->dbCount); fputc(',',f); jsonStringOut(f, "dbList", el->dbList); @@ -519,31 +528,32 @@ fputc(',',f); jsonInteger(f, "hgNearOk", el->hgNearOk); fputc(',',f); jsonInteger(f, "hgPbOk", el->hgPbOk); fputc(',',f); jsonStringOut(f, "sourceName", el->sourceName); fputc(',',f); jsonInteger(f, "taxId", el->taxId); fputc('}',f); } static void jsonPublicHubs() /* output the hubPublic SQL table */ { struct hubPublic *el = publicHubList; -printf("{\"source\":\"UCSantaCruz\",\"publicHubs\":["); +jsonStartOutput(stdout); +printf("\"publicHubs\":["); for ( ; el != NULL; el = el->next ) { hubPublicJsonOutput(el, stdout); if (el->next) printf(","); } printf("]}\n"); } static int dbDbCmpName(const void *va, const void *vb) /* Compare two dbDb elements: name, ignore case. */ { const struct dbDb *a = *((struct dbDb **)va); const struct dbDb *b = *((struct dbDb **)vb); return strcasecmp(a->name, b->name); @@ -562,144 +572,193 @@ { el = dbDbLoad(row); slAddHead(&dbList, el); } sqlFreeResult(&sr); hDisconnectCentral(&conn); slSort(&dbList, dbDbCmpName); return dbList; } static void jsonDbDb() /* output the dbDb SQL table */ { struct dbDb *dbList = ucscDbDb(); struct dbDb *el; -printf("{\"source\":\"UCSantaCruz\",\"ucscGenomes\":["); +jsonStartOutput(stdout); +printf("\"ucscGenomes\":["); for ( el=dbList; el != NULL; el = el->next ) { dbDbJsonOutput(el, stdout); if (el->next) printf(","); } printf("]}\n"); } +static void chromInfoJsonOutput(char *db, FILE *f, char *track) +{ +if (track) + { +; + } +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); + } + fputc('}',f); + } +} + +static void chromListJsonOutput(char *db, FILE *f) +/* return chromsome list from specified UCSC database name, + * can be for a specific track if cgiVar(track) exists, otherwise, + * the chrom list is from the chromInfo table. + */ +{ +char *track = cgiOptionalString("track"); +chromInfoJsonOutput(db, f, track); +} /* static void chromListJsonOutput(char *db, FILE *f) */ + static void trackDbJsonOutput(char *db, FILE *f) /* return track list from specified UCSC database name */ { struct trackDb *tdbList = hTrackDb(db); struct trackDb *el; -fputc('{',f); -jsonStringOut(f, "source", "UCSantaCruz"); -fputc(',',f); +jsonStartOutput(f); jsonStringOut(f, "db", db); fputc(',',f); fprintf(f, "\"tracks\":["); for (el = tdbList; el != NULL; el = el->next ) { char *a = jsonStringEscape(el->track); printf("\"%s\"", a); freeMem(a); if (el->next) fputc(',',f); } 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 */ +/* 'list' function words[1] is the subCommand */ { if (sameWord("publicHubs", words[1])) jsonPublicHubs(); else if (sameWord("ucscGenomes", words[1])) jsonDbDb(); -else if (sameWord("genomes", words[1])) +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"); struct trackHub *hub = trackHubOpen(hubUrl, ""); if (hub->genomeList) { - printf("{\"source\":\"UCSantaCruz\","); + 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"); } - if (isEmpty(hubUrl)) + 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"); } struct trackHub *hub = trackHubOpen(hubUrl, ""); if (hub->genomeList) { struct slName *dbTrackList = NULL; (void) genomeList(hub, &dbTrackList, genome); - printf("{\"source\":\"UCSantaCruz\","); + 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"); + } + if (isEmpty(hubUrl)) // missing hubUrl implies UCSC database + { + chromListJsonOutput(db, stdout); // only need db for this function + return; + } + } else - errAbort("# ERROR: do not recognize command '%s' for 'list' function\n", words[1]); + errAbort("# 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) @@ -803,33 +862,34 @@ struct trackHub *hub = trackHubOpen(urlInput, ""); if (measureTiming) { long thisTime = clock1000(); 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/genomes?hubUrl=%s'>list genomes from specified hub</a> <em>/cgi-bin/hubApi/list/genomes?hubUrl='%s'</em></li>\n", urlInput, urlInput); +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("</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;");