840cb1f540fd01d0728d0313bcafebe95b2bd6ca hiram Fri Apr 19 10:11:42 2019 -0700 complete wiggle table output for all options refs #18869 diff --git src/hg/hubApi/getData.c src/hg/hubApi/getData.c index d4940ef..a6dd07f 100644 --- src/hg/hubApi/getData.c +++ src/hg/hubApi/getData.c @@ -1,56 +1,58 @@ /* manage endpoint /getData/ functions */ #include "dataApi.h" -static void wigTableDataOutput(struct jsonWrite *jw, char *database, char *table, char *chrom, int start, int end) +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); struct wigAsciiData *el; jsonWriteListStart(jw, chrom); unsigned itemCount = 0; -for (el = wds->ascii; itemCount < maxItemsOutput && el; el = el->next) +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; 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; } 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) @@ -212,120 +214,148 @@ { /* this setup here is for the case of non-split tables, will later * 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)) + { + if (jsonOutputArrays || debug) + wigColumnTypes(jw); + wigTableDataOutput(jw, db, splitSqlTable, chrom, 0, ci->size, 0); + 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 (jsonOutputArrays || debug) - wigColumnTypes(jw); if (startsWith("wig", tdb->type)) { - wigTableDataOutput(jw, db, splitSqlTable, chrom, start, end); + if (jsonOutputArrays || debug) + wigColumnTypes(jw); + wigTableDataOutput(jw, db, splitSqlTable, chrom, start, end, 0); 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; char **columnTypes = NULL; int *jsonTypes = NULL; struct asObject *as = asForTable(conn, splitSqlTable, tdb); struct asColumn *columnEl = as->columnList; int asColumnCount = slCount(columnEl); int columnCount = tableColumns(conn, jw, splitSqlTable, &columnNames, &columnTypes, &jsonTypes); if (jsonOutputArrays || debug) { + if (startsWith("wig", tdb->type)) + { + wigColumnTypes(jw); + } + else + { jsonWriteListStart(jw, "columnTypes"); int i = 0; for (i = 0; i < columnCount; ++i) { jsonWriteObjectStart(jw, NULL); jsonWriteString(jw, "name", columnNames[i]); jsonWriteString(jw, "sqlType", columnTypes[i]); jsonWriteString(jw, "jsonType", jsonTypeStrings[jsonTypes[i]]); if ((0 == i) && (hti && hti->hasBin)) jsonWriteString(jw, "description", "Indexing field to speed chromosome range queries"); else if (columnEl && isNotEmpty(columnEl->comment)) jsonWriteString(jw, "description", columnEl->comment); else jsonWriteString(jw, "description", ""); /* 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 and isSplit, needs to run through all chrom names */ -if ((hti && hti->isSplit) && isEmpty(chrom)) +/* empty chrom, needs to run through all chrom names */ +if (isEmpty(chrom)) { + char fullTableName[256]; struct chromInfo *ciList = createChromInfoList(NULL, db); slSort(ciList, chromInfoCmp); struct chromInfo *el = ciList; - char fullTableName[256]; for ( ; itemsDone < maxItemsOutput && el != NULL; el = el->next ) { 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); sqlDyStringPrintf(query, "select * from %s", fullTableName); - itemsDone += sqlQueryJsonOutput(conn, jw, query->string, columnCount, - columnNames, jsonTypes, itemsDone); + } + 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); } } else { itemsDone += sqlQueryJsonOutput(conn, jw, query->string, columnCount, columnNames, jsonTypes, itemsDone); } freeDyString(&query); -jsonWriteListEnd(jw); +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;