002a02e0a481cb3f1f06c7f848adfdc7940844cf
hiram
  Tue Feb 5 11:24:36 2019 -0800
return dbDb contents /list/ucscGenomes function refs #18869

diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c
index 9ae29b3..c74b89a 100644
--- src/hg/hubApi/hubApi.c
+++ src/hg/hubApi/hubApi.c
@@ -52,32 +52,32 @@
     char *longLabel;	/* Hub long label. */
     char *registrationTime;	/* Time first registered */
     unsigned dbCount;	/* Number of databases hub has data for. */
     char *dbList;	/* Comma separated list of databases. */
     char *descriptionUrl;	/* URL to description HTML */
     };
 
 /* Global Variables */
 static struct cart *cart;             /* CGI and other variables */
 static struct hash *oldVars = NULL;
 static struct hash *trackCounter = NULL;
 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 struct hubPublic *publicHubList = NULL;
 static char *defaultHub = "Plants";
 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)
 /* output one json interger: "tag":value appropriately quoted and encoded */
 {
 fprintf(f,"\"%s\":%d",tag, value);
 }
 
 static void jsonStringOut(FILE *f, char *tag, char *value)
@@ -136,36 +136,35 @@
 ret->hubUrl = cloneString(row[0]);
 ret->shortLabel = cloneString(row[1]);
 ret->longLabel = cloneString(row[2]);
 ret->registrationTime = cloneString(row[3]);
 ret->dbCount = sqlUnsigned(row[4]);
 ret->dbList = cloneString(row[5]);
 // if (row[6])
     ret->descriptionUrl = cloneString(row[6]);
 // else
 //     ret->descriptionUrl = cloneString("");
 return ret;
 }
 
 static struct hubPublic *hubPublicLoadAll()
 {
+char query[1024];
 struct hubPublic *list = NULL;
 struct sqlConnection *conn = hConnectCentral();
-// Build a query to find all public hub URL's
-struct dyString *query = sqlDyStringCreate("select * from %s",
-                                           hubPublicTableName());
-struct sqlResult *sr = sqlGetResult(conn, query->string);
+sqlSafef(query, sizeof(query), "select * from %s", hubPublicTableName());
+struct sqlResult *sr = sqlGetResult(conn, query);
 char **row;
 while ((row = sqlNextRow(sr)) != NULL)
     {
     struct hubPublic *el = hubPublicLoad(row);
     slAddHead(&list, el);
     }
 sqlFreeResult(&sr);
 hDisconnectCentral(&conn);
 publicHubSortCase(&list);
 int listSize = slCount(list);
 AllocArray(shortLabels, listSize);
 struct hubPublic *el = list;
 int i = 0;
 for ( ; el != NULL; el = el->next )
     {
@@ -481,59 +480,131 @@
 
 static char *urlFromShortLabel(char *shortLabel)
 {
 char hubUrl[1024];
 char query[1024];
 struct sqlConnection *conn = hConnectCentral();
 // Build a query to select the hubUrl for the given shortLabel
 sqlSafef(query, sizeof(query), "select hubUrl from %s where shortLabel='%s'",
       hubPublicTableName(), shortLabel);
 if (! sqlQuickQuery(conn, query, hubUrl, sizeof(hubUrl)))
     hubUrl[0] = 0;
 hDisconnectCentral(&conn);
 return cloneString(hubUrl);
 }
 
+static void dbDbJsonOutput(struct dbDb *el, FILE *f) 
+/* Print out hubPublic element in JSON format. */
+{
+fputc('{',f);
+jsonStringOut(f, "name", el->name);
+fputc(',',f);
+jsonStringOut(f, "description", el->description);
+fputc(',',f);
+jsonStringOut(f, "nibPath", el->nibPath);
+fputc(',',f);
+jsonStringOut(f, "organism", el->organism);
+fputc(',',f);
+jsonStringOut(f, "defaultPos", el->defaultPos);
+fputc(',',f);
+jsonInteger(f, "active", el->active);
+fputc(',',f);
+jsonInteger(f, "orderKey", el->orderKey);
+fputc(',',f);
+jsonStringOut(f, "genome", el->genome);
+fputc(',',f);
+jsonStringOut(f, "scientificName", el->scientificName);
+fputc(',',f);
+jsonStringOut(f, "htmlPath", el->htmlPath);
+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("{\"publicHubs\":[");
+printf("{\"source\":\"UCSantaCruz\",\"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);
+}
+
+static void jsonDbDb()
+/* output the dbDb SQL table */
+{
+char query[1024];
+struct sqlConnection *conn = hConnectCentral();
+sqlSafef(query, sizeof(query), "select * from dbDb");
+struct dbDb *dbList = NULL, *el = NULL;
+struct sqlResult *sr = sqlGetResult(conn, query);
+char **row;
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = dbDbLoad(row);
+    slAddHead(&dbList, el);
+    }
+sqlFreeResult(&sr);
+hDisconnectCentral(&conn);
+slSort(&dbList, dbDbCmpName);
+printf("{\"source\":\"UCSantaCruz\",\"ucscGenomes\":[");
+for ( el=dbList; el != NULL; el = el->next )
+    {
+    dbDbJsonOutput(el, stdout);
+    if (el->next)
+       printf(",");
+    }
+printf("]}\n");
+}
+
 #define MAX_PATH_INFO 32
 static void apiList(char *words[MAX_PATH_INFO])
 /* 'list' function */
 {
 if (sameWord("publicHubs", words[1]))
     jsonPublicHubs();
+else if (sameWord("ucscGenomes", words[1]))
+    jsonDbDb();
 else if (sameWord("genomes", 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)
 	{
-	fputc('{',stdout);
+        printf("{\"source\":\"UCSantaCruz\",");
 	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");
@@ -544,31 +615,31 @@
     char *hubUrl = cgiOptionalString("hubUrl");
     char *genome = cgiOptionalString("genome");
     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);
-	fputc('{',stdout);
+        printf("{\"source\":\"UCSantaCruz\",");
 	jsonStringOut(stdout, "hubUrl", hubUrl);
 	fputc(',',stdout);
 	jsonStringOut(stdout, "genome", genome);
 	fputc(',',stdout);
 	printf("\"tracks\":[");
 	slNameSort(&dbTrackList);
 	struct slName *el = dbTrackList;
 	for ( ; el ; el = el->next )
 	    {
 	    char *a = jsonStringEscape(el->name);
 	    printf("\"%s\"", a);
 	    freeMem(a);
 	    if (el->next)
 		fputc(',',stdout);
 	    }
@@ -656,32 +727,33 @@
     urlInput = otherHubUrl;
 
 long lastTime = clock1000();
 struct trackHub *hub = trackHubOpen(urlInput, "");
 if (measureTiming)
     {
     long thisTime = clock1000();
     hPrintf("<em>hub open time: %ld millis</em><br>\n", thisTime - lastTime);
     }
 
 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/tracks?hubUrl=%s&genome=%s'>list tracks from specified hub and genome</a> <em>/cgi-bin/hubApi/list/genomes?hubUrl='%s&genome=%s'</em></li>\n", urlInput, hubGenome->name, urlInput, hubGenome->name);
+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("</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:&nbsp;</b>");
 #define JBUFSIZE 2048
 char javascript[JBUFSIZE];
 struct slPair *events = NULL;
 safef(javascript, sizeof(javascript), "this.lastIndex=this.selectedIndex;");
 slPairAdd(&events, "focus", cloneString(javascript));