2770a53d1e8e0e5773020965d19c2499439481ca chmalee Tue Feb 7 13:33:08 2023 -0800 Make hubApi return data from multiple tracks at once. Get trackDb tableBrowser setting working correctly in the api diff --git src/hg/cgilib/cartTrackDb.c src/hg/cgilib/cartTrackDb.c index 36d2a5c..5a906e7 100644 --- src/hg/cgilib/cartTrackDb.c +++ src/hg/cgilib/cartTrackDb.c @@ -48,36 +48,39 @@ char *tbOff = trackDbSetting(tdb, "tableBrowser"); if (useAC && tbOff != NULL && (startsWithWord("off", tbOff) || startsWithWord("noGenome", tbOff) || startsWithWord("tbNoGenome", tbOff))) { slAddHead(&accessControlTrackRefList, slRefNew(tdb)); if (! startsWithWord("off", tbOff)) slAddHead(&newList, tdb); } else slAddHead(&newList, tdb); } slReverse(&newList); list = newList; // Add custom tracks at head of list +if (cart) + { struct customTrack *ctList, *ct; ctList = customTracksParseCart(db, cart, NULL, NULL); for (ct = ctList; ct != NULL; ct = ct->next) { slAddHead(&list, ct->tdb); } + } return list; } static struct grp *makeGroupList(char *db, struct trackDb *trackList, struct grp **pHubGrpList, boolean allTablesOk) /* Get list of groups that actually have something in them. */ { struct grp *groupsAll, *groupList = NULL, *group; struct hash *groupsInTrackList = newHash(0); struct hash *groupsInDatabase = newHash(0); struct trackDb *track; /* Do some error checking for tracks with group names that are not in database. * Warnings at this stage mess up CGIs that may produce text output like hgTables & hgIntegrator, @@ -174,30 +177,45 @@ * If useAccessControl, exclude tracks with 'tableBrowser off' nor tables listed * in the table tableAccessControl. */ { char *db = cartString(cart, "db"); useAC = useAccessControl; struct grp *hubGrpList = NULL; struct trackDb *fullTrackList = getFullTrackList(cart, db, &hubGrpList); boolean allTablesOk = hAllowAllTables() && !trackHubDatabase(db); struct grp *fullGroupList = makeGroupList(db, fullTrackList, &hubGrpList, allTablesOk); if (retFullTrackList != NULL) *retFullTrackList = fullTrackList; if (retFullGroupList != NULL) *retFullGroupList = fullGroupList; } +void cartTrackDbInitForApi(struct cart *cart, char *db, struct trackDb **retFullTrackList, + struct grp **retFullGroupList, boolean useAccessControl) +/* Similar to cartTrackDbInit, but allow cart to be NULL */ +{ +useAC = useAccessControl; +struct grp *hubGrpList = NULL; +struct trackDb *fullTrackList = getFullTrackList(cart, db, &hubGrpList); +boolean allTablesOk = hAllowAllTables() && !trackHubDatabase(db); +struct grp *fullGroupList = makeGroupList(db, fullTrackList, &hubGrpList, allTablesOk); +if (retFullTrackList != NULL) + *retFullTrackList = fullTrackList; +if (retFullGroupList != NULL) + *retFullGroupList = fullGroupList; +} + static char *chopAtFirstDot(char *string) /* Terminate string at first '.' if found. Return string for convenience. */ { char *ptr = strchr(string, '.'); if (ptr != NULL) *ptr = '\0'; return string; } struct accessControl /* Restricted permission settings for a table */ { struct slName *hostList; // List of hosts that are allowed to view this table boolean isNoGenome; // True if it's OK for position range but not genome-wide query }; @@ -249,51 +267,76 @@ if (sqlTableExists(conn, "tableAccessControl")) { struct sqlResult *sr = NULL; char **row = NULL; acHash = newHash(0); char query[1024]; sqlSafef(query, sizeof query, "select name,host from tableAccessControl"); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) acHashAddOneTable(acHash, row[0], chopAtFirstDot(row[1]), FALSE); sqlFreeResult(&sr); } hFreeConn(&conn); } struct slRef *tdbRef; + +// init accessControlTrackRefList +if (!accessControlTrackRefList) + { + boolean oldAC = useAC; + useAC = TRUE; + (void)getFullTrackList(NULL, db, NULL); + useAC = oldAC; + } for (tdbRef = accessControlTrackRefList; tdbRef != NULL; tdbRef = tdbRef->next) { struct trackDb *tdb = tdbRef->val; char *tbOff = cloneString(trackDbSetting(tdb, "tableBrowser")); if (isEmpty(tbOff)) errAbort("accessControlInit bug: tdb for %s does not have tableBrowser setting", tdb->track); // First word is "off" or "noGenome" or "tbNoGenome": char *type = nextWord(&tbOff); boolean isNoGenome = sameString(type, "noGenome"); if (!isNoGenome) - isNoGenome = sameString(type, "tbNoGenome"); // like 'noGenome' but only in the table browser, not the API + isNoGenome = sameString(type, "off") || sameString(type, "tbNoGenome"); // like 'noGenome' but only in the table browser, not the API // since the API does not use this function // Add track table to acHash: acHashAddOneTable(acHash, tdb->table, NULL, isNoGenome); // Remaining words are additional table names to add: char *tbl; while ((tbl = nextWord(&tbOff)) != NULL) acHashAddOneTable(acHash, tbl, NULL, isNoGenome); + // add any subtracks that don't have their own setting overriding us + struct trackDb *subTdb; + for (subTdb = tdb->subtracks; subTdb != NULL; subTdb = subTdb->next) + { + char *subTdbOff = cloneString(trackDbSetting(tdb, "tableBrowser")); + if (!subTdbOff) + acHashAddOneTable(acHash, subTdb->table, NULL, isNoGenome); + else + { + char *subTdbType = nextWord(&subTdbOff); + boolean subTdbIsNoGenome = sameString(subTdbType, "noGenome"); + if (!subTdbIsNoGenome) + subTdbIsNoGenome = sameString(subTdbType, "off") || sameString(subTdbType, "tbNoGenome"); + acHashAddOneTable(acHash, subTdb->table, NULL, subTdbIsNoGenome); + } + } } return acHash; } static struct hash *getCachedAcHash(char *db) /* Returns a hash that maps table names to accessControl, creating it if necessary. */ { static struct hash *dbToAcHash = NULL; if (dbToAcHash == NULL) dbToAcHash = hashNew(0); struct hash *acHash = hashFindVal(dbToAcHash, db); if (acHash == NULL) { acHash = accessControlInit(db); hashAdd(dbToAcHash, db, acHash);