cf2bb7881c445dcf901c5b2d770aa90995e18fa7 tdreszer Fri Jun 10 13:19:57 2011 -0700 downloadsOnly tracks will continue to have a 'table' value, even though that is meaningless. This is because CGIs need bullet-proofing. I have done hgTracks, hgTrackUi, hgTables and hgGenome. diff --git src/hg/lib/hdb.c src/hg/lib/hdb.c index c761050..db9aac3 100644 --- src/hg/lib/hdb.c +++ src/hg/lib/hdb.c @@ -833,41 +833,45 @@ tableNames = (struct slName *)hashFindVal(hash, trackName); for (tbl = tableNames; tbl != NULL; tbl = tbl->next) { if (sameString(table, tbl->name)) return TRUE; } return FALSE; } char *hTableForTrack(char *db, char *trackName) /* Return a table for a track in db. Returns one of the split * tables, or main table if not split. * In addition, caches all the tracks and tables in db the first * time it is called (could be many thousand tables). */ { +if (trackName == NULL) + return NULL; struct hash *hash = tableListGetDbHash(db); struct slName *tableNames = NULL; tableNames = (struct slName *)hashFindVal(hash, trackName); if (tableNames != NULL) return tableNames->name; return NULL; } boolean hTableOrSplitExists(char *db, char *track) /* Return TRUE if track table (or split table) exists in db. */ { +if (track == NULL) + return FALSE; if (!hDbExists(db)) return FALSE; struct hash *hash = tableListGetDbHash(db); return (hashLookup(hash, track) != NULL); } void hParseTableName(char *db, char *table, char trackName[HDB_MAX_TABLE_STRING], char chrom[HDB_MAX_CHROM_STRING]) /* Parse an actual table name like "chr17_random_blastzWhatever" into * the track name (blastzWhatever) and chrom (chr17_random). */ /* Note: for the sake of speed, this does not consult chromInfo * because that would be extremely slow for scaffold-based dbs. * Instead this makes some assumptions about chromosome names and split * table names in databases that support split tables, and just parses text. * When chromosome/table name conventions change, this will need an update! */ @@ -3471,34 +3475,38 @@ static boolean trackDataAccessible(char *database, struct trackDb *tdb) /* Return TRUE if data accessible - meaning either it has a bigDataUrl, or the * table exists. */ { return trackDbSetting(tdb, "bigDataUrl") != NULL || hTableForTrack(database, tdb->table) != NULL; } static void addTrackIfDataAccessible(char *database, struct trackDb *tdb, boolean privateHost, struct trackDb **tdbRetList) /* check if a trackDb entry should be included in display, and if so * add it to the list, otherwise free it */ { if ((!tdb->private || privateHost) && trackDataAccessible(database, tdb)) slAddHead(tdbRetList, tdb); -else if (sameWord(tdb->type,"downloadsOnly")) - { - if (sameString(tdb->table,tdb->track)) - tdb->table = NULL; +else if (tdbIsDownloadsOnly(tdb)) + { + // While it would be good to make table NULL, since we should support tracks + // without tables (composties, etc) and even data tracks without tables (bigWigs). + // However, some CGIs still need careful bullet-proofing. I have done so with + // hgTrackUi, hgTracks, hgTable and hgGenome + //if (tdb->table != NULL && sameString(tdb->table,tdb->track)) + // tdb->table = NULL; slAddHead(tdbRetList, tdb); } else trackDbFree(&tdb); } #ifdef UNUSED static void inheritFieldsFromParents(struct trackDb *tdb, struct trackDb *parent) /* Inherit undefined fields (outside of settings) from parent. */ { if (tdb->shortLabel == NULL) tdb->shortLabel = cloneString(parent->shortLabel); if (tdb->type == NULL) tdb->type = cloneString(parent->type); if (tdb->longLabel == NULL) @@ -3686,30 +3694,43 @@ rInheritFields(tdbList); slSort(&tdbList, trackDbCmp); return tdbList; } struct trackDb *hTrackDb(char *db) /* Load tracks associated with current db. * Supertracks are loaded as a trackDb, but are not in the returned list, * but are accessible via the parent pointers of the member tracks. Also, * the supertrack trackDb subtrack fields are not set here (would be * incompatible with the returned list) * Returns list sorted by priority * NOTE: this result is cached, do not free it ! */ { +// FIXME: This is NOT CACHED and should be! Since some callers (e.g. hgTables) consume the list, +// I would suggest: +// 1) static hash by db/hub +// 2) call creates list if not in hash +// 3) static (to this file) routine gives the actual tdb list +// 4) public lib routine that returns fully cloned list +// 5) public lib routine that returns cloned individual tdb complete with up/down inheritance +// UNFORTUNATELY, cloning the memory with prove costly in time as well, because of all the pointers +// to relink. THEREFORE what should be done is to make the tdb list with const ->next pointers and +// force discpline on the callers. Sorts should be by hdb.c routines and any new lists (such as +// hgTables makes) should be via tdbRefs. +// SO we are back to being STALLED because of the volume of work. + // static char *existingDb = NULL; // static struct trackDb *tdbList = NULL; struct trackDb *tdbList = NULL; //if (differentStringNullOk(existingDb, db)) // { tdbList = loadTrackDb(db, NULL); tdbList = trackDbLinkUpGenerations(tdbList); tdbList = trackDbPolishAfterLinkup(tdbList, db); // freeMem(existingDb); // existingDb = cloneString(db); // } return tdbList; } static struct trackDb *loadAndLookupTrackDb(struct sqlConnection *conn,