Esempio n. 1
0
struct bed *getRegionAsBed(
        char *db, char *table,  /* Database and table. */
        struct region *region,  /* Region to get data for. */
        char *filter,           /* Filter to add to SQL where clause if any. */
        struct hash *idHash,    /* Restrict to id's in this hash if non-NULL. */
        struct lm *lm,          /* Where to allocate memory. */
        int *retFieldCount)     /* Number of fields. */
/* Return a bed list of all items in the given range in table.
 * Cleanup result via lmCleanup(&lm) rather than bedFreeList.  */
{
char *fields = NULL;
struct sqlResult *sr;
struct hTableInfo *hti;
struct bed *bedList=NULL, *bed;
char **row;
int fieldCount;
boolean isPsl, isGenePred, isBedWithBlocks;
boolean pslKnowIfProtein = FALSE, pslIsProtein = FALSE;
struct sqlConnection *conn = NULL;
char *dbTable = NULL;

if (isCustomTrack(table))
    {
    struct customTrack *ct = ctLookupName(table);
    dbTable = ct->dbTableName;
    conn = hAllocConn(CUSTOM_TRASH);
    hti = hFindTableInfo(CUSTOM_TRASH, region->chrom, dbTable);
    }
else
    {
    dbTable = table;
    struct trackDb *tdb;
    if(sameWord(db, database))
        tdb = tdbForTrack(db, table, &fullTrackList);
    else
        tdb = hTrackDbForTrack(db, table);
    conn = (tdb ? hAllocConnTrack(db, tdb) : hAllocConn(db));
    hti = hFindTableInfo(db, region->chrom, table);
    }
if (hti == NULL)
    errAbort("Could not find table info for table %s.%s", db,table);


if (isWiggle(db, table))
    {
    bedList = getWiggleAsBed(db, table, region, filter, idHash, lm, conn);
    fieldCount = 4;
    }
else
    {
    bedSqlFieldsExceptForChrom(hti, &fieldCount, &fields);
    isPsl = htiIsPsl(hti);
    isGenePred = sameString("exonEnds", hti->endsSizesField);
    isBedWithBlocks = (
        (sameString("chromStarts", hti->startsField) ||
	 sameString("blockStarts", hti->startsField))
	     && sameString("blockSizes", hti->endsSizesField));

    /* All beds have at least chrom,start,end.  We omit the chrom
     * from the query since we already know it. */
    sr = regionQuery(conn, dbTable, fields, region, TRUE, filter);
    while (sr != NULL && (row = sqlNextRow(sr)) != NULL)
	{
	/* If have a name field apply hash filter. */
	if (fieldCount >= 4 && idHash != NULL)
	    if (!hashLookup(idHash, row[2]))
		continue;
	bed = bedFromRow(region->chrom, row, fieldCount, isPsl, isGenePred,
			 isBedWithBlocks, &pslKnowIfProtein, &pslIsProtein, lm);
	slAddHead(&bedList, bed);
	}
    freez(&fields);
    sqlFreeResult(&sr);
    slReverse(&bedList);
    }
hFreeConn(&conn);
if (retFieldCount)
    *retFieldCount = fieldCount;
return(bedList);
}
void tjLoadSome(struct region *regionList,
                struct joinedTables *joined, int fieldOffset, int keyOffset,
                char *idField, struct hash *idHash,
                struct slName *chopBefore, struct slName *chopAfter,
                struct tableJoiner *tj, boolean isPositional, boolean isFirst)
/* Load up rows. */
{
    struct region *region;
    struct dyString *sqlFields = dyStringNew(0);
    struct joinerDtf *dtf;
    struct slRef *ref;
    struct joinerPair *jp;
    int fieldCount = 0, keyCount = 0;
    int idFieldIx = -1;
    struct sqlConnection *conn = hAllocConn(tj->database);
    char *identifierFilter = NULL;
    char *filter;
    boolean needUpdateFilter = FALSE;
    struct joinedRow *jr;

    if (isFirst)
        identifierFilter = identifierWhereClause(idField, idHash);
    filter = filterClause(tj->database, tj->table, regionList->chrom, identifierFilter);

    /* Record combined filter. */
// Show only the SQL filter built from filter page options, not identifierFilter,
// because identifierFilter can get enormous (like 126kB for 12,500 rsIDs).
    char *filterNoIds = filterClause(tj->database, tj->table, regionList->chrom, NULL);
    if (filterNoIds != NULL)
    {
        if (joined->filter == NULL)
            joined->filter = dyStringNew(0);
        else
            dyStringAppend(joined->filter, " AND ");
        dyStringAppend(joined->filter, filterNoIds);
        if (!isFirst)
        {
            needUpdateFilter = TRUE;
            for (jr = joined->rowList; jr != NULL; jr = jr->next)
                jr->hitThisTable = FALSE;
        }
    }

    /* Create field spec for sql - first fields user will see, and
     * second keys if any. */
    for (dtf = tj->fieldList; dtf != NULL; dtf = dtf->next)
    {
        struct joinerDtf *dupe = joinerDtfClone(dtf);
        slAddTail(&joined->fieldList, dupe);
        dyStringAddList(sqlFields, dtf->field);
        ++fieldCount;
    }
    for (ref = tj->keysOut; ref != NULL; ref = ref->next)
    {
        struct joinerDtf *dupe;
        jp = ref->val;
        dupe = joinerDtfClone(jp->a);
        slAddTail(&joined->keyList, dupe);
        dyStringAddList(sqlFields, jp->a->field);
        ++keyCount;
    }
    if (idHash != NULL)
    {
        if (idField == NULL)
            internalErr();
        idFieldIx = fieldCount + keyCount;
        dyStringAddList(sqlFields, idField);
    }

    for (region = regionList; region != NULL; region = region->next)
    {
        char **row;
        /* We free at end of loop so we get new one for each chromosome. */
        char *filter = filterClause(tj->database, tj->table, region->chrom, identifierFilter);
        struct sqlResult *sr = regionQuery(conn, tj->table,
                                           sqlFields->string, region, isPositional, filter);
        while (sr != NULL && (row = sqlNextRow(sr)) != NULL)
        {
            if (idFieldIx < 0)
            {
                if (jrRowAdd(joined, row, fieldCount, keyCount) == NULL)
                    break;
            }
            else
            {
                char *id = row[idFieldIx];
                if (isFirst)
                {
                    if (hashLookup(idHash, id))
                    {
                        if (jrRowAdd(joined, row, fieldCount, keyCount) == NULL)
                            break;
                    }
                }
                else
                {
                    struct hashEl *bucket;
                    id = chopKey(chopBefore, chopAfter, id);
                    for (bucket = hashLookup(idHash, id); bucket != NULL;
                            bucket = hashLookupNext(bucket))
                    {
                        jr = bucket->val;
                        jr->hitThisTable = TRUE;
                        jrRowExpand(joined, jr, row,
                                    fieldOffset, fieldCount, keyOffset, keyCount);
                    }
                }
            }
        }
        sqlFreeResult(&sr);
        freez(&filter);
        if (!isPositional)
            break;
    }
    if (isFirst)
        slReverse(&joined->rowList);
    if (needUpdateFilter)
    {
        for (jr = joined->rowList; jr != NULL; jr = jr->next)
        {
            jr->passedFilter &= jr->hitThisTable;
        }
    }
    tj->loaded = TRUE;
    hFreeConn(&conn);
}