73b1cfe6f896f7830c2286ab0733a97ede5b641d angie Thu Sep 26 17:24:48 2019 -0700 In my previous change to bigBedFind.c, I opened a bbi but forgot to errCatch & close it. So, errCatch & close it; also reuse it instead of reopening it for each index. refs #23283 diff --git src/hg/lib/bigBedFind.c src/hg/lib/bigBedFind.c index a9c0f39..b730d40 100644 --- src/hg/lib/bigBedFind.c +++ src/hg/lib/bigBedFind.c @@ -46,92 +46,89 @@ { // highlight the item bases only, to distinguish from padding hgPos->highlight = addHighlight(cartString(cart, "db"), hgPos->chrom, hgPos->chromStart, hgPos->chromEnd); hgPos->chromStart -= padding; hgPos->chromEnd += padding; if (hgPos->chromStart < 0) hgPos->chromStart = 0; } } } return posList; } -static struct hgPos *getPosFromBigBed(struct cart *cart, struct trackDb *tdb, char *bigDataUrl, +static struct hgPos *getPosFromBigBed(struct cart *cart, struct trackDb *tdb, struct bbiFile *bbi, char *indexField, char *term, char *description, struct hgFindSpec *hfs) /* Given a bigBed file with a search index, check for term. */ { struct errCatch *errCatch = errCatchNew(); struct hgPos *posList = NULL; -struct bbiFile *bbi = NULL; if (errCatchStart(errCatch)) { - bbi = bigBedFileOpen(bigDataUrl); int fieldIx; struct bptFile *bpt = bigBedOpenExtraIndex(bbi, indexField, &fieldIx); struct lm *lm = lmInit(0); struct bigBedInterval *intervalList; intervalList = bigBedNameQuery(bbi, bpt, fieldIx, term, lm); posList = bigBedIntervalListToHgPositions(cart, tdb, bbi, term, intervalList, description, hfs); - bbiFileClose(&bbi); + bptFileDetach(&bpt); } errCatchEnd(errCatch); if (errCatch->gotError) { - bbiFileClose(&bbi); - // we fail silently if bigBed is missing + // we fail silently if there is a problem e.g. bad index name return NULL; } return posList; } static struct hgPos *doTrixSearch(struct cart *cart, struct trackDb *tdb, char *trixFile, - struct slName *indices, char *bigDataUrl, char *term, char *description, + struct slName *indices, struct bbiFile *bbi, char *term, char *description, struct hgFindSpec *hfs) /* search a trix file in the "searchTrix" field of a bigBed trackDb */ { struct trix *trix = trixOpen(trixFile); int trixWordCount = 0; char *tmp = cloneString(term); char *val = nextWord(&tmp); char *trixWords[128]; while (val != NULL) { trixWords[trixWordCount] = strLower(val); trixWordCount++; if (trixWordCount == sizeof(trixWords)/sizeof(char*)) errAbort("exhausted space for trixWords"); val = nextWord(&tmp); } if (trixWordCount == 0) return NULL; struct trixSearchResult *tsList = trixSearch(trix, trixWordCount, trixWords, tsmExpand); struct hgPos *posList = NULL; for ( ; tsList != NULL; tsList = tsList->next) { struct slName *oneIndex = indices; for (; oneIndex; oneIndex = oneIndex->next) { - struct hgPos *posList2 = getPosFromBigBed(cart, tdb, bigDataUrl, oneIndex->name, + struct hgPos *posList2 = getPosFromBigBed(cart, tdb, bbi, oneIndex->name, tsList->itemId, description, hfs); posList = slCat(posList, posList2); } } return posList; } boolean findBigBedPosInTdbList(struct cart *cart, char *db, struct trackDb *tdbList, char *term, struct hgPositions *hgp, struct hgFindSpec *hfs) /* Given a list of trackDb entries, check each of them for a searchIndex */ { char *description = NULL; if (hfs) @@ -147,76 +144,86 @@ boolean found = FALSE; for(tdb=tdbList; tdb; tdb = tdb->next) { if (tdb->subtracks) found = findBigBedPosInTdbList(cart, db, tdbList->subtracks, term, hgp, hfs) || found; char *fileName = trackDbSetting(tdb, "bigDataUrl"); if (!fileName) { struct sqlConnection *conn = hAllocConnTrack(db, tdb); fileName = bbiNameFromSettingOrTable(tdb, conn, tdb->table); hFreeConn(&conn); } if (!fileName) continue; - struct bbiFile *bbi = bigBedFileOpen(fileName); + // we fail silently if bigBed can't be opened. + struct bbiFile *bbi = NULL; + struct errCatch *errCatch = errCatchNew(); + if (errCatchStart(errCatch)) + { + bbi = bigBedFileOpen(fileName); + } + errCatchEnd(errCatch); + if (errCatch->gotError) + continue; // Which field(s) to search? Look for searchIndex in search spec, then in trackDb for // backwards compat. If not found, but there is a name field with index, use that. char *indexField = NULL; if (hfs) indexField = hgFindSpecSetting(hfs, "searchIndex"); if (!indexField) indexField = trackDbSetting(tdb, "searchIndex"); if (!indexField) { struct slName *indexFields = bigBedListExtraIndexes(bbi); if (slNameInList(indexFields, "name")) indexField = "name"; slNameFreeList(&indexFields); } if (!indexField) continue; struct slName *indexList = slNameListFromString(indexField, ','); struct hgPos *posList1 = NULL, *posList2 = NULL; char *trixFile = trackDbSetting(tdb, "searchTrix"); // if there is a trix file, use it to search for the term if (trixFile != NULL) { struct errCatch *errCatch = errCatchNew(); if (errCatchStart(errCatch)) { - posList1 = doTrixSearch(cart, tdb, hReplaceGbdb(trixFile), indexList, fileName, term, + posList1 = doTrixSearch(cart, tdb, hReplaceGbdb(trixFile), indexList, bbi, term, NULL, hfs); } errCatchEnd(errCatch); if (errCatch->gotError) warn("trix search failure for %s: %s", tdb->table, dyStringContents(errCatch->message)); errCatchFree(&errCatch); } // now search for the raw id's struct slName *oneIndex=indexList; for (; oneIndex; oneIndex = oneIndex->next) { - posList2 = getPosFromBigBed(cart, tdb, fileName, oneIndex->name, term, NULL, hfs); + posList2 = getPosFromBigBed(cart, tdb, bbi, oneIndex->name, term, NULL, hfs); posList1 = slCat(posList1, posList2); } if (posList1 != NULL) { struct hgPosTable *table; found = TRUE; AllocVar(table); slAddHead(&hgp->tableList, table); table->description = cloneString(description ? description : tdb->longLabel); table->name = cloneString(tdb->table); table->posList = posList1; } + bigBedFileClose(&bbi); } freeMem(description); return found; }