8a4758bc9826bad352cbce19052b01f28fb7171c hiram Fri Jul 5 11:25:55 2019 -0700 now allowing getData for any table in the database refs #23589 diff --git src/hg/hubApi/getData.c src/hg/hubApi/getData.c index 347f58c..2e4fcce 100644 --- src/hg/hubApi/getData.c +++ src/hg/hubApi/getData.c @@ -189,48 +189,48 @@ { /* 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 (tdb && startsWith("wig", tdb->type)) { if (jsonOutputArrays || debug) wigColumnTypes(jw); jsonWriteListStart(jw, chrom); itemsReturned += wigTableDataOutput(jw, db, splitSqlTable, chrom, 0, ci->size, 0); jsonWriteListEnd(jw); return; /* DONE */ } else { sqlDyStringPrintf(query, "select * from %s where %s='%s' order by %s", splitSqlTable, chromName, chrom, startName); } } else /* fully specified chrom:start-end */ { jsonWriteString(jw, "chrom", chrom); - if (startsWith("wig", tdb->type)) + if (tdb && startsWith("wig", tdb->type)) { if (jsonOutputArrays || debug) wigColumnTypes(jw); jsonWriteListStart(jw, chrom); itemsReturned += wigTableDataOutput(jw, db, splitSqlTable, chrom, start, end, 0); jsonWriteListEnd(jw); return; /* DONE */ } else { sqlDyStringPrintf(query, "select * from %s where ", splitSqlTable); if (hti->hasBin) hAddBinToQuery(start, end, query); sqlDyStringPrintf(query, "%s='%s' AND %s > %u AND %s < %u ORDER BY %s", chromName, chrom, endName, start, startName, end, startName); } @@ -263,31 +263,31 @@ struct chromInfo *ciList = createChromInfoList(NULL, db); slSort(ciList, chromInfoCmp); struct chromInfo *ci = ciList; for ( ; ci && itemsDone < maxItemsOutput; 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", ci->chrom, hti->rootName); sqlDyStringPrintf(query, "select * from %s", fullTableName); } else sqlDyStringPrintf(query, "select * from %s", splitSqlTable); - if (startsWith("wig", tdb->type)) + if (tdb && 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 */ } if (itemsDone >= maxItemsOutput) reachedMaxItems = TRUE; jsonWriteObjectEnd(jw); /* end track data output */ itemsReturned += itemsDone; } else { /* a single chrom has been requested, run it */ jsonWriteListStart(jw, track); /* data output list starting */ @@ -436,31 +436,31 @@ if (isEmpty(track)) apiErrAbort(err400, err400Msg, "missing track=<name> for endpoint '/getData/track' given hubUrl='%s'", hubUrl); struct trackHub *hub = errCatchTrackHubOpen(hubUrl); struct trackHubGenome *hubGenome = findHubGenome(hub, genome, "/getData/track", hubUrl); struct trackDb *tdb = obtainTdb(hubGenome, NULL); if (NULL == tdb) apiErrAbort(err400, err400Msg, "failed to find a track hub definition in genome=%s for endpoint '/getData/track' given hubUrl='%s'", genome, hubUrl); struct trackDb *thisTrack = findTrackDb(track, tdb); if (NULL == thisTrack) apiErrAbort(err400, err400Msg, "failed to find specified track=%s in genome=%s for endpoint '/getData/track' given hubUrl='%s'", track, genome, hubUrl); -if (tdbIsComposite(thisTrack) || tdbIsCompositeView(thisTrack)) +if (trackHasNoData(thisTrack)) apiErrAbort(err400, err400Msg, "container track '%s' does not contain data, use the children of this container for data access", track); if (! isSupportedType(thisTrack->type)) apiErrAbort(err415, err415Msg, "track type '%s' for track=%s not supported at this time", thisTrack->type, track); char *bigDataUrl = trackDbSetting(thisTrack, "bigDataUrl"); struct bbiFile *bbi = bigFileOpen(thisTrack->type, bigDataUrl); if (NULL == bbi) apiErrAbort(err400, err400Msg, "track type %s management not implemented yet TBD track=%s in genome=%s for endpoint '/getData/track' given hubUrl='%s'", thisTrack->type, track, genome, hubUrl); struct jsonWrite *jw = apiStartOutput(); jsonWriteString(jw, "hubUrl", hubUrl); jsonWriteString(jw, "genome", genome); unsigned chromSize = 0; struct bbiChromInfo *chromList = NULL; if (isNotEmpty(chrom)) @@ -545,61 +545,73 @@ unsigned uStart = 0; unsigned uEnd = chromSize; /* maybe set later */ if ( ! (isEmpty(start) || isEmpty(end)) ) { uStart = sqlUnsigned(start); uEnd = sqlUnsigned(end); if (uEnd < uStart) apiErrAbort(err400, err400Msg, "given start coordinate %u is greater than given end coordinate", uStart, uEnd); } if (isEmpty(db)) apiErrAbort(err400, err400Msg, "missing URL variable genome=<ucscDb> name for endpoint '/getData/track"); if (isEmpty(track)) apiErrAbort(err400, err400Msg, "missing URL variable track=<trackName> name for endpoint '/getData/track"); +/* database existence has already been checked before now, might + * have disappeared in the mean time (well, not really . . .) + */ +struct sqlConnection *conn = hAllocConnMaybe(db); +if (NULL == conn) + apiErrAbort(err400, err400Msg, "can not find genome 'genome=%s' for endpoint '/getData/track", db); + struct trackDb *thisTrack = hTrackDbForTrack(db, track); if (NULL == thisTrack) + { + if (! sqlTableExists(conn, track)) apiErrAbort(err400, err400Msg, "can not find track=%s name for endpoint '/getData/track", track); -if (tdbIsComposite(thisTrack) || tdbIsCompositeView(thisTrack)) + } +if (thisTrack && ! isSupportedType(thisTrack->type)) + apiErrAbort(err415, err415Msg, "track type '%s' for track=%s not supported at this time", thisTrack->type, track); +if (trackHasNoData(thisTrack)) apiErrAbort(err400, err400Msg, "container track '%s' does not contain data, use the children of this container", track); -if (! isSupportedType(thisTrack->type)) - apiErrAbort(err415, err415Msg, "track type '%s' for track=%s not supported at this time subtracks %llx", thisTrack->type, track, (unsigned long long)thisTrack->subtracks); - // tdb->subtracks && COMPOSITE_NODE( tdb->treeNodeType); /* might be a big* track with no table */ -char *bigDataUrl = trackDbSetting(thisTrack, "bigDataUrl"); +char *bigDataUrl = NULL; boolean tableTrack = TRUE; +boolean protectedData = FALSE; + +if (thisTrack) + { + bigDataUrl = trackDbSetting(thisTrack, "bigDataUrl"); /* might have a specific table defined instead of the track name */ char *tableName = trackDbSetting(thisTrack, "table"); if (isNotEmpty(tableName)) { freeMem(sqlTable); sqlTable = cloneString(tableName); } -boolean protectedData = FALSE; if (trackDbSetting(thisTrack, "tableBrowser")) protectedData = TRUE; - -/* database existence has already been checked before now, might - * have disappeared in the mean time - */ -struct sqlConnection *conn = hAllocConnMaybe(db); -if (NULL == conn) - apiErrAbort(err400, err400Msg, "can not find genome 'genome=%s' for endpoint '/getData/track", db); + } +else + { + freeMem(sqlTable); + sqlTable = cloneString(track); + } struct hTableInfo *hti = hFindTableInfoWithConn(conn, NULL, sqlTable); char *splitSqlTable = NULL; if (hti && hti->isSplit) { if (isNotEmpty(chrom)) { char fullTableName[256]; safef(fullTableName, sizeof(fullTableName), "%s_%s", chrom, hti->rootName); splitSqlTable = cloneString(fullTableName); } else { @@ -624,40 +636,42 @@ jsonWriteString(jw, "genome", db); if (tableTrack) { char *dataTime = NULL; if (hti && hti->isSplit) dataTime = sqlTableUpdate(conn, splitSqlTable); else 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); } +if (thisTrack) jsonWriteString(jw, "trackType", thisTrack->type); + jsonWriteString(jw, "track", track); if (debug) jsonWriteBoolean(jw, "jsonOutputArrays", jsonOutputArrays); char query[4096]; struct bbiFile *bbi = NULL; struct bbiChromInfo *chromList = NULL; -if (startsWith("big", thisTrack->type)) +if (thisTrack && 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))) { bigDataUrl = cloneString(quickReturn); bbi = bigFileOpen(thisTrack->type, bigDataUrl); } } if (NULL == bbi) apiErrAbort(err400, err400Msg, "failed to find bigDataUrl=%s for track=%s in database=%s for endpoint '/getData/track'", bigDataUrl, track, db); @@ -674,57 +688,57 @@ else { chromList = bbiChromList(bbi); jsonWriteNumber(jw, "chromCount", (long long)slCount(chromList)); } jsonWriteString(jw, "bigDataUrl", bigDataUrl); } /* when start, end given, show them */ if ( uEnd > uStart ) { jsonWriteNumber(jw, "start", uStart); jsonWriteNumber(jw, "end", uEnd); } -if (allowedBigBedType(thisTrack->type)) +if (thisTrack && allowedBigBedType(thisTrack->type)) { struct asObject *as = bigBedAsOrDefault(bbi); struct sqlFieldType *fiList = sqlFieldTypesFromAs(as); if (jsonOutputArrays || debug) bigColumnTypes(jw, fiList, as); jsonWriteListStart(jw, track); unsigned itemsDone = 0; if (isEmpty(chrom)) { struct bbiChromInfo *bci; for (bci = chromList; bci && (itemsDone < maxItemsOutput); bci = bci->next) { itemsDone += bbiDataOutput(jw, bbi, bci->name, 0, bci->size, fiList, thisTrack, itemsDone); } if (itemsDone >= maxItemsOutput) reachedMaxItems = TRUE; } else itemsDone += bbiDataOutput(jw, bbi, chrom, uStart, uEnd, fiList, thisTrack, itemsDone); itemsReturned += itemsDone; jsonWriteListEnd(jw); } -else if (startsWith("bigWig", thisTrack->type)) +else if (thisTrack && startsWith("bigWig", thisTrack->type)) { if (jsonOutputArrays || debug) wigColumnTypes(jw); jsonWriteObjectStart(jw, track); wigData(jw, bbi, chrom, uStart, uEnd); jsonWriteObjectEnd(jw); bbiFileClose(&bbi); } else tableDataOutput(db, thisTrack, conn, jw, track, chrom, uStart, uEnd); apiFinishOutput(0, NULL, jw); hFreeConn(&conn); }