eda78578a5c610db7acf00034b8823d6e9b96383
hiram
  Tue Feb 19 14:39:21 2019 -0800
returning any and all data from bigBed track refs #18869

diff --git src/hg/hubApi/getData.c src/hg/hubApi/getData.c
index 7188b0b..7a7b0b8 100644
--- src/hg/hubApi/getData.c
+++ src/hg/hubApi/getData.c
@@ -56,30 +56,53 @@
 /* Convert asObject to list of sqlFieldTypes */
 {
 struct sqlFieldType *ft, *list = NULL;
 struct asColumn *col;
 for (col = as->columnList; col != NULL; col = col->next)
     {
     struct dyString *type = asColumnToSqlType(col);
     ft = sqlFieldTypeNew(col->name, type->string);
     slAddHead(&list, ft);
     dyStringFree(&type);
     }
 slReverse(&list);
 return list;
 }
 
+static void bedDataOutput(struct jsonWrite *jw, struct bbiFile *bbi,
+    char *chrom, unsigned start, unsigned end, unsigned maxItems)
+/* output the data for one chrom in the given bbi file */
+{
+struct lm *bbLm = lmInit(0);
+struct bigBedInterval *iv, *ivList = NULL;
+ivList = bigBedIntervalQuery(bbi,chrom, start, end, 0, bbLm);
+char *row[bbi->fieldCount];
+for (iv = ivList; iv; iv = iv->next)
+    {
+    char startBuf[16], endBuf[16];
+    bigBedIntervalToRow(iv, chrom, startBuf, endBuf, row, bbi->fieldCount);
+    jsonWriteListStart(jw, NULL);
+    int i;
+    for (i = 0; i < bbi->fieldCount; ++i)
+        {
+        jsonWriteString(jw, NULL, row[i]);
+        }
+    jsonWriteListEnd(jw);
+    }
+lmCleanup(&bbLm);
+}
+
 static void getHubTrackData(char *hubUrl)
 /* return data from a hub track, optionally just one chrom data,
  *  optionally just one section of that chrom data
  */
 {
 char *genome = cgiOptionalString("genome");
 char *track = cgiOptionalString("track");
 char *chrom = cgiOptionalString("chrom");
 char *start = cgiOptionalString("start");
 char *end = cgiOptionalString("end");
 
 if (isEmpty(genome))
     apiErrAbort("missing genome=<name> for endpoint '/getdata/track'  given hubUrl='%s'", hubUrl);
 if (isEmpty(track))
     apiErrAbort("missing track=<name> for endpoint '/getdata/track'  given hubUrl='%s'", hubUrl);
@@ -96,81 +119,94 @@
 
 struct trackDb *tdb = trackHubTracksForGenome(hubGenome->trackHub, hubGenome);
 
 if (NULL == tdb)
     apiErrAbort("failed to find a track hub definition in genome=%s for endpoint '/getdata/track'  given hubUrl='%s'", genome, hubUrl);
 
 struct trackDb *thisTrack = NULL;
 for (thisTrack = tdb; thisTrack; thisTrack = thisTrack->next)
     {
     if (sameWord(thisTrack->track, track))
 	break;
     }
 if (NULL == thisTrack)
     apiErrAbort("failed to find specified track=%s in genome=%s for endpoint '/getdata/track'  given hubUrl='%s'", track, genome, hubUrl);
 
+char *bigDataUrl = trackDbSetting(thisTrack, "bigDataUrl");
+struct bbiFile *bbi = bigFileOpen(thisTrack->type, bigDataUrl);
+if (NULL == bbi)
+    apiErrAbort("track type %s management not implemented yet TBD track=%s in genome=%s for endpoint '/getdata/track'  given hubUrl='%s'", track, genome, hubUrl);
+
 struct jsonWrite *jw = apiStartOutput();
 jsonWriteString(jw, "hubUrl", hubUrl);
 jsonWriteString(jw, "genome", genome);
 jsonWriteString(jw, "track", track);
+unsigned chromSize = 0;
+struct bbiChromInfo *chromList = NULL;
 if (isNotEmpty(chrom))
+    {
     jsonWriteString(jw, "chrom", chrom);
+    chromSize = bbiChromSize(bbi, chrom);
+    if (0 == chromSize)
+	apiErrAbort("can not find specified chrom=%s in bigBed file URL %s", chrom, bigDataUrl);
+    jsonWriteNumber(jw, "chromSize", (long long)chromSize);
+    }
+else
+    {
+    chromList = bbiChromList(bbi);
+    jsonWriteNumber(jw, "chromCount", (long long)slCount(chromList));
+    }
+
+unsigned uStart = 0;
+unsigned uEnd = chromSize;
 if ( ! (isEmpty(start) || isEmpty(end)) )
     {
-    jsonWriteString(jw, "start", start);
-    jsonWriteString(jw, "end", end);
+    uStart = sqlUnsigned(start);
+    uEnd = sqlUnsigned(end);
+    jsonWriteNumber(jw, "start", uStart);
+    jsonWriteNumber(jw, "end", uEnd);
     }
-char *bigDataUrl = trackDbSetting(thisTrack, "bigDataUrl");
+
 jsonWriteString(jw, "bigDataUrl", bigDataUrl);
 jsonWriteString(jw, "type", thisTrack->type);
-struct bbiFile *bbi = bigFileOpen(thisTrack->type, bigDataUrl);
-if (NULL == bbi)
-    apiErrAbort("track type %s management not implemented yet TBD track=%s in genome=%s for endpoint '/getdata/track'  given hubUrl='%s'", track, genome, hubUrl);
+
 if (startsWith("bigBed", thisTrack->type))
     {
     struct asObject *as = bigBedAsOrDefault(bbi);
     struct sqlFieldType *fi, *fiList = sqlFieldTypesFromAs(as);
     jsonWriteListStart(jw, "columnNames");
+    unsigned maxItems = 0;	/* TBD will use this later for paging */
 //    int columnCount = slCount(fiList);
     for (fi = fiList; fi; fi = fi->next)
 	{
 	jsonWriteObjectStart(jw, NULL);
 	jsonWriteString(jw, fi->name, fi->type);
 	jsonWriteObjectEnd(jw);
 	}
     jsonWriteListEnd(jw);
-    struct lm *bbLm = lmInit(0);
-    unsigned uStart = sqlUnsigned(start);
-    unsigned uEnd = sqlUnsigned(end);
-    struct bigBedInterval *iv, *ivList = NULL;
-    ivList = bigBedIntervalQuery(bbi,chrom, uStart, uEnd, 0, bbLm);
-    char *row[bbi->fieldCount];
     jsonWriteListStart(jw, "trackData");
-    for (iv = ivList; iv; iv = iv->next)
+    if (isEmpty(chrom))
 	{
-	char startBuf[16], endBuf[16];
-	bigBedIntervalToRow(iv, chrom, startBuf, endBuf, row, bbi->fieldCount);
-	jsonWriteListStart(jw, NULL);
-        int i;
-        for (i = 0; i < bbi->fieldCount; ++i)
+	struct bbiChromInfo *bci;
+	for (bci = chromList; bci; bci = bci->next)
 	    {
-	    jsonWriteString(jw, NULL, row[i]);
+	    bedDataOutput(jw, bbi, bci->name, 0, bci->size, maxItems);
 	    }
-	jsonWriteListEnd(jw);
 	}
+    else
+	bedDataOutput(jw, bbi, chrom, uStart, uEnd, maxItems);
     jsonWriteListEnd(jw);
-    lmCleanup(&bbLm);
     }
 else if (startsWith("bigWig", thisTrack->type))
     {
     }
 bbiFileClose(&bbi);
 jsonWriteObjectEnd(jw);
 fputs(jw->dy->string,stdout);
 }
 
 static void getTrackData()
 /* return data from a track, optionally just one chrom data,
  *  optionally just one section of that chrom data
  */
 {
 char *db = cgiOptionalString("db");