15c2acbbf16454d91d9079216f21427fdd33a609 hiram Tue Apr 16 13:45:20 2019 -0700 beginning to allow the array output time to function refs #18869 diff --git src/hg/hubApi/getData.c src/hg/hubApi/getData.c index ab5e0ab..e0e455a 100644 --- src/hg/hubApi/getData.c +++ src/hg/hubApi/getData.c @@ -87,32 +87,30 @@ safef(endName, sizeof(endName), "genoEnd"); } } if (sqlColumnExists(conn, sqlTable, "txStart")) // track type genePred { safef(startName, sizeof(startName), "txStart"); safef(endName, sizeof(endName), "txEnd"); } /* no chrom specified, return entire table */ if (isEmpty(chrom)) sqlSafef(query, sizeof(query), "select * from %s", sqlTable); else if (0 == (start + end)) /* have chrom, no start,end == full chr */ { -// boolean useTname = FALSE; - /* need to extend the chrom column check to allow tName also */ if (! sqlColumnExists(conn, sqlTable, chromName)) apiErrAbort(err400, err400Msg, "track '%s' is not a position track, request track without chrom specification, genome: '%s'", track, db); jsonWriteString(jw, "chrom", chrom); struct chromInfo *ci = hGetChromInfo(db, chrom); jsonWriteNumber(jw, "start", (long long)0); jsonWriteNumber(jw, "end", (long long)ci->size); sqlSafef(query, sizeof(query), "select * from %s where %s='%s'", sqlTable, chromName, chrom); } else /* fully specified chrom:start-end */ { jsonWriteString(jw, "chrom", chrom); jsonWriteNumber(jw, "start", (long long)start); jsonWriteNumber(jw, "end", (long long)end); if (startsWith("wig", tdb->type)) @@ -122,54 +120,63 @@ } else { sqlSafef(query, sizeof(query), "select * from %s where %s='%s' AND %s > %u AND %s < %u", sqlTable, chromName, chrom, endName, start, startName, end); } } if (debug) jsonWriteString(jw, "select", query); /* continuing, not a wiggle output */ char **columnNames = NULL; char **columnTypes = NULL; int *jsonTypes = NULL; int columnCount = tableColumns(conn, jw, sqlTable, &columnNames, &columnTypes, &jsonTypes); -if (debug) +if (jsonOutputArrays || debug) { jsonWriteObjectStart(jw, "columnTypes"); int i = 0; for (i = 0; i < columnCount; ++i) { char bothTypes[1024]; safef(bothTypes, sizeof(bothTypes), "%s - %s", columnTypes[i], jsonTypeStrings[jsonTypes[i]]); jsonWriteString(jw, columnNames[i], bothTypes); } jsonWriteObjectEnd(jw); } jsonWriteListStart(jw, track); struct sqlResult *sr = sqlGetResult(conn, query); char **row = NULL; unsigned itemCount = 0; while (itemCount < maxItemsOutput && (row = sqlNextRow(sr)) != NULL) { + if (jsonOutputArrays) + jsonWriteListStart(jw, NULL); + else jsonWriteObjectStart(jw, NULL); int i = 0; for (i = 0; i < columnCount; ++i) { + if (jsonOutputArrays) + jsonDatumOut(jw, NULL, row[i], jsonTypes[i]); + else jsonDatumOut(jw, columnNames[i], row[i], jsonTypes[i]); } + if (jsonOutputArrays) + jsonWriteListEnd(jw); + else jsonWriteObjectEnd(jw); ++itemCount; } sqlFreeResult(&sr); jsonWriteListEnd(jw); } /* static void tableDataOutput(char *db, struct trackDb *tdb, ... ) */ static void bedDataOutput(struct jsonWrite *jw, struct bbiFile *bbi, char *chrom, unsigned start, unsigned end, struct sqlFieldType *fiList, struct trackDb *tdb) /* output bed data for one chrom in the given bbi file */ { char *itemRgb = trackDbSetting(tdb, "itemRgb"); int *jsonTypes = NULL; int columnCount = slCount(fiList); @@ -185,43 +192,52 @@ else jsonTypes[i++] = autoSqlToJsonType(fi->type); } else jsonTypes[i++] = autoSqlToJsonType(fi->type); } struct lm *bbLm = lmInit(0); struct bigBedInterval *iv, *ivList = NULL; ivList = bigBedIntervalQuery(bbi,chrom, start, end, 0, bbLm); char *row[bbi->fieldCount]; unsigned itemCount = 0; for (iv = ivList; itemCount < maxItemsOutput && iv; iv = iv->next) { char startBuf[16], endBuf[16]; bigBedIntervalToRow(iv, chrom, startBuf, endBuf, row, bbi->fieldCount); + if (jsonOutputArrays) + jsonWriteListStart(jw, NULL); + else jsonWriteObjectStart(jw, NULL); int i; struct sqlFieldType *fi = fiList; for (i = 0; i < bbi->fieldCount; ++i) { + if (jsonOutputArrays) + jsonDatumOut(jw, NULL, row[i], jsonTypes[i]); + else jsonDatumOut(jw, fi->name, row[i], jsonTypes[i]); fi = fi->next; } + if (jsonOutputArrays) + jsonWriteListEnd(jw); + else jsonWriteObjectEnd(jw); ++itemCount; } lmCleanup(&bbLm); -} +} /* static void bedDataOutput(struct jsonWrite *jw, . . . ) */ static void wigDataOutput(struct jsonWrite *jw, struct bbiFile *bwf, char *chrom, unsigned start, unsigned end) /* output wig data for one chrom in the given bwf file */ { struct lm *lm = lmInit(0); struct bbiInterval *iv, *ivList = bigWigIntervalQuery(bwf, chrom, start, end, lm); if (NULL == ivList) return; unsigned itemCount = 0; jsonWriteListStart(jw, chrom); for (iv = ivList; iv && itemCount < maxItemsOutput; iv = iv->next) { @@ -333,30 +349,32 @@ jsonWriteNumber(jw, "chromCount", (long long)slCount(chromList)); } unsigned uStart = 0; unsigned uEnd = chromSize; if ( ! (isEmpty(start) || isEmpty(end)) ) { uStart = sqlUnsigned(start); uEnd = sqlUnsigned(end); jsonWriteNumber(jw, "start", uStart); jsonWriteNumber(jw, "end", uEnd); } jsonWriteString(jw, "bigDataUrl", bigDataUrl); jsonWriteString(jw, "trackType", thisTrack->type); +if (debug) + jsonWriteString(jw, "jsonOutputArrays", jsonOutputArrays ? "TRUE":"FALSE"); if (allowedBigBedType(thisTrack->type)) { struct asObject *as = bigBedAsOrDefault(bbi); struct sqlFieldType *fiList = sqlFieldTypesFromAs(as); if (debug) bigColumnTypes(jw, fiList); jsonWriteListStart(jw, track); if (isEmpty(chrom)) { struct bbiChromInfo *bci; for (bci = chromList; bci; bci = bci->next) { bedDataOutput(jw, bbi, bci->name, 0, bci->size, fiList, thisTrack); @@ -433,30 +451,32 @@ struct jsonWrite *jw = apiStartOutput(); jsonWriteString(jw, "db", db); if (tableTrack) { char *dataTime = sqlTableUpdate(conn, sqlTable); time_t dataTimeStamp = sqlDateToUnixTime(dataTime); replaceChar(dataTime, ' ', 'T'); /* ISO 8601 */ jsonWriteString(jw, "dataTime", dataTime); jsonWriteNumber(jw, "dataTimeStamp", (long long)dataTimeStamp); if (differentStringNullOk(sqlTable,track)) jsonWriteString(jw, "sqlTable", sqlTable); } jsonWriteString(jw, "trackType", thisTrack->type); jsonWriteString(jw, "track", track); +if (debug) + jsonWriteString(jw, "jsonOutputArrays", jsonOutputArrays ? "TRUE":"FALSE"); char query[4096]; struct bbiFile *bbi = NULL; struct bbiChromInfo *chromList = NULL; if (startsWith("big", thisTrack->type)) { if (bigDataUrl) bbi = bigFileOpen(thisTrack->type, bigDataUrl); else { char quickReturn[2048]; sqlSafef(query, sizeof(query), "select fileName from %s", sqlTable); if (sqlQuickQuery(conn, query, quickReturn, sizeof(quickReturn))) { @@ -610,35 +630,39 @@ /* this MaybeChromInfo will open the twoBit file, if not already done */ struct chromInfo *ci = trackHubMaybeChromInfo(hubGenome->name, chrom); if (NULL == ci) apiErrAbort(err400, err400Msg, "can not find sequence for chrom=%s for endpoint '/getData/sequence?genome=%s;chrom=%s' given hubUrl='%s'", chrom, genome, chrom, hubUrl); struct jsonWrite *jw = apiStartOutput(); jsonWriteString(jw, "hubUrl", hubUrl); jsonWriteString(jw, "genome", genome); jsonWriteString(jw, "chrom", chrom); int fragStart = 0; int fragEnd = 0; if (isNotEmpty(start) && isNotEmpty(end)) { fragStart = sqlSigned(start); fragEnd = sqlSigned(end); + if ((fragEnd - fragStart) > MAX_DNA_LENGTH) + apiErrAbort(err400, err400Msg, "DNA sequence request %d too large, limit: %u for endpoint '/getData/sequence?genome=%s;chrom=%s;start=%d;end=%d' given hubUrl='%s'", fragEnd-fragEnd, MAX_DNA_LENGTH, genome, chrom, fragStart, fragEnd, hubUrl); jsonWriteNumber(jw, "start", (long long)fragStart); jsonWriteNumber(jw, "end", (long long)fragEnd); } else { + if (ci->size > MAX_DNA_LENGTH) + apiErrAbort(err400, err400Msg, "DNA sequence request %d too large, limit: %u for endpoint '/getData/sequence?genome=%s;chrom=%s' given hubUrl='%s'", ci->size, MAX_DNA_LENGTH, genome, chrom, hubUrl); jsonWriteNumber(jw, "start", (long long)0); jsonWriteNumber(jw, "end", (long long)ci->size); } struct dnaSeq *seq = twoBitReadSeqFrag(hubGenome->tbf, chrom, fragStart, fragEnd); if (NULL == seq) { if (fragEnd > fragStart) apiErrAbort(err400, err400Msg, "can not find sequence for chrom=%s;start=%s;end=%s for endpoint '/getData/sequence?genome=%s;chrom=%s;start=%s;end=%s' give hubUrl='%s'", chrom, start, end, genome, chrom, start, end, hubUrl); else apiErrAbort(err400, err400Msg, "can not find sequence for chrom=%s for endpoint '/getData/sequence?genome=%s;chrom=%s' give hubUrl='%s'", chrom, genome, chrom, hubUrl); } jsonWriteString(jw, "dna", seq->dna); apiFinishOutput(0, NULL, jw); }