f587148862bf76eb764a550db5d52b00318679fc angie Wed May 29 10:28:10 2019 -0700 Report item counts correctly for big* types whose files are specified in db tables instead of bigDataUrl settings. refs #18869, #23521 diff --git src/hg/hubApi/list.c src/hg/hubApi/list.c index 1db5129..e41e290 100644 --- src/hg/hubApi/list.c +++ src/hg/hubApi/list.c @@ -342,76 +342,105 @@ { if (allowedBigBedType(type)) { struct bbiFile *bbi = NULL; bbi = bigBedFileOpen(bigDataUrl); itemCount = bigBedItemCount(bbi); bbiFileClose(&bbi); } else if (startsWithWord("bigWig", type)) { struct bbiFile *bwf = bigWigFileOpen(bigDataUrl); struct bbiSummaryElement sum = bbiTotalSummary(bwf); itemCount = sum.validCount; bbiFileClose(&bwf); } + // NOTE: htslib does not appear to have a function to extract a count from BAI or TBI (tabix) + // indexes. One could probably be added by adding code similar to samtools' idxstats subcommand, + // But in the meantime, this is not supported for types vcfTabix and bam. } errCatchEnd(errCatch); errCatchFree(&errCatch); return itemCount; } +static long long bbiTableItemCount(struct sqlConnection *conn, char *type, char *tableName) +/* Given a tableName that has a fileName column pointing to big*, bam or vcfTabix files, return the + * total itemCount from all rows (BAM and VCF tables may have one row per chrom). */ +{ +long long itemCount = 0; +char query[2048]; +sqlSafef(query, sizeof query, "select fileName from %s", tableName); +struct sqlResult *sr = sqlGetResult(conn, query); +char **row; +while ((row = sqlNextRow(sr)) != NULL) + { + itemCount += bbiItemCount(row[0], type); + } +sqlFreeResult(&sr); +return itemCount; +} + static long long dataItemCount(char *db, struct trackDb *tdb) /* determine how many items are in this data set */ { boolean isContainer = tdbIsComposite(tdb) || tdbIsCompositeView(tdb); if (trackDbSetting(tdb, "container")) isContainer = TRUE; long long itemCount = 0; if (isContainer) /* containers have no data items */ return itemCount; if (sameWord("downloadsOnly", tdb->type)) return itemCount; char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl"); if (isNotEmpty(bigDataUrl)) itemCount = bbiItemCount(bigDataUrl, tdb->type); else { /* prepare for getting table row count, find table name */ /* the trackDb might have a specific table defined */ char *tableName = trackDbSetting(tdb, "table"); if (isEmpty(tableName)) tableName = trackDbSetting(tdb, "track"); if (isNotEmpty(tableName)) { struct sqlConnection *conn = hAllocConnMaybe(db); if (conn) { + if ((startsWith("big", tdb->type) || + sameString("vcfTabix", tdb->type) || sameString("bam", tdb->type)) && + sqlColumnExists(conn, tableName, "fileName")) + { + itemCount = bbiTableItemCount(conn, tdb->type, tableName); + } + else + { /* punting on split tables, return zero */ struct hTableInfo *hti = hFindTableInfoWithConn(conn, NULL, tableName); if (hti && hti->isSplit) { itemCount = 0; } else { char query[2048]; sqlSafef(query, sizeof(query), "select count(*) from %s", tableName); itemCount = sqlQuickNum(conn, query); } + } hFreeConn(&conn); } } } 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);