03680a45cb9806e93bc784905fbdb4f6e9ac063e
hiram
  Fri Feb 8 14:26:15 2019 -0800
output column names for dbDb table refs #18869

diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c
index 4f16665..8b6078c 100644
--- src/hg/hubApi/hubApi.c
+++ src/hg/hubApi/hubApi.c
@@ -108,57 +108,57 @@
 fputc(',',f);
 }
 
 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);
 jsonTagValue(stdout, "error", errMsg);
 fputc('}',stdout);
 }
 
-static void hubPublicJsonData(struct hubPublic *el, FILE *f)
+static void hubPublicJsonData(FILE *f, struct hubPublic *el)
 /* Print array data for one row from hubPublic table, order here
  * must be same as was stated in the columnName header element
  *  TODO: need to figure out how to use the order of the columns as
  *        they are in the 'desc' request
  */
 {
 fputc('[',f);
 jsonStringPrint(f, el->hubUrl);
 fputc(',',f);
 jsonStringPrint(f, el->shortLabel);
 fputc(',',f);
 jsonStringPrint(f, el->longLabel);
 fputc(',',f);
 jsonStringPrint(f, el->registrationTime);
 fputc(',',f);
 fprintf(f, "%lld", (long long)el->dbCount);
 fputc(',',f);
 jsonStringPrint(f, el->dbList);
 fputc(',',f);
 jsonStringPrint(f, el->descriptionUrl);
 fputc(']',f);
 }
 
 #ifdef NOT
 /* This function should be in hg/lib/hubPublic.c */
-static void hubPublicJsonOutput(struct hubPublic *el, FILE *f)
+static void hubPublicJsonOutput(FILE *f, struct hubPublic *el)
 /* Print out hubPublic element in JSON format. */
 {
 fputc('{',f);
 jsonTagValue(f, "hubUrl", el->hubUrl);
 fputc(',',f);
 jsonTagValue(f, "shortLabel", el->shortLabel);
 fputc(',',f);
 jsonTagValue(f, "longLabel", el->longLabel);
 fputc(',',f);
 jsonTagValue(f, "registrationTime", el->registrationTime);
 fputc(',',f);
 jsonInteger(f, "dbCount", el->dbCount);
 fputc(',',f);
 jsonTagValue(f, "dbList", el->dbList);
 fputc(',',f);
@@ -535,31 +535,71 @@
 
 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)
+static void dbDbJsonData(FILE *f, struct dbDb *el)
+/* Print out dbDb table element in JSON format.
+ * must be same as was stated in the columnName header element
+ *  TODO: need to figure out how to use the order of the columns as
+ *        they are in the 'desc' request
+ */
+{
+fputc('[',f);
+jsonStringPrint(f, el->name);
+fputc(',',f);
+jsonStringPrint(f, el->description);
+fputc(',',f);
+jsonStringPrint(f, el->nibPath);
+fputc(',',f);
+jsonStringPrint(f, el->organism);
+fputc(',',f);
+jsonStringPrint(f, el->defaultPos);
+fputc(',',f);
+fprintf(f, "%lld", (long long)el->active);
+fputc(',',f);
+fprintf(f, "%lld", (long long)el->orderKey);
+fputc(',',f);
+jsonStringPrint(f, el->genome);
+fputc(',',f);
+jsonStringPrint(f, el->scientificName);
+fputc(',',f);
+jsonStringPrint(f, el->htmlPath);
+fputc(',',f);
+fprintf(f, "%lld", (long long)el->hgNearOk);
+fputc(',',f);
+fprintf(f, "%lld", (long long)el->hgPbOk);
+fputc(',',f);
+jsonStringPrint(f, el->sourceName);
+fputc(',',f);
+fprintf(f, "%lld", (long long)el->taxId);
+fputc(']',f);
+}
+
+#ifdef NOT
+/* this code should be in hg/lib/dbDb.c */
+static void dbDbJsonOutput(FILE *f, struct dbDb *el)
 /* Print out hubPublic element in JSON format. */
 {
 fputc('{',f);
 jsonTagValue(f, "name", el->name);
 fputc(',',f);
 jsonTagValue(f, "description", el->description);
 fputc(',',f);
 jsonTagValue(f, "nibPath", el->nibPath);
 fputc(',',f);
 jsonTagValue(f, "organism", el->organism);
 fputc(',',f);
 jsonTagValue(f, "defaultPos", el->defaultPos);
 fputc(',',f);
 jsonInteger(f, "active", el->active);
 fputc(',',f);
@@ -568,30 +608,31 @@
 jsonTagValue(f, "genome", el->genome);
 fputc(',',f);
 jsonTagValue(f, "scientificName", el->scientificName);
 fputc(',',f);
 jsonTagValue(f, "htmlPath", el->htmlPath);
 fputc(',',f);
 jsonInteger(f, "hgNearOk", el->hgNearOk);
 fputc(',',f);
 jsonInteger(f, "hgPbOk", el->hgPbOk);
 fputc(',',f);
 jsonTagValue(f, "sourceName", el->sourceName);
 fputc(',',f);
 jsonInteger(f, "taxId", el->taxId);
 fputc('}',f);
 }
+#endif
 
 static boolean tableColumns(FILE *f, char *table)
 /* output the column names for the given table
  * return: TRUE on error, FALSE on success
  */
 {
 fprintf(f, "\"columnNames\":[");
 char query[1024];
 struct sqlConnection *conn = hConnectCentral();
 sqlSafef(query, sizeof(query), "desc %s", table);
 struct sqlResult *sr = sqlGetResult(conn, query);
 char **row;
 row = sqlNextRow(sr);
 if (NULL == row)
     {
@@ -608,31 +649,31 @@
 sqlFreeResult(&sr);
 hDisconnectCentral(&conn);
 fprintf(f, "],");
 return FALSE;
 }
 
 static void jsonPublicHubs()
 /* output the hubPublic SQL table */
 {
 struct hubPublic *el = publicHubList;
 jsonStartOutput(stdout);
 tableColumns(stdout, hubPublicTableName());
 printf("\"publicHubData\":[");
 for ( ; el != NULL; el = el->next )
     {
-    hubPublicJsonData(el, stdout);
+    hubPublicJsonData(stdout, el);
     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 struct dbDb *ucscDbDb()
@@ -649,42 +690,47 @@
     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;
 jsonStartOutput(stdout);
+tableColumns(stdout, "dbDb");
 printf("\"ucscGenomes\":[");
 for ( el=dbList; el != NULL; el = el->next )
     {
-    dbDbJsonOutput(el, stdout);
+    dbDbJsonData(stdout, el);
     if (el->next)
        printf(",");
     }
 printf("]}\n");
 }
 
-static void chromInfoJsonOutput(char *db, FILE *f, char *track)
+static void chromInfoJsonOutput(FILE *f, char *db)
+/* for given db, if there is a track, list the chromosomes in that track,
+ * for no track, simply list the chromosomes in the sequence
+ */
 {
+char *track = cgiOptionalString("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);
 	jsonTagValue(f, "genome", db);
 	fputc(',',f);
 	jsonTagValue(f, "track", track);
 	fputc(',',f);
         struct slPair *list = NULL;
 	char query[2048];
         sqlSafef(query, sizeof(query), "select distinct chrom from %s", track);
@@ -722,40 +768,30 @@
     jsonStartOutput(f);
     jsonTagValue(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;
 jsonStartOutput(f);
 jsonTagValue(f, "db", db);
 fputc(',',f);
 fprintf(f, "\"tracks\":[");
 for (el = tdbList; el != NULL; el = el->next )
     {
     jsonStringPrint(f, el->track);
     if (el->next)
 	fputc(',',f);
     }
@@ -833,31 +869,31 @@
 		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))
         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
+        chromInfoJsonOutput(stdout, db);
 	return;
 	}
     }
 else
     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;