static void showTableFieldsDb(char *db, char *rootTable, boolean withGetButton) /* Put up a little html table with a check box, name, and hopefully * a description for each field in SQL rootTable. */ { struct sqlConnection *conn = NULL; if (!trackHubDatabase(database)) conn = hAllocConn(db); struct trackDb *tdb = findTdbForTable(db, curTrack, rootTable, ctLookupName); struct asObject *asObj = asForTable(conn, rootTable); boolean showItemRgb = FALSE; showItemRgb=bedItemRgb(tdb); /* should we expect itemRgb instead of "reserved" */ struct slName *fieldList; if (isBigBed(database, rootTable, curTrack, ctLookupName)) fieldList = bigBedGetFields(rootTable, conn); else if (isBamTable(rootTable)) fieldList = bamGetFields(); else if (isVcfTable(rootTable, NULL)) fieldList = vcfGetFields(); else { char *table = chromTable(conn, rootTable); fieldList = sqlListFields(conn, table); freez(&table); } showTableFieldsOnList(db, rootTable, asObj, fieldList, showItemRgb, withGetButton); hFreeConn(&conn); }
struct bbiFile *fetchBbiForTrack(struct track *track) /* Fetch bbiFile from track, opening it if it is not already open. */ { struct bbiFile *bbi = track->bbiFile; if (bbi == NULL) { char *fileName = NULL; if (track->parallelLoading) // do not use mysql during parallel fetch { fileName = cloneString(trackDbSetting(track->tdb, "bigDataUrl")); } else { struct sqlConnection *conn = NULL; if (!trackHubDatabase(database)) conn = hAllocConnTrack(database, track->tdb); fileName = bbiNameFromSettingOrTable(track->tdb, conn, track->table); hFreeConn(&conn); } #ifdef USE_GBIB_PWD #include "gbib.c" #endif bbi = track->bbiFile = bigBedFileOpen(fileName); } return bbi; }
int bbExtraFieldIndex(struct trackDb *tdb, char* fieldName) /* return the index of a given extra field from the bbInterval * 0 is the name-field of bigBed and is used as an error code * as this is the default anyways */ { if (fieldName==NULL) return 0; // copied from hgc.c // get .as file for track struct sqlConnection *conn = NULL ; if (!trackHubDatabase(database)) conn = hAllocConnTrack(database, tdb); struct asObject *as = asForTdb(conn, tdb); hFreeConn(&conn); if (as == NULL) return 0; // search for field name, return index if found struct asColumn *col = as->columnList; int ix = 0; for (;col != NULL;col=col->next, ix+=1) if (sameString(col->name, fieldName)) return max(ix-3, 0); // never return a negative value return 0; }
char *showTableField(struct trackDb *track, char *varName, boolean useJoiner) /* Show table control and label. */ { struct slName *name, *nameList = NULL; char *selTable; if (track == NULL) nameList = tablesForDb(findSelDb()); else nameList = cartTrackDbTablesForTrack(database, track, useJoiner); /* Get currently selected table. If it isn't in our list * then revert to first in list. */ selTable = cartUsualString(cart, varName, nameList->name); if (!slNameInListUseCase(nameList, selTable)) selTable = nameList->name; /* Print out label and drop-down list. */ hPrintf("<B>table: </B>"); hPrintf("<SELECT NAME=\"%s\" %s>\n", varName, onChangeTable()); struct trackDb *selTdb = NULL; for (name = nameList; name != NULL; name = name->next) { struct trackDb *tdb = NULL; if (track != NULL) tdb = findTdbForTable(database,track,name->name, ctLookupName); hPrintf("<OPTION VALUE=\"%s\"", name->name); // Disable options for related tables that are noGenome -- if a non-positional table // is selected then we output its entire contents. if (cartTrackDbIsNoGenome(database, name->name) && (track == NULL || differentString(track->table, name->name))) hPrintf(" DISABLED"NO_GENOME_CLASS); else if (sameString(selTable, name->name)) { hPrintf(" SELECTED"); selTdb = tdb; } if (tdb != NULL) if ((curTrack == NULL) || differentWord(tdb->shortLabel, curTrack->shortLabel)) hPrintf(">%s (%s)\n", tdb->shortLabel, name->name); else hPrintf(">%s\n", name->name); else hPrintf(">%s\n", name->name); } hPrintf("</SELECT>\n"); if (!trackHubDatabase(database)) { char *restrictDate = encodeRestrictionDateDisplay(database,selTdb); if (restrictDate) { hPrintf("<A HREF=\'%s\' TARGET=BLANK>restricted until:</A> %s", ENCODE_DATA_RELEASE_POLICY, restrictDate); freeMem(restrictDate); } } return selTable; }
static void printGeneSuggestTrack(struct cartJson *cj, char *db) /* Get the gene track used by hgSuggest for db (defaulting to cart db), or null if * there is none for this assembly. */ { if (isEmpty(db)) db = cartString(cj->cart, "db"); char *track = NULL; if (! trackHubDatabase(db)) track = assemblyGeneSuggestTrack(db); jsonWriteString(cj->jw, "geneSuggestTrack", track); }
struct serverTable *findServer(char *db, boolean isTrans) /* Return server for given database. Db can either be * database name or description. */ { if (trackHubDatabase(db)) { struct serverTable *hubSt = trackHubServerTable(db, isTrans); if (hubSt != NULL) return hubSt; errAbort("Cannot get blat server parameters for track hub with database %s\n", db); } static struct serverTable st; struct sqlConnection *conn = hConnectCentral(); char query[256]; struct sqlResult *sr; char **row; char dbActualName[32]; /* If necessary convert database description to name. */ sqlSafef(query, sizeof(query), "select name from dbDb where name = '%s'", db); if (!sqlExists(conn, query)) { sqlSafef(query, sizeof(query), "select name from dbDb where description = '%s'", db); if (sqlQuickQuery(conn, query, dbActualName, sizeof(dbActualName)) != NULL) db = dbActualName; } /* Do a little join to get data to fit into the serverTable. */ sqlSafef(query, sizeof(query), "select dbDb.name,dbDb.description,blatServers.isTrans" ",blatServers.host,blatServers.port,dbDb.nibPath " "from dbDb,blatServers where blatServers.isTrans = %d and " "dbDb.name = '%s' and dbDb.name = blatServers.db", isTrans, db); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) == NULL) { errAbort("Can't find a server for %s database %s. Click " "<A HREF=\"/cgi-bin/hgBlat?%s&command=start&db=%s\">here</A> " "to reset to default database.", (isTrans ? "translated" : "DNA"), db, cartSidUrlString(cart), hDefaultDb()); } st.db = cloneString(row[0]); st.genome = cloneString(row[1]); st.isTrans = atoi(row[2]); st.host = cloneString(row[3]); st.port = cloneString(row[4]); st.nibDir = hReplaceGbdbSeqDir(row[5], st.db); sqlFreeResult(&sr); hDisconnectCentral(&conn); return &st; }
struct trackDb *hubCollectTracks( char *database, struct grp **pGroupList) /* Generate trackDb structures for all the tracks in attached hubs. * Make grp structures for each hub. Returned group list is reversed. */ { // return the cached copy if it exists static struct trackDb *hubTrackDbs; static struct grp *hubGroups; if (hubTrackDbs != NULL) { if (pGroupList != NULL) *pGroupList = hubGroups; return hubTrackDbs; } struct hubConnectStatus *hub, *hubList = hubConnectGetHubs(); struct trackDb *tdbList = NULL; for (hub = hubList; hub != NULL; hub = hub->next) { if (isEmpty(hub->errorMessage)) { /* error catching in so it won't just abort */ struct errCatch *errCatch = errCatchNew(); if (errCatchStart(errCatch)) { struct trackDb *thisList = hubAddTracks(hub, database); tdbList = slCat(tdbList, thisList); } errCatchEnd(errCatch); if (errCatch->gotError) { warn("%s", errCatch->message->string); hubUpdateStatus( errCatch->message->string, hub); } else { if (!trackHubDatabase(database)) { struct grp *grp = grpFromHub(hub); slAddHead(&hubGroups, grp); } hubUpdateStatus(NULL, hub); } errCatchFree(&errCatch); } } hubTrackDbs = tdbList; if (pGroupList != NULL) *pGroupList = hubGroups; return tdbList; }
void printAllAssemblyListHtmlParm(char *db, struct dbDb *dbList, char *dbCgi, bool allowInactive, char *javascript) /* Prints to stdout the HTML to render a dropdown list containing the list * of assemblies for the current genome to choose from. By default, * this includes only active assemblies with a database (with the * exception of the default assembly, which will be included even * if it isn't active). * param db - The default assembly (the database name) to choose as selected. * If NULL, no default selection. * param allowInactive - if set, print all assemblies for this genome, * even if they're inactive or have no database */ { char *assemblyList[128]; char *values[128]; int numAssemblies = 0; struct dbDb *cur = NULL; char *genome = hGenomeOrArchive(db); char *selAssembly = NULL; if (genome == NULL) #ifdef LOWELAB genome = "Pyrococcus furiosus"; #else genome = "Human"; #endif for (cur = dbList; cur != NULL; cur = cur->next) { /* Only for this genome */ if (!sameWord(genome, cur->genome)) continue; /* Save a pointer to the current assembly */ if (sameWord(db, cur->name)) selAssembly = cur->name; if (allowInactive || ((cur->active || sameWord(cur->name, db)) && (trackHubDatabase(db) || sqlDatabaseExists(cur->name)))) { assemblyList[numAssemblies] = cur->description; values[numAssemblies] = cur->name; numAssemblies++; if (numAssemblies >= ArraySize(assemblyList)) internalErr(); } } cgiMakeDropListFull(dbCgi, assemblyList, values, numAssemblies, selAssembly, javascript); }
static void writeFindPositionInfo(struct jsonWrite *jw, char *db, int taxId, char *hubUrl, char *position) /* Write JSON for the info needed to populate the 'Find Position' section. */ { char *genome = hGenome(db); if (isEmpty(genome)) { jsonWriteStringf(jw, "error", "No genome for db '%s'", db); } else { jsonWriteString(jw, "db", db); jsonWriteNumber(jw, "taxId", taxId); jsonWriteString(jw, "genome", genome); struct slPair *dbOptions = NULL; char genomeLabel[PATH_LEN*4]; if (isNotEmpty(hubUrl)) { struct trackHub *hub = hubConnectGetHub(hubUrl); if (hub == NULL) { jsonWriteStringf(jw, "error", "Can't connect to hub at '%s'", hubUrl); return; } struct dbDb *dbDbList = trackHubGetDbDbs(hub->name); dbOptions = trackHubDbDbToValueLabel(dbDbList); safecpy(genomeLabel, sizeof(genomeLabel), hub->shortLabel); jsonWriteString(jw, "hubUrl", hubUrl); } else { dbOptions = hGetDbOptionsForGenome(genome); safecpy(genomeLabel, sizeof(genomeLabel), genome); } jsonWriteValueLabelList(jw, "dbOptions", dbOptions); jsonWriteString(jw, "genomeLabel", genomeLabel); jsonWriteString(jw, "position", position); char *suggestTrack = NULL; if (! trackHubDatabase(db)) suggestTrack = assemblyGeneSuggestTrack(db); jsonWriteString(jw, "suggestTrack", suggestTrack); char *description = maybeGetDescriptionText(db); //#*** TODO: move jsonStringEscape inside jsonWriteString char *encoded = jsonStringEscape(description); jsonWriteString(jw, "description", encoded); listAssemblyHubs(jw); } }
void cartTrackDbInit(struct cart *cart, struct trackDb **retFullTrackList, struct grp **retFullGroupList, boolean useAccessControl) /* Get lists of all tracks and of groups that actually have tracks in them. * 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; }
static void getUiState(struct cartJson *cj, struct hash *paramHash) /* Write out JSON for hgGateway.js's uiState object using current cart settings. */ { char *db = cartUsualString(cj->cart, "db", hDefaultDb()); char *position = cartUsualString(cart, "position", hDefaultPos(db)); char *hubUrl = NULL; if (trackHubDatabase(db)) { struct trackHub *hub = hubConnectGetHubForDb(db); hubUrl = hub->url; } writeFindPositionInfo(cj->jw, db, hTaxId(db), hubUrl, position); // If cart already has a pix setting, pass that along; otherwise the JS will // set pix according to web browser window width. int pix = cartUsualInt(cj->cart, "pix", 0); if (pix) jsonWriteNumber(cj->jw, "pix", pix); }
void findClosestServer(char **pDb, char **pOrg) /* If db doesn't have a blat server, look for the closest db (or org) that has one, * as hgPcr does. */ { char *db = *pDb, *org = *pOrg; if (trackHubDatabase(db) && (trackHubServerTable(db, FALSE) != NULL)) { *pDb = db; *pOrg = hGenome(db); return; } struct sqlConnection *conn = hConnectCentral(); char query[256]; sqlSafef(query, sizeof(query), "select db from blatServers where db = '%s'", db); if (!sqlExists(conn, query)) { sqlSafef(query, sizeof(query), "select blatServers.db from blatServers,dbDb " "where blatServers.db = dbDb.name and dbDb.genome = '%s'", org); char *db = sqlQuickString(conn, query); if (db == NULL) { sqlSafef(query, sizeof(query), "select blatServers.db from blatServers,dbDb " "where blatServers.db = dbDb.name order by dbDb.orderKey,dbDb.name desc"); char *db = sqlQuickString(conn, query); if (db == NULL) errAbort("central database tables blatServers and dbDb are disjoint/empty"); else { *pDb = db; *pOrg = hGenome(db); } } else { *pDb = db; *pOrg = hGenome(db); } } hDisconnectCentral(&conn); }
struct trackVersion *getTrackVersion(char *database, char *track) // Get most recent trackVersion for given track in given database { boolean trackVersionExists = !trackHubDatabase(database) && hTableExists("hgFixed", "trackVersion"); struct trackVersion *trackVersion = NULL; if (trackVersionExists) { char query[256]; struct sqlConnection *conn = hAllocConn(database); sqlSafef(query, sizeof(query), "select * from hgFixed.trackVersion where db = '%s' AND name = '%s' order by ix DESC limit 1", database, track); struct sqlResult *sr = sqlGetResult(conn, query); char **row; if ((row = sqlNextRow(sr)) != NULL) trackVersion = trackVersionLoad(row); sqlFreeResult(&sr); hFreeConn(&conn); } return trackVersion; }
void showSchemaBigBed(char *table, struct trackDb *tdb) /* Show schema on bigBed. */ { /* Figure out bigBed file name and open it. Get contents for first chromosome as an example. */ struct sqlConnection *conn = NULL; if (!trackHubDatabase(database)) conn = hAllocConn(database); char *fileName = bigBedFileName(table, conn); struct bbiFile *bbi = bigBedFileOpen(fileName); struct bbiChromInfo *chromList = bbiChromList(bbi); struct lm *lm = lmInit(0); struct bigBedInterval *ivList = getNElements(bbi, chromList, lm, 10); /* Get description of columns, making it up from BED records if need be. */ struct asObject *as = bigBedAsOrDefault(bbi); hPrintf("<B>Database:</B> %s", database); hPrintf(" <B>Primary Table:</B> %s<br>", table); hPrintf("<B>Big Bed File:</B> %s", fileName); if (bbi->version >= 2) { hPrintf("<BR><B>Item Count:</B> "); printLongWithCommas(stdout, bigBedItemCount(bbi)); } hPrintf("<BR>\n"); hPrintf("<B>Format description:</B> %s<BR>", as->comment); /* Put up table that describes fields. */ hTableStart(); hPrintf("<TR><TH>field</TH>"); if (ivList != NULL) hPrintf("<TH>example</TH>"); hPrintf("<TH>description</TH> "); puts("</TR>\n"); struct asColumn *col; int colCount = 0; char *row[bbi->fieldCount]; char startBuf[16], endBuf[16]; if (ivList != NULL) { char *dupeRest = lmCloneString(lm, ivList->rest); /* Manage rest-stomping side-effect */ bigBedIntervalToRow(ivList, chromList->name, startBuf, endBuf, row, bbi->fieldCount); ivList->rest = dupeRest; } for (col = as->columnList; col != NULL; col = col->next) { hPrintf("<TR><TD><TT>%s</TT></TD>", col->name); if (ivList != NULL) hPrintf("<TD>%s</TD>", row[colCount]); hPrintf("<TD>%s</TD></TR>", col->comment); ++colCount; } /* If more fields than descriptions put up minimally helpful info (at least has example). */ for ( ; colCount < bbi->fieldCount; ++colCount) { hPrintf("<TR><TD><TT>column%d</TT></TD>", colCount+1); if (ivList != NULL) hPrintf("<TD>%s</TD>", row[colCount]); hPrintf("<TD>n/a</TD></TR>\n"); } hTableEnd(); if (ivList != NULL) { /* Put up another section with sample rows. */ webNewSection("Sample Rows"); hTableStart(); /* Print field names as column headers for example */ hPrintf("<TR>"); int colIx = 0; for (col = as->columnList; col != NULL; col = col->next) { hPrintf("<TH>%s</TH>", col->name); ++colIx; } for (; colIx < colCount; ++colIx) hPrintf("<TH>column%d</TH>", colIx+1); hPrintf("</TR>\n"); /* Print sample lines. */ struct bigBedInterval *iv; for (iv=ivList; iv != NULL; iv = iv->next) { bigBedIntervalToRow(iv, chromList->name, startBuf, endBuf, row, bbi->fieldCount); hPrintf("<TR>"); for (colIx=0; colIx<colCount; ++colIx) { writeHtmlCell(row[colIx]); } hPrintf("</TR>\n"); } hTableEnd(); } printTrackHtml(tdb); /* Clean up and go home. */ lmCleanup(&lm); bbiFileClose(&bbi); freeMem(fileName); hFreeConn(&conn); }
void showSchemaBam(char *table, struct trackDb *tdb) /* Show schema on bam. */ { struct sqlConnection *conn = NULL; if (!trackHubDatabase(database)) conn = hAllocConn(database); char *fileName = bamFileName(table, conn, NULL); struct asObject *as = bamAsObj(); hPrintf("<B>Database:</B> %s", database); hPrintf(" <B>Primary Table:</B> %s<br>", table); hPrintf("<B>BAM File:</B> %s", fileName); hPrintf("<BR>\n"); hPrintf("<B>Format description:</B> %s<BR>", as->comment); hPrintf("See the <A HREF=\"%s\" target=_blank>SAM Format Specification</A> for more details<BR>\n", "http://samtools.sourceforge.net/SAM1.pdf"); /* Put up table that describes fields. */ hTableStart(); hPrintf("<TR><TH>field</TH>"); hPrintf("<TH>description</TH> "); puts("</TR>\n"); struct asColumn *col; int colCount = 0; for (col = as->columnList; col != NULL; col = col->next) { hPrintf("<TR><TD><TT>%s</TT></TD>", col->name); hPrintf("<TD>%s</TD></TR>", col->comment); ++colCount; } hTableEnd(); /* Put up another section with sample rows. */ webNewSection("Sample Rows"); hTableStart(); /* Print field names as column headers for example */ hPrintf("<TR>"); int colIx = 0; for (col = as->columnList; col != NULL; col = col->next) { hPrintf("<TH>%s</TH>", col->name); ++colIx; } hPrintf("</TR>\n"); /* Fetch sample rows. */ samfile_t *fh = bamOpen(fileName, NULL); struct lm *lm = lmInit(0); struct samAlignment *sam, *samList = bamReadNextSamAlignments(fh, 10, lm); /* Print sample lines. */ char *row[SAMALIGNMENT_NUM_COLS]; char numBuf[BAM_NUM_BUF_SIZE]; for (sam=samList; sam != NULL; sam = sam->next) { samAlignmentToRow(sam, numBuf, row); hPrintf("<TR>"); for (colIx=0; colIx<colCount; ++colIx) { hPrintf("<TD>"); xmlEscapeStringToFile(row[colIx], stdout); hPrintf("</TD>"); } hPrintf("</TR>\n"); } hTableEnd(); printTrackHtml(tdb); /* Clean up and go home. */ bamClose(&fh); lmCleanup(&lm); freeMem(fileName); hFreeConn(&conn); }
void configMultiRegionPage() /* Do multi-region config page after setting track visibility. If vis is -2, then visibility * is unchanged. If -1 then set visibility to default, otherwise it should * be tvHide, tvDense, etc. */ { char *groupTarget; struct track *trackList; struct track *ideoTrack; struct group *groupList; int vis = -2; configInitTrackList(vis, &groupTarget, &trackList, &ideoTrack, &groupList); hPrintf("<FORM ACTION=\"%s\" NAME=\"mainForm\" METHOD=%s>\n", hgTracksName(), cartUsualString(cart, "formMethod", "POST")); webStartWrapperDetailedNoArgs(cart, database, "", "", FALSE, FALSE, FALSE, FALSE); cartSaveSession(cart); hPrintf("<BR>\n"); hTableStart(); virtModeType = cartUsualString(cart, "virtModeType", virtModeType); hPrintf("<TR><TD>"); cgiMakeRadioButton("virtModeType", "default", sameWord("default", virtModeType)); hPrintf("</TD><TD>"); hPrintf("Exit multi-region mode"); hPrintf("</TD></TR>\n"); struct sqlConnection *conn = NULL; if (!trackHubDatabase(database)) // no db conn for assembly hubs conn = hAllocConn(database); // Do we have a gene table for exonMostly? findBestEMGeneTable(trackList); if (emGeneTable) { hPrintf("<TR><TD>"); cgiMakeRadioButton("virtModeType", "exonMostly", sameWord("exonMostly", virtModeType)); hPrintf("</TD><TD>"); hPrintf("Show exons using %s. Use padding of: ", emGeneTrack->shortLabel); hIntVar("emPadding", cartUsualInt(cart, "emPadding", emPadding), 3); hPrintf(" bases."); hPrintf("</TD></TR>\n"); } if (emGeneTable) { hPrintf("<TR><TD>"); cgiMakeRadioButton("virtModeType", "geneMostly", sameWord("geneMostly", virtModeType)); hPrintf("</TD><TD>"); hPrintf("Show genes using %s. Use padding of: ", emGeneTrack->shortLabel); hIntVar("gmPadding", cartUsualInt(cart, "gmPadding", gmPadding), 3); hPrintf(" bases."); hPrintf("</TD></TR>\n"); } /* obsolete if (conn && sqlTableExists(conn,"knownCanonical")) { hPrintf("<TR><TD>"); cgiMakeRadioButton("virtModeType", "kcGenes", sameWord("kcGenes", virtModeType)); hPrintf("</TD><TD>"); hPrintf("Show gene regions genome-wide."); hPrintf("</TD></TR>\n"); } */ hPrintf("<TR><TD>"); cgiMakeRadioButton("virtModeType", "customUrl", sameWord("customUrl", virtModeType)); hPrintf("</TD><TD>"); hPrintf("Enter Custom regions as BED, or a URL to them:<br>"); multiRegionsBedUrl = cartUsualString(cart, "multiRegionsBedUrl", multiRegionsBedUrl); struct dyString *dyMultiRegionsBedInput = dyStringNew(256); if (strstr(multiRegionsBedUrl,"://")) { dyStringAppend(dyMultiRegionsBedInput, multiRegionsBedUrl); } else { if (fileExists(multiRegionsBedUrl)) { struct lineFile *lf = lineFileMayOpen(multiRegionsBedUrl, TRUE); char *line; int lineSize; while (lineFileNext(lf, &line, &lineSize)) { dyStringPrintf(dyMultiRegionsBedInput, "%s\n", line); } lineFileClose(&lf); } } hPrintf("<TEXTAREA NAME='multiRegionsBedInput' ID='multiRegionsBedInput' rows='4' cols='58' style='white-space: pre;'>%s</TEXTAREA>", dyMultiRegionsBedInput->string); hPrintf("</TD></TR>\n"); /* The AllChroms option will be released in future if (emGeneTable && sqlTableExists(conn, emGeneTable)) { hPrintf("<TR><TD>"); cgiMakeRadioButton("virtModeType", "singleTrans", sameWord("singleTrans", virtModeType)); hPrintf("</TD><TD>"); hPrintf("Show only one transcript using an ID from %s : ", emGeneTrack->shortLabel); char *trans = cartUsualString(cart, "singleTransId", singleTransId); char sql[1024]; sqlSafef(sql, sizeof sql, "select name from %s where name='%s'", emGeneTable, trans); char *result = sqlQuickString(conn, sql); if (!result) { sqlSafef(sql, sizeof sql, "select name from %s limit 1", emGeneTable); trans = sqlQuickString(conn, sql); } hTextVar("singleTransId", trans, 20); hPrintf("</TD></TR>\n"); } */ if (conn) { boolean altLocExists = sqlTableExists(conn, "altLocations"); boolean fixLocExists = sqlTableExists(conn, "fixLocations"); if (altLocExists || fixLocExists) { hPrintf("<TR><TD>"); cgiMakeRadioButton("virtModeType", "singleAltHaplo", sameWord("singleAltHaplo", virtModeType)); hPrintf("</TD><TD>"); hPrintf("Show one alternate haplotype"); if (fixLocExists) hPrintf(" or fix patch"); hPrintf(", placed on its chromosome, using ID: "); char *haplo = cartUsualString(cart, "singleAltHaploId", singleAltHaploId); char *foundHaplo = NULL; char sql[1024]; if (altLocExists) { sqlSafef(sql, sizeof sql, "select name from altLocations where name rlike '^%s(:[0-9-]+)?'", haplo); foundHaplo = sqlQuickString(conn, sql); } if (!foundHaplo && fixLocExists) { sqlSafef(sql, sizeof sql, "select name from fixLocations where name rlike '^%s(:[0-9-]+)?'", haplo); foundHaplo = sqlQuickString(conn, sql); } if (!foundHaplo) { if (altLocExists) sqlSafef(sql, sizeof sql, "select name from altLocations limit 1"); else sqlSafef(sql, sizeof sql, "select name from fixLocations limit 1"); haplo = sqlQuickString(conn, sql); chopSuffixAt(haplo, ':'); } hTextVar("singleAltHaploId", haplo, 60); hPrintf("</TD></TR>\n"); } } /* disable demo for now if (sameString(database,"hg19") || sameString(database, "hg38")) { hPrintf("<TR><TD>"); cgiMakeRadioButton("virtModeType", "demo1", sameWord("demo1", virtModeType)); hPrintf("</TD><TD>"); hPrintf("demo1 two windows on two chroms (default pos on chr21, and same loc on chr22)"); hPrintf("</TD></TR>\n"); } */ /* Disabled for now hPrintf("<TR><TD>"); cgiMakeRadioButton("virtModeType", "demo2", sameWord("demo2", virtModeType)); hPrintf("</TD><TD>"); hPrintf("demo2 multiple "); hIntVar("demo2NumWindows", cartUsualInt(cart, "demo2NumWindows", demo2NumWindows), 3); hPrintf(" windows on one chrom chr21 def posn, window size "); hIntVar("demo2WindowSize", cartUsualInt(cart, "demo2WindowSize", demo2WindowSize), 3); hPrintf(" and step size "); hIntVar("demo2StepSize", cartUsualInt(cart, "demo2StepSize", demo2StepSize), 3); hPrintf(" exon-like"); hPrintf("</TD></TR>\n"); */ /* The AllChroms option will be released in future if (conn) // requires chromInfo from database. { // TODO allow it to use assembly hubs via trackHubAllChromInfo() ? hPrintf("<TR><TD>"); cgiMakeRadioButton("virtModeType", "allChroms", sameWord("allChroms", virtModeType)); hPrintf("</TD><TD>"); hPrintf("<br>Show all chromosomes.<br><span style='color:red'>Warning:</span> Turn off all tracks except bigBed, bigWig, and very sparse tracks.<br>Press Hide All to hide all tracks."); hPrintf("</TD></TR>\n"); } */ /* Disabled for now hPrintf("<TR><TD>"); cgiMakeRadioButton("virtModeType", "demo4", sameWord("demo4", virtModeType)); hPrintf("</TD><TD>"); hPrintf("demo4 multiple (311) windows showing exons from TITIN gene uc031rqd.1."); hPrintf("</TD></TR>\n"); */ /* Disabled for now hPrintf("<TR><TD>"); cgiMakeRadioButton("virtModeType", "demo5", sameWord("demo5", virtModeType)); hPrintf("</TD><TD>"); hPrintf("demo5 alt locus on hg38. Shows alt chrom surrounded by regions of same size from reference genome."); hPrintf("</TD></TR>\n"); */ /* Disabled for now hPrintf("<TR><TD>"); cgiMakeRadioButton("virtModeType", "demo6", sameWord("demo6", virtModeType)); hPrintf("</TD><TD>"); hPrintf("demo6 shows zoomed in exon-exon junction from SOD1 gene, between exon1 and exon2."); hPrintf("</TD></TR>\n"); */ hTableEnd(); hPrintf("<BR>\n"); hPrintf("<TABLE style=\"border:0px; \">\n"); hPrintf("<TR><TD>"); hCheckBox("emAltHighlight", cartUsualBoolean(cart, "emAltHighlight", FALSE)); hPrintf("</TD><TD>"); hPrintf("Highlight alternating regions in multi-region view"); hPrintf("</TD></TR>\n"); hPrintf("</TABLE>\n"); hPrintf("<BR>\n"); hPrintf("<TABLE style=\"border:0px;width:650px \">\n"); hPrintf("<TR><TD>"); cgiMakeButton("topSubmit", "submit"); hPrintf("</TD><TD align=right>"); hPrintf("<A HREF=\"../goldenPath/help/multiRegionHelp.html\" target=_blank>Help</A>\n"); hPrintf("</TD></TR>\n"); hPrintf("</TABLE>\n"); hFreeConn(&conn); cgiDown(0.9); freez(&groupTarget); webEndSectionTables(); hPrintf("</FORM>"); }
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; /* Stream through track list building up hash of active groups. */ for (track = trackList; track != NULL; track = track->next) { if (!hashLookup(groupsInTrackList,track->grp)) hashAdd(groupsInTrackList, track->grp, NULL); } /* Scan through group table, putting in ones where we have data. */ groupsAll = hLoadGrps(db); for (group = slPopHead(&groupsAll); group != NULL; group = slPopHead(&groupsAll)) { if (hashLookup(groupsInTrackList, group->name)) { slAddTail(&groupList, group); hashAdd(groupsInDatabase, group->name, group); } else grpFree(&group); } /* if we have custom tracks, we want to add the track hubs * after that group */ struct grp *addAfter = NULL; if ((groupList != NULL) && sameString(groupList->name, "user")) addAfter = groupList; /* Add in groups from hubs. */ for (group = slPopHead(pHubGrpList); group != NULL; group = slPopHead(pHubGrpList)) { // if the group isn't represented in any track, don't add it to list if (!hashLookup(groupsInTrackList,group->name)) continue; /* check to see if we're inserting hubs rather than * adding them to the front of the list */ struct grp *newGrp = grpDup(group); if (addAfter != NULL) { newGrp->next = addAfter->next; addAfter->next = newGrp; } else slAddHead(&groupList, newGrp); hashAdd(groupsInDatabase, newGrp->name, newGrp); } /* Do some error checking for tracks with group names that are * not in database. Just warn about them. */ if (!trackHubDatabase(db)) for (track = trackList; track != NULL; track = track->next) { if (!hashLookup(groupsInDatabase, track->grp)) warn("Track %s has group %s, which isn't in grp table", track->table, track->grp); } /* Create dummy group for all tracks. */ AllocVar(group); group->name = cloneString("allTracks"); group->label = cloneString("All Tracks"); slAddTail(&groupList, group); /* Create another dummy group for all tables. */ if (allTablesOk) { AllocVar(group); group->name = cloneString("allTables"); group->label = cloneString("All Tables"); slAddTail(&groupList, group); } hashFree(&groupsInTrackList); hashFree(&groupsInDatabase); return groupList; }
static void filterControlsForTableDb(char *db, char *rootTable) /* Put up filter controls for a single database table. */ { struct sqlConnection *conn = NULL; if (!trackHubDatabase(db)) conn = hAllocConn(db); char *table = chromTable(conn, rootTable); struct trackDb *tdb = findTdbForTable(db, curTrack, rootTable, ctLookupName); boolean isSmallWig = isWiggle(db, table); boolean isBigWig = tdb ? tdbIsBigWig(tdb) : isBigWigTable(table); boolean isWig = isSmallWig || isBigWig; boolean isBedGr = tdb ? tdbIsBedGraph(tdb) : isBedGraph(rootTable); boolean isBb = tdb ? tdbIsBigBed(tdb) : isBigBed(database, table, curTrack, ctLookupName); boolean isBam = tdb ? tdbIsBam(tdb) : isBamTable(rootTable); boolean isVcf = tdb ? tdbIsVcf(tdb) : isVcfTable(rootTable, NULL); int bedGraphColumn = 5; /* default score column */ if (isBedGr) { int wordCount; char *words[8]; char *typeLine = cloneString(tdb->type); wordCount = chopLine(typeLine,words); if (wordCount > 1) bedGraphColumn = sqlUnsigned(words[1]); freez(&typeLine); } if (isWig) { hPrintf("<TABLE BORDER=0>\n"); if ((tdb != NULL) && (tdb->type != NULL)) { double min, max; wiggleMinMax(tdb,&min,&max); numericFilterWithLimits(db, rootTable, filterDataValueVar,filterDataValueVar,min,max,""); hPrintf("<TR><TD COLSPAN=3 ALIGN=RIGHT> (dataValue range: [%g:%g]) " "</TD></TR></TABLE>\n", min, max); } else { numericFilter(db, rootTable, filterDataValueVar,filterDataValueVar, ""); hPrintf("</TABLE>\n"); } } else { struct sqlFieldType *ftList; if (isBb) ftList = bigBedListFieldsAndTypes(tdb, conn); else if (isBam) ftList = bamListFieldsAndTypes(); else if (isVcf) ftList = vcfListFieldsAndTypes(); else ftList = sqlListFieldsAndTypes(conn, table); printSqlFieldListAsControlTable(ftList, db, rootTable, tdb, isBedGr); } /* Printf free-form query row. */ if (!(isWig||isBedGr||isBam||isVcf)) { char *name; hPrintf("<TABLE BORDER=0><TR><TD>\n"); name = filterFieldVarName(db, rootTable, "", filterRawLogicVar); cgiMakeDropList(name, logOpMenu, logOpMenuSize, cartUsualString(cart, name, logOpMenu[0])); hPrintf(" Free-form query: "); name = filterFieldVarName(db, rootTable, "", filterRawQueryVar); char *val = cartUsualString(cart, name, ""); // escape double quotes to avoid HTML parse trouble in the text input. val = htmlEncodeText(val, FALSE); cgiMakeTextVar(name, val, 50); hPrintf("</TD></TR></TABLE>\n"); } if (isWig||isBedGr||isBam||isVcf) { char *name; hPrintf("<TABLE BORDER=0><TR><TD> Limit data output to: \n"); name = filterFieldVarName(db, rootTable, "_", filterMaxOutputVar); cgiMakeDropList(name, maxOutMenu, maxOutMenuSize, cartUsualString(cart, name, maxOutMenu[0])); hPrintf(" lines</TD></TR></TABLE>\n"); } freez(&table); hFreeConn(&conn); hPrintf("<BR>\n"); cgiMakeButton(hgtaDoFilterSubmit, "submit"); hPrintf(" "); cgiMakeButton(hgtaDoMainPage, "cancel"); }
void showMainControlTable(struct sqlConnection *conn) /* Put up table with main controls for main page. */ { struct grp *selGroup; boolean isWig = FALSE, isPositional = FALSE, isMaf = FALSE, isBedGr = FALSE, isChromGraphCt = FALSE, isPal = FALSE, isArray = FALSE, isBam = FALSE, isVcf = FALSE, isHalSnake = FALSE, isLongTabix = FALSE; boolean gotClade = hGotClade(); struct hTableInfo *hti = NULL; hPrintf("<TABLE BORDER=0>\n"); /* Print clade, genome and assembly line. */ { if (gotClade) { hPrintf("<TR><TD><B>clade:</B>\n"); printCladeListHtml(hGenome(database), onChangeClade()); nbSpaces(3); hPrintf("<B>genome:</B>\n"); printGenomeListForCladeHtml(database, onChangeOrg()); } else { hPrintf("<TR><TD><B>genome:</B>\n"); printGenomeListHtml(database, onChangeOrg()); } nbSpaces(3); hPrintf("<B>assembly:</B>\n"); printAssemblyListHtml(database, onChangeDb()); hPrintf("</TD></TR>\n"); } /* Print group and track line. */ { hPrintf("<TR><TD>"); selGroup = showGroupField(hgtaGroup, onChangeGroupOrTrack(), conn, hAllowAllTables()); nbSpaces(3); curTrack = showTrackField(selGroup, hgtaTrack, onChangeGroupOrTrack(), FALSE); nbSpaces(3); boolean hasCustomTracks = FALSE; struct trackDb *t; for (t = fullTrackList; t != NULL; t = t->next) { if (isCustomTrack(t->table)) { hasCustomTracks = TRUE; break; } } hOnClickButton("document.customTrackForm.submit();return false;", hasCustomTracks ? CT_MANAGE_BUTTON_LABEL : CT_ADD_BUTTON_LABEL); hPrintf(" "); if (hubConnectTableExists()) hOnClickButton("document.trackHubForm.submit();return false;", "track hubs"); hPrintf("</TD></TR>\n"); } /* Print table line. */ { hPrintf("<TR><TD>"); curTable = showTableField(curTrack, hgtaTable, TRUE); if (isHubTrack(curTable) || (strchr(curTable, '.') == NULL)) /* In same database */ { hti = getHti(database, curTable, conn); isPositional = htiIsPositional(hti); } isLongTabix = isLongTabixTable( curTable); isBam = isBamTable( curTable); isVcf = isVcfTable(curTable, NULL); isWig = isWiggle(database, curTable); if (isBigWigTable(curTable)) { isPositional = TRUE; isWig = TRUE; } isHalSnake = isHalTable( curTable); isMaf = isMafTable(database, curTrack, curTable); isBedGr = isBedGraph(curTable); isArray = isMicroarray(curTrack, curTable); struct trackDb *tdb = findTdbForTable(database, curTrack, curTable, ctLookupName); isPal = isPalCompatible(conn, tdb, curTable); nbSpaces(1); if (isCustomTrack(curTable)) { isChromGraphCt = isChromGraph(tdb); } cgiMakeButton(hgtaDoSchema, "describe table schema"); hPrintf("</TD></TR>\n"); } if (curTrack == NULL) { struct trackDb *tdb = hTrackDbForTrack(database, curTable); struct trackDb *cTdb = hCompositeTrackDbForSubtrack(database, tdb); if (cTdb) curTrack = cTdb; else curTrack = tdb; isMaf = isMafTable(database, curTrack, curTable); } /* Region line */ { char *regionType = cartUsualString(cart, hgtaRegionType, hgtaRegionTypeGenome); char *range = cartUsualString(cart, hgtaRange, ""); if (isPositional) { boolean doEncode = FALSE; if (!trackHubDatabase(database)) doEncode = sqlTableExists(conn, "encodeRegions"); hPrintf("<TR><TD><B>region:</B>\n"); /* If regionType not allowed force it to "genome". */ if ((sameString(regionType, hgtaRegionTypeUserRegions) && userRegionsFileName() == NULL) || (sameString(regionType, hgtaRegionTypeEncode) && !doEncode)) regionType = hgtaRegionTypeGenome; // Is "genome" is not allowed because of tdb 'tableBrowser noGenome'? boolean disableGenome = ((curTrack && cartTrackDbIsNoGenome(database, curTrack->table)) || (curTable && cartTrackDbIsNoGenome(database, curTable))); // If "genome" is selected but not allowed, force it to "range": if (sameString(regionType, hgtaRegionTypeGenome) && disableGenome) regionType = hgtaRegionTypeRange; jsTrackingVar("regionType", regionType); if (disableGenome) { makeRegionButtonExtraHtml(hgtaRegionTypeGenome, regionType, "DISABLED"); hPrintf(" <span"NO_GENOME_CLASS">genome (unavailable for selected track)</span>" " "); } else { makeRegionButton(hgtaRegionTypeGenome, regionType); hPrintf(" genome "); } if (doEncode) { makeRegionButton(hgtaRegionTypeEncode, regionType); hPrintf(" ENCODE Pilot regions "); } makeRegionButton(hgtaRegionTypeRange, regionType); hPrintf(" position "); hPrintf("<INPUT TYPE=TEXT NAME=\"%s\" SIZE=26 VALUE=\"%s\" onFocus=\"%s\">\n", hgtaRange, range, jsRadioUpdate(hgtaRegionType, "regionType", "range")); cgiMakeButton(hgtaDoLookupPosition, "lookup"); hPrintf(" "); if (userRegionsFileName() != NULL) { makeRegionButton(hgtaRegionTypeUserRegions, regionType); hPrintf(" defined regions "); cgiMakeButton(hgtaDoSetUserRegions, "change"); hPrintf(" "); cgiMakeButton(hgtaDoClearUserRegions, "clear"); } else cgiMakeButton(hgtaDoSetUserRegions, "define regions"); hPrintf("</TD></TR>\n"); } else { /* Need to put at least stubs of cgi variables in for JavaScript to work. */ jsTrackingVar("regionType", regionType); cgiMakeHiddenVar(hgtaRange, range); cgiMakeHiddenVar(hgtaRegionType, regionType); } /* Select identifiers line (if applicable). */ if (!isWig && getIdField(database, curTrack, curTable, hti) != NULL) { hPrintf("<TR><TD><B>identifiers (names/accessions):</B>\n"); cgiMakeButton(hgtaDoPasteIdentifiers, "paste list"); hPrintf(" "); cgiMakeButton(hgtaDoUploadIdentifiers, "upload list"); if (identifierFileName() != NULL) { hPrintf(" "); cgiMakeButton(hgtaDoClearIdentifiers, "clear list"); } hPrintf("</TD></TR>\n"); } } /* microarray options */ /* button for option page here (median/log-ratio, etc) */ /* Filter line. */ { hPrintf("<TR><TD><B>filter:</B>\n"); if (anyFilter()) { cgiMakeButton(hgtaDoFilterPage, "edit"); hPrintf(" "); cgiMakeButton(hgtaDoClearFilter, "clear"); if (isWig || isBedGr) wigShowFilter(conn); } else { cgiMakeButton(hgtaDoFilterPage, "create"); } hPrintf("</TD></TR>\n"); } /* Composite track subtrack merge line. */ boolean canSubtrackMerge = (curTrack && tdbIsComposite(curTrack) && !isBam && !isVcf && !isLongTabix); if (canSubtrackMerge) { hPrintf("<TR><TD><B>subtrack merge:</B>\n"); if (anySubtrackMerge(database, curTable)) { cgiMakeButton(hgtaDoSubtrackMergePage, "edit"); hPrintf(" "); cgiMakeButton(hgtaDoClearSubtrackMerge, "clear"); } else { cgiMakeButton(hgtaDoSubtrackMergePage, "create"); } hPrintf("</TD></TR>\n"); } /* Intersection line. */ if (isPositional) { if (anyIntersection()) { hPrintf("<TR><TD><B>intersection with %s:</B>\n", cartString(cart, hgtaIntersectTable)); cgiMakeButton(hgtaDoIntersectPage, "edit"); hPrintf(" "); cgiMakeButton(hgtaDoClearIntersect, "clear"); hPrintf("</TD></TR>\n"); } else if (canIntersect(database, curTable)) { hPrintf("<TR><TD><B>intersection:</B>\n"); cgiMakeButton(hgtaDoIntersectPage, "create"); hPrintf("</TD></TR>\n"); } } /* Correlation line. */ struct trackDb *tdb = findTdbForTable(database, curTrack, curTable, ctLookupName); if (correlateTrackTableOK(tdb, curTable)) { char *table2 = cartUsualString(cart, hgtaCorrelateTable, "none"); hPrintf("<TR><TD><B>correlation:</B>\n"); if (differentWord(table2, "none") && strlen(table2) && ! isNoGenomeDisabled(database, table2)) { struct grp *groupList = fullGroupList; struct grp *selGroup = findSelectedGroup(groupList, hgtaCorrelateGroup); struct trackDb *tdb2 = findSelectedTrack(fullTrackList, selGroup,hgtaCorrelateTrack); if (tdbIsComposite(tdb2)) { struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(tdb2->subtracks); struct slRef *tdbRef; for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next) { struct trackDb *subTdb = tdbRef->val; if (sameString(table2, subTdb->table)) { tdb2 = subTdb; break; } } slFreeList(&tdbRefList); } cgiMakeButton(hgtaDoCorrelatePage, "calculate"); cgiMakeButton(hgtaDoClearCorrelate, "clear"); if (tdb2 && tdb2->shortLabel) hPrintf(" (with: %s)", tdb2->shortLabel); #ifdef NOT_YET /* debugging dbg vvvvv */ if (curTrack && curTrack->type) /* dbg */ { hPrintf("<BR> (debug: '%s', '%s(%s)')", curTrack->type, tdb2->type, table2); } /* debugging debug ^^^^^ */ #endif } else cgiMakeButton(hgtaDoCorrelatePage, "create"); hPrintf("</TD></TR>\n"); } /* Print output type line. */ showOutputTypeRow(isWig, isBedGr, isPositional, isMaf, isChromGraphCt, isPal, isArray, isHalSnake); /* Print output destination line. */ { char *compressType = cartUsualString(cart, hgtaCompressType, textOutCompressNone); char *fileName = cartUsualString(cart, hgtaOutFileName, ""); hPrintf("<TR><TD>\n"); hPrintf("<B>output file:</B> "); cgiMakeTextVar(hgtaOutFileName, fileName, 29); hPrintf(" (leave blank to keep output in browser)</TD></TR>\n"); hPrintf("<TR><TD>\n"); hPrintf("<B>file type returned: </B>"); cgiMakeRadioButton(hgtaCompressType, textOutCompressNone, sameWord(textOutCompressNone, compressType)); hPrintf(" plain text  "); cgiMakeRadioButton(hgtaCompressType, textOutCompressGzip, sameWord(textOutCompressGzip, compressType)); hPrintf(" gzip compressed"); hPrintf("</TD></TR>\n"); } hPrintf("</TABLE>\n"); /* Submit buttons. */ { hPrintf("<BR>\n"); if (isWig || isBam || isVcf || isLongTabix) { char *name; extern char *maxOutMenu[]; char *maxOutput = maxOutMenu[0]; if (isCustomTrack(curTable)) name=filterFieldVarName("ct", curTable, "_", filterMaxOutputVar); else name=filterFieldVarName(database,curTable, "_",filterMaxOutputVar); maxOutput = cartUsualString(cart, name, maxOutMenu[0]); if (isWig) hPrintf( "<I>Note: to return more than %s lines, change the filter setting" " (above). The entire data set may be available for download as" " a very large file that contains the original data values (not" " compressed into the wiggle format) -- see the Downloads page." "</I><BR>", maxOutput); else if (isBam || isVcf || isLongTabix) hPrintf( "<I>Note: to return more than %s lines, change the filter setting" " (above). Please consider downloading the entire data from our Download pages." "</I><BR>", maxOutput); } else if (anySubtrackMerge(database, curTable) || anyIntersection()) { hPrintf("<I>Note: The all fields and selected fields output formats " "are not available when a%s has been specified.</I><BR>", canSubtrackMerge ? " subtrack merge or intersection" : "n intersection"); } cgiMakeButton(hgtaDoTopSubmit, "get output"); hPrintf(" "); if (isPositional || isWig) { cgiMakeButton(hgtaDoSummaryStats, "summary/statistics"); hPrintf(" "); } #ifdef SOMETIMES hPrintf(" "); cgiMakeButton(hgtaDoTest, "test"); #endif /* SOMETIMES */ } hPrintf("<P>" "To reset <B>all</B> user cart settings (including custom tracks), \n" "<A HREF=\"/cgi-bin/cartReset?destination=%s\">click here</A>.\n", getScriptName()); }
static void showLinkedTables(struct joiner *joiner, struct dbTable *inList, char *varPrefix, char *buttonName, char *buttonText) /* Print section with list of linked tables and check boxes to turn them * on. */ { struct dbTable *outList = NULL, *out, *in; char dtName[256]; struct hash *uniqHash = newHash(0); struct hash *inHash = newHash(8); /* Build up list of tables we link to in outList. */ for (in = inList; in != NULL; in = in->next) { struct sqlConnection *conn = NULL; if (!trackHubDatabase(database)) conn = hAllocConn(in->db); struct joinerPair *jpList, *jp; /* Keep track of tables in inList. */ safef(dtName, sizeof(dtName), "%s.%s", inList->db, inList->table); hashAdd(inHash, dtName, NULL); /* First table in input is not allowed in output. */ if (in == inList) hashAdd(uniqHash, dtName, NULL); /* Scan through joining information and add tables, * avoiding duplicate additions. */ jpList = joinerRelate(joiner, in->db, in->table); for (jp = jpList; jp != NULL; jp = jp->next) { safef(dtName, sizeof(dtName), "%s.%s", jp->b->database, jp->b->table); if (!hashLookup(uniqHash, dtName) && !cartTrackDbIsAccessDenied(jp->b->database, jp->b->table)) { hashAdd(uniqHash, dtName, NULL); out = dbTableNew(jp->b->database, jp->b->table); slAddHead(&outList, out); } } joinerPairFreeList(&jpList); hFreeConn(&conn); } slSort(&outList, dbTableCmp); /* Print html. */ if (outList != NULL) { webNewSection("Linked Tables"); hTableStart(); for (out = outList; out != NULL; out = out->next) { struct sqlConnection *conn = hAllocConn(out->db); struct asObject *asObj = asForTable(conn, out->table); char *var = dbTableVar(varPrefix, out->db, out->table); hPrintf("<TR>"); hPrintf("<TD>"); cgiMakeCheckBox(var, varOn(var)); hPrintf("</TD>"); hPrintf("<TD>%s</TD>", out->db); hPrintf("<TD>%s</TD>", out->table); hPrintf("<TD>"); if (asObj != NULL) hPrintf("%s", asObj->comment); else hPrintf(" "); hPrintf("</TD>"); hPrintf("</TR>"); hFreeConn(&conn); } hTableEnd(); hPrintf("<BR>"); cgiMakeButton(buttonName, buttonText); } }