9d54db29580e26c13688de88701c61eae1aca9ce hiram Wed Jul 3 10:55:21 2019 -0700 add trackDb output to the list schema and allow tables without trackDb refs #23589 diff --git src/hg/hubApi/list.c src/hg/hubApi/list.c index 02b5113..9708dde 100644 --- src/hg/hubApi/list.c +++ src/hg/hubApi/list.c @@ -281,30 +281,70 @@ { itemCount = bamFileItemCount(bigDataUrl, indexFileOrUrl); } else if (sameString("vcfTabix", type)) { itemCount = vcfTabixItemCount(bigDataUrl, indexFileOrUrl); } } errCatchEnd(errCatch); if (isNotEmpty(errCatch->message->string)) fprintf(stderr, "%s", errCatch->message->string); errCatchFree(&errCatch); return itemCount; } +static void outputTrackDbVars(struct jsonWrite *jw, struct trackDb *tdb, + long long itemCount) +/* JSON output the fundamental trackDb variables */ +{ +if (NULL == tdb) /* might not be any trackDb */ + return; + +boolean protectedData = FALSE; +if (trackDbSetting(tdb, "tableBrowser")) + protectedData = TRUE; +jsonWriteString(jw, "shortLabel", tdb->shortLabel); +jsonWriteString(jw, "type", tdb->type); +jsonWriteString(jw, "longLabel", tdb->longLabel); +jsonWriteNumber(jw, "itemCount", itemCount); +if (tdb->parent) + { + jsonWriteString(jw, "parent", tdb->parent->track); + if (tdb->parent->parent) + jsonWriteString(jw, "parentParent", tdb->parent->parent->track); + } +if (tdb->settingsHash) + { + struct hashEl *hel; + struct hashCookie hc = hashFirst(tdb->settingsHash); + while ((hel = hashNext(&hc)) != NULL) + { + if (sameWord("track", hel->name)) + continue; // already output in header + if (sameWord("tableBrowser", hel->name)) + jsonWriteBoolean(jw, "protectedData", TRUE); + else if (isEmpty((char *)hel->val)) + jsonWriteString(jw, hel->name, "empty"); + else if (protectedData && sameWord(hel->name, "bigDataUrl")) + jsonWriteString(jw, hel->name, "protectedData"); + else + jsonWriteString(jw, hel->name, (char *)hel->val); + } + } +} + static void hubSchemaJsonOutput(FILE *f, char *hubUrl, char *genome, char *track) /* for given hubUrl and track, output the schema for the hub track */ { struct trackHub *hub = errCatchTrackHubOpen(hubUrl); struct trackHubGenome *ge = NULL; if (isEmpty(genome)) apiErrAbort(err400, err400Msg, "must specify a 'genome=name' with hubUrl for endpoint: /list/schema?hubUrl=%s;genome=<empty>", hubUrl); struct trackHubGenome *foundGenome = NULL; for (ge = hub->genomeList; ge; ge = ge->next) { if (sameOk(genome, ge->name)) { @@ -324,55 +364,58 @@ struct trackDb *tdb = obtainTdb(foundGenome, NULL); if (NULL == tdb) apiErrAbort(err400, err400Msg, "failed to find a track hub definition in genome=%s track=%s for endpoint '/list/schema' given hubUrl=%s'", genome, track, hubUrl); struct trackDb *thisTrack = findTrackDb(track, tdb); if (NULL == thisTrack) apiErrAbort(err400, err400Msg, "failed to find specified track=%s in genome=%s for endpoint '/list/schema' given hubUrl='%s'", track, genome, hubUrl); char *bigDataUrl = hReplaceGbdb(trackDbSetting(thisTrack, "bigDataUrl")); if (NULL == bigDataUrl) apiErrAbort(err400, err400Msg, "failed to find bigDataUrl for specified track=%s in genome=%s for endpoint '/list/schema' given hubUrl='%s'", track, genome, hubUrl); char *indexFileOrUrl = hReplaceGbdb(trackDbSetting(tdb, "bigDataIndex")); struct bbiFile *bbi = bigFileOpen(thisTrack->type, bigDataUrl); long long itemCount = bbiItemCount(bigDataUrl, thisTrack->type, indexFileOrUrl); -jsonWriteNumber(jw, "itemCount", itemCount); +outputTrackDbVars(jw, thisTrack, itemCount); struct asObject *as = bigBedAsOrDefault(bbi); struct sqlFieldType *fiList = sqlFieldTypesFromAs(as); bigColumnTypes(jw, fiList, as); apiFinishOutput(0, NULL, jw); } /* static void hubSchemaJsonOutput(FILE *f, char *hubUrl, * char *genome, char *track) */ static void schemaJsonOutput(FILE *f, char *db, char *track) /* for given db and track, output the schema for the associated table */ { struct sqlConnection *conn = hAllocConnMaybe(db); if (NULL == conn) apiErrAbort(err400, err400Msg, "can not find 'genome=%s' for endpoint '/list/schema", db); struct trackDb *tdb = obtainTdb(NULL, db); struct trackDb *thisTrack = findTrackDb(track, tdb); -if (NULL == thisTrack) +if (NULL == thisTrack) /* OK to work with tables without trackDb definitions */ + { + if (! sqlTableExists(conn, track)) apiErrAbort(err400, err400Msg, "failed to find specified track=%s in genome=%s for endpoint '/list/schema'", track, db); + } +/* in case of no trackDb, be wary of trying to use it */ if (thisTrack && (tdbIsComposite(thisTrack) || tdbIsCompositeView(thisTrack))) apiErrAbort(err400, err400Msg, "container track '%s' does not contain data, use the children of this container for data access", track); - char *sqlTableName = cloneString(track); /* the trackDb might have a specific table defined instead */ char *tableName = trackDbSetting(thisTrack, "table"); if (isNotEmpty(tableName)) { freeMem(sqlTableName); sqlTableName = cloneString(tableName); } /* this function knows how to deal with split chromosomes, the NULL * here for the chrom name means to use the first chrom name in chromInfo */ struct hTableInfo *hti = hFindTableInfoWithConn(conn, NULL, sqlTableName); /* check if table name needs to be modified */ char *splitTableName = NULL; @@ -398,42 +441,46 @@ struct asColumn *columnEl = as->columnList; int asColumnCount = slCount(columnEl); char *dataTime = sqlTableUpdate(conn, splitTableName); time_t dataTimeStamp = sqlDateToUnixTime(dataTime); replaceChar(dataTime, ' ', 'T'); /* ISO 8601 */ struct jsonWrite *jw = apiStartOutput(); jsonWriteString(jw, "genome", db); jsonWriteString(jw, "track", track); jsonWriteString(jw, "dataTime", dataTime); jsonWriteNumber(jw, "dataTimeStamp", (long long)dataTimeStamp); freeMem(dataTime); long long itemCount = 0; +/* do not show counts for protected data */ +if (! trackDbSetting(thisTrack, "tableBrowser")) + { char query[2048]; sqlSafef(query, sizeof(query), "select count(*) from %s", splitTableName); -itemCount = sqlQuickNum(conn, query); if (hti && hti->isSplit) /* punting on split table item count */ itemCount = 0; else { itemCount = sqlQuickNum(conn, query); - jsonWriteNumber(jw, "itemCount", itemCount); + } } hFreeConn(&conn); +outputTrackDbVars(jw, thisTrack, itemCount); + if (hti && (hti->isSplit || debug)) jsonWriteBoolean(jw, "splitTable", hti->isSplit); outputSchema(thisTrack, jw, columnNames, columnTypes, jsonTypes, hti, columnCount, asColumnCount, columnEl); apiFinishOutput(0, NULL, jw); } /* static void schemaJsonOutput(FILE *f, char *db, char *track) */ static void chromInfoJsonOutput(FILE *f, char *db) /* for given db, if there is a track, list the chromosomes in that track, * for no track, simply list the chromosomes in the sequence */ { @@ -594,69 +641,40 @@ } return itemCount; } static void recursiveTrackList(struct jsonWrite *jw, struct trackDb *tdb, char *db) /* output trackDb tags only for real tracks, not containers, * recursive when subtracks exist */ { boolean isContainer = tdbIsComposite(tdb) || tdbIsCompositeView(tdb); /* do *NOT* print containers when 'trackLeavesOnly' requested */ if (! (trackLeavesOnly && isContainer) ) { - boolean protectedData = FALSE; long long itemCount = 0; - if (trackDbSetting(tdb, "tableBrowser")) - protectedData = TRUE; - else + /* do not show counts for protected data */ + if (! trackDbSetting(tdb, "tableBrowser")) itemCount = dataItemCount(db, tdb); jsonWriteObjectStart(jw, tdb->track); if (tdbIsComposite(tdb)) jsonWriteString(jw, "compositeContainer", "TRUE"); if (tdbIsCompositeView(tdb)) jsonWriteString(jw, "compositeViewContainer", "TRUE"); - jsonWriteString(jw, "shortLabel", tdb->shortLabel); - jsonWriteString(jw, "type", tdb->type); - jsonWriteString(jw, "longLabel", tdb->longLabel); - jsonWriteNumber(jw, "itemCount", itemCount); - if (tdb->parent) - { - jsonWriteString(jw, "parent", tdb->parent->track); - if (tdb->parent->parent) - jsonWriteString(jw, "parentParent", tdb->parent->parent->track); - } - if (tdb->settingsHash) - { - struct hashEl *hel; - struct hashCookie hc = hashFirst(tdb->settingsHash); - while ((hel = hashNext(&hc)) != NULL) - { - if (sameWord("track", hel->name)) - continue; // already output in header - if (sameWord("tableBrowser", hel->name)) - jsonWriteBoolean(jw, "protectedData", TRUE); - else if (isEmpty((char *)hel->val)) - jsonWriteString(jw, hel->name, "empty"); - else if (protectedData && sameWord(hel->name, "bigDataUrl")) - jsonWriteString(jw, hel->name, "protectedData"); - else - jsonWriteString(jw, hel->name, (char *)hel->val); - } - } + outputTrackDbVars(jw, tdb, itemCount); if (tdb->subtracks) { struct trackDb *el = NULL; for (el = tdb->subtracks; el != NULL; el = el->next ) recursiveTrackList(jw, el, db); } jsonWriteObjectEnd(jw); } else if (tdb->subtracks) { struct trackDb *el = NULL; for (el = tdb->subtracks; el != NULL; el = el->next ) recursiveTrackList(jw, el, db);