08cc33e57afb8e6cadcf195e9c9178c84b871720 hiram Fri Apr 19 14:59:12 2019 -0700 correctly wiggle data output adding split table testing refs #18869 diff --git src/hg/hubApi/getData.c src/hg/hubApi/getData.c index a6dd07f..10e9cec 100644 --- src/hg/hubApi/getData.c +++ src/hg/hubApi/getData.c @@ -1,59 +1,63 @@ /* manage endpoint /getData/ functions */ #include "dataApi.h" static unsigned wigTableDataOutput(struct jsonWrite *jw, char *database, char *table, char *chrom, int start, int end, unsigned itemsDone) /* output wiggle data from the given table and specified chrom:start-end */ { struct wiggleDataStream *wds = wiggleDataStreamNew(); wds->setMaxOutput(wds, maxItemsOutput); wds->setChromConstraint(wds, chrom); wds->setPositionConstraint(wds, start, end); int operations = wigFetchAscii; -long long valuesMatched = wds->getData(wds, database, table, operations); -jsonWriteNumber(jw, "valuesMatched", valuesMatched); +(void) wds->getData(wds, database, table, operations); struct wigAsciiData *el; -jsonWriteListStart(jw, chrom); unsigned itemCount = 0; for (el = wds->ascii; (itemCount + itemsDone) < maxItemsOutput && el; el = el->next) { - int s = el->data->chromStart; - int e = s + el->span; - double val = el->data->value; + unsigned span = el->span; + unsigned count = el->count; + unsigned i = 0; + struct asciiDatum *data = el->data; + for ( ; ((itemCount + itemsDone) < maxItemsOutput) && i < count; ++i,++data) + { + int s = data->chromStart; + int e = s + span; + double val = data->value; if (jsonOutputArrays) { jsonWriteListStart(jw, NULL); jsonWriteNumber(jw, NULL, (long long)s); jsonWriteNumber(jw, NULL, (long long)e); jsonWriteDouble(jw, NULL, val); jsonWriteListEnd(jw); } else { jsonWriteObjectStart(jw, NULL); jsonWriteNumber(jw, "start", (long long)s); jsonWriteNumber(jw, "end", (long long)e); jsonWriteDouble(jw, "value", val); jsonWriteObjectEnd(jw); } ++itemCount; } -jsonWriteListEnd(jw); -return itemCount; } +return itemCount; +} /* static unsigned wigTableDataOutput(struct jsonWrite *jw, ...) */ static void jsonDatumOut(struct jsonWrite *jw, char *name, char *val, int jsonType) /* output a json item, determine type, appropriate output, name can be NULL */ { if (JSON_DOUBLE == jsonType) jsonWriteDouble(jw, name, sqlDouble(val)); else if (JSON_NUMBER == jsonType) jsonWriteNumber(jw, name, sqlLongLong(val)); else jsonWriteString(jw, name, val); } static void wigColumnTypes(struct jsonWrite *jw) /* output column headers for a wiggle data output schema */ @@ -216,50 +220,54 @@ * determine if split, and then will go through each chrom */ sqlDyStringPrintf(query, "select * from %s", splitSqlTable); } else if (0 == (start + end)) /* have chrom, no start,end == full chr */ { if (! sqlColumnExists(conn, splitSqlTable, 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); if (startsWith("wig", tdb->type)) { + jsonWriteListStart(jw, NULL); if (jsonOutputArrays || debug) wigColumnTypes(jw); wigTableDataOutput(jw, db, splitSqlTable, chrom, 0, ci->size, 0); + jsonWriteListEnd(jw); return; /* DONE */ } else { sqlDyStringPrintf(query, "select * from %s where %s='%s'", splitSqlTable, 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)) { + jsonWriteListStart(jw, NULL); if (jsonOutputArrays || debug) wigColumnTypes(jw); wigTableDataOutput(jw, db, splitSqlTable, chrom, start, end, 0); + jsonWriteListEnd(jw); return; /* DONE */ } else { sqlDyStringPrintf(query, "select * from %s where ", splitSqlTable); hAddBinToQuery(start, end, query); sqlDyStringPrintf(query, "%s='%s' AND %s > %u AND %s < %u", chromName, chrom, endName, start, startName, end); } } if (debug) jsonWriteString(jw, "select", query->string); /* continuing, not a wiggle output */ char **columnNames = NULL; @@ -294,68 +302,70 @@ /* perhaps move the comment pointer forward */ if (columnEl) { if (asColumnCount == columnCount) columnEl = columnEl->next; else if (! ((0 == i) && (hti && hti->hasBin))) columnEl = columnEl->next; } jsonWriteObjectEnd(jw); } jsonWriteListEnd(jw); } } -/* data output list starting */ -jsonWriteListStart(jw, track); - unsigned itemsDone = 0; /* empty chrom, needs to run through all chrom names */ if (isEmpty(chrom)) { + jsonWriteObjectStart(jw, track); /* begin track data output */ char fullTableName[256]; struct chromInfo *ciList = createChromInfoList(NULL, db); slSort(ciList, chromInfoCmp); - struct chromInfo *el = ciList; - for ( ; itemsDone < maxItemsOutput && el != NULL; el = el->next ) + struct chromInfo *ci = ciList; + for ( ; itemsDone < maxItemsOutput && ci != NULL; ci = ci->next ) { + jsonWriteListStart(jw, ci->chrom); /* starting a chrom output */ freeDyString(&query); query = dyStringNew(64); if (hti && hti->isSplit) /* when split, make up split chr name */ { - safef(fullTableName, sizeof(fullTableName), "%s_%s", el->chrom, hti->rootName); + safef(fullTableName, sizeof(fullTableName), "%s_%s", ci->chrom, hti->rootName); sqlDyStringPrintf(query, "select * from %s", fullTableName); } else sqlDyStringPrintf(query, "select * from %s", splitSqlTable); if (startsWith("wig", tdb->type)) itemsDone += wigTableDataOutput(jw, db, splitSqlTable, chrom, start, end, itemsDone); else itemsDone += sqlQueryJsonOutput(conn, jw, query->string, columnCount, columnNames, jsonTypes, itemsDone); + jsonWriteListEnd(jw); /* chrom data output list end */ } + jsonWriteObjectEnd(jw); /* end track data output */ } else - { + { /* a single chrom has been requested, run it */ + jsonWriteListStart(jw, track); /* data output list starting */ itemsDone += sqlQueryJsonOutput(conn, jw, query->string, columnCount, columnNames, jsonTypes, itemsDone); + jsonWriteListEnd(jw); /* data output list end */ } freeDyString(&query); -jsonWriteListEnd(jw); /* data output list end */ } /* static void tableDataOutput(char *db, struct trackDb *tdb, ... ) */ static boolean typedBig9Plus(struct trackDb *tdb) /* check if track type is 'bed 9+ ...' to determine itemRgb for big* types */ { if (isNotEmpty(tdb->type) && (allowedBigBedType(tdb->type))) { char *words[8]; int wordCount; wordCount = chopLine(cloneString(tdb->type), words); if ( (wordCount > 1) && startsWith("bigBed", words[0])) { if (isAllDigits(words[1])) if (8 < sqlUnsigned(words[1])) return TRUE;