void enumFilterOption(char *db, char *table, char *field, char *type, char *logOp) /* Print out a table row with filter constraint options for an enum/set. */ { char *name = NULL; char **valMenu = NULL; int valMenuSize = 0; hPrintf("<TR VALIGN=BOTTOM align='left'><TD valign=top align='left'colspan=2> %s </TD>" "<TD valign=top>\n", field); name = filterFieldVarName(db, table, field, filterDdVar); cgiMakeDropListClassWithStyle(name, ddOpMenu, ddOpMenuSize, cartUsualString(cart, name, ddOpMenu[0]),"normalText","width: 76px"); hPrintf("<TD valign=top>%s</TD><TD colspan=4 nowrap>\n", isSqlSetType(type) ? "include" : "match"); name = filterPatternVarName(db, table, field); makeEnumValMenu(type, &valMenu, &valMenuSize); if (logOp == NULL) logOp = ""; if (valMenuSize-1 > 2) { struct slName *defaults = cartOptionalSlNameList(cart, name); if (defaults == NULL) defaults = slNameNew("*"); cgiMakeCheckboxGroup(name, valMenu, valMenuSize, defaults, 5); hPrintf("</TD><TD>%s </TD></TR>\n", logOp); } else { cgiMakeDropList(name, valMenu, valMenuSize,cartUsualString(cart, name, valMenu[0])); hPrintf(" %s </TD></TR>\n", logOp); } }
static void getVar(struct cartJson *cj, struct hash *paramHash) /* Print out the requested cart var(s). varString may be a comma-separated list. * If a var is a list variable, prints out a list of values for that var. */ { char *varString = cartJsonRequiredParam(paramHash, "var", cj->jw, "get"); if (! varString) return; struct slName *varList = slNameListFromComma(varString), *var; for (var = varList; var != NULL; var = var->next) { if (cartListVarExists(cj->cart, var->name)) { // Use cartOptionalSlNameList and return a list: struct slName *valList = cartOptionalSlNameList(cj->cart, var->name); jsonWriteSlNameList(cj->jw, var->name, valList); slFreeList(&valList); } else { // Regular single-value variable (or not in the cart): char *val = cartOptionalString(cj->cart, var->name); //#*** TODO: move jsonStringEscape inside jsonWriteString char *encoded = jsonStringEscape(val); jsonWriteString(cj->jw, var->name, encoded); freeMem(encoded); } } slFreeList(&varList); }
struct slPair *mdbSelectPairs(struct cart *cart, struct slPair *mdbVars) // Returns the current mdb vars and vals in the table of drop down selects { // figure out how many metadata selects are visible. int numMetadataSelects = 0; struct slPair *mdbSelectPairs = NULL; if (mdbVars == NULL) return 0; // Get the current number of rows in the table of mdb selects for (;;) { char buf[256]; safef(buf, sizeof(buf), "%s%d", METADATA_NAME_PREFIX, numMetadataSelects + 1); char *str = cartOptionalString(cart, buf); if (isEmpty(str)) break; else numMetadataSelects++; } // Requesting to add or delete any? int delSearchSelect = cartUsualInt(cart, TRACK_SEARCH_DEL_ROW, 0); // 1-based row to delete int addSearchSelect = cartUsualInt(cart, TRACK_SEARCH_ADD_ROW, 0); // 1-based row to insert after if (delSearchSelect) numMetadataSelects--; if (addSearchSelect) numMetadataSelects++; if (numMetadataSelects) { int ix; char buf[256]; for (ix = 0; ix < numMetadataSelects; ix++) { int offset; // used to handle additions/deletions if (addSearchSelect > 0 && ix >= addSearchSelect) offset = 0; // do nothing to offset (i.e. copy data from previous row) else if (delSearchSelect > 0 && ix + 1 >= delSearchSelect) offset = 2; else offset = 1; safef(buf, sizeof(buf), "%s%d", METADATA_NAME_PREFIX, ix + offset); char *var = cartOptionalString(cart, buf); char *val = NULL; // We need to make sure var is valid in this assembly; if it isn't, reset it to "cell". if (slPairFindVal(mdbVars,var) == NULL) var = "cell"; else { safef(buf, sizeof(buf), "%s%d", METADATA_VALUE_PREFIX, ix + offset); enum cvSearchable searchBy = cvSearchMethod(var); if (searchBy == cvSearchByMultiSelect) { // Multi-selects as comma delimited list of values struct slName *vals = cartOptionalSlNameList(cart,buf); if (vals) { val = slNameListToString(vals,','); // A comma delimited list of values slNameFreeList(&vals); } } else if (searchBy == cvSearchBySingleSelect || searchBy == cvSearchByFreeText || searchBy == cvSearchByWildList) val = cloneString(cartUsualString(cart, buf,ANYLABEL)); //else if (searchBy == cvSearchByDateRange || searchBy == cvSearchByIntegerRange) // { // // TO BE IMPLEMENTED // } if (val != NULL && sameString(val, ANYLABEL)) val = NULL; } slPairAdd(&mdbSelectPairs,var,val); // val already cloned } if (delSearchSelect > 0) { safef(buf, sizeof(buf), "%s%d", METADATA_NAME_PREFIX, numMetadataSelects + 1); cartRemove(cart, buf); safef(buf, sizeof(buf), "%s%d", METADATA_VALUE_PREFIX, numMetadataSelects + 1); cartRemove(cart, buf); } } else { // create defaults slPairAdd(&mdbSelectPairs,"cell", NULL); slPairAdd(&mdbSelectPairs,"antibody",NULL); } slReverse(&mdbSelectPairs); return mdbSelectPairs; }
char *filterClause(char *db, char *table, char *chrom, char *extraClause) /* Get filter clause (something to put after 'where') * for table */ { struct sqlConnection *conn = NULL; char varPrefix[128]; int varPrefixSize, fieldNameSize; struct hashEl *varList, *var; struct dyString *dy = NULL; boolean needAnd = FALSE; char oldDb[128]; char dbTableBuf[256]; char explicitDb[128]; char splitTable[256]; char explicitDbTable[512]; /* Return just extraClause (which may be NULL) if no filter on us. */ if (! (anyFilter() && filteredOrLinked(db, table))) return cloneString(extraClause); safef(oldDb, sizeof(oldDb), "%s", db); dbOverrideFromTable(dbTableBuf, &db, &table); if (!sameString(oldDb, db)) safef(explicitDb, sizeof(explicitDb), "%s.", db); else explicitDb[0] = 0; /* Cope with split table and/or custom tracks. */ if (isCustomTrack(table)) { conn = hAllocConn(CUSTOM_TRASH); struct customTrack *ct = ctLookupName(table); safef(explicitDbTable, sizeof(explicitDbTable), "%s", ct->dbTableName); } else { conn = hAllocConn(db); safef(splitTable, sizeof(splitTable), "%s_%s", chrom, table); if (!sqlTableExists(conn, splitTable)) safef(splitTable, sizeof(splitTable), "%s", table); safef(explicitDbTable, sizeof(explicitDbTable), "%s%s", explicitDb, splitTable); } /* Get list of filter variables for this table. */ safef(varPrefix, sizeof(varPrefix), "%s%s.%s.", hgtaFilterVarPrefix, db, table); varPrefixSize = strlen(varPrefix); varList = cartFindPrefix(cart, varPrefix); if (varList == NULL) { hFreeConn(&conn); return cloneString(extraClause); } /* Create filter clause string, stepping through vars. */ dy = dyStringNew(0); for (var = varList; var != NULL; var = var->next) { /* Parse variable name into field and type. */ char field[64], *s, *type; s = var->name + varPrefixSize; type = strchr(s, '.'); if (type == NULL) internalErr(); fieldNameSize = type - s; if (fieldNameSize >= sizeof(field)) internalErr(); memcpy(field, s, fieldNameSize); field[fieldNameSize] = 0; sqlCkId(field); type += 1; /* rawLogic and rawQuery are handled below; * filterMaxOutputVar is not really a filter variable and is handled * in wiggle.c. */ if (startsWith("raw", type) || sameString(filterMaxOutputVar, type)) continue; /* Any other variables that are missing a name: * <varPrefix>..<type> * are illegal */ if (fieldNameSize < 1) { warn("Missing name in cart variable: %s\n", var->name); continue; } if (sameString(type, filterDdVar)) { char *patVar = filterPatternVarName(db, table, field); struct slName *patList = cartOptionalSlNameList(cart, patVar); normalizePatList(&patList); if (slCount(patList) > 0) { char *ddVal = cartString(cart, var->name); boolean neg = sameString(ddVal, ddOpMenu[1]); char *fieldType = getSqlType(conn, explicitDbTable, field); boolean needOr = FALSE; if (needAnd) dyStringAppend(dy, " and "); needAnd = TRUE; if (neg) dyStringAppend(dy, "not "); boolean composite = (slCount(patList) > 1); if (composite || neg) dyStringAppendC(dy, '('); struct slName *pat; for (pat = patList; pat != NULL; pat = pat->next) { char *sqlPat = sqlLikeFromWild(pat->name); if (needOr) dyStringAppend(dy, " OR "); needOr = TRUE; if (isSqlSetType(fieldType)) { sqlDyStringPrintfFrag(dy, "FIND_IN_SET('%s', %s.%s)>0 ", sqlPat, explicitDbTable , field); } else { sqlDyStringPrintfFrag(dy, "%s.%s ", explicitDbTable, field); if (sqlWildcardIn(sqlPat)) dyStringAppend(dy, "like "); else dyStringAppend(dy, "= "); sqlDyStringPrintf(dy, "'%s'", sqlPat); } freez(&sqlPat); } if (composite || neg) dyStringAppendC(dy, ')'); } } else if (sameString(type, filterCmpVar)) { char *patVar = filterPatternVarName(db, table, field); char *pat = trimSpaces(cartOptionalString(cart, patVar)); char *cmpVal = cartString(cart, var->name); if (cmpReal(pat, cmpVal)) { if (needAnd) dyStringAppend(dy, " and "); needAnd = TRUE; if (sameString(cmpVal, "in range")) { char *words[2]; int wordCount; char *dupe = cloneString(pat); wordCount = chopString(dupe, ", \t\n", words, ArraySize(words)); if (wordCount < 2) /* Fake short input */ words[1] = "2000000000"; if (strchr(pat, '.')) /* Assume floating point */ { double a = atof(words[0]), b = atof(words[1]); sqlDyStringPrintfFrag(dy, "%s.%s >= %f && %s.%s <= %f", explicitDbTable, field, a, explicitDbTable, field, b); } else { int a = atoi(words[0]), b = atoi(words[1]); sqlDyStringPrintfFrag(dy, "%s.%s >= %d && %s.%s <= %d", explicitDbTable, field, a, explicitDbTable, field, b); } freez(&dupe); } else { // cmpVal has been checked already above in cmpReal for legal values. sqlDyStringPrintfFrag(dy, "%s.%s %-s ", explicitDbTable, field, cmpVal); if (strchr(pat, '.')) /* Assume floating point. */ dyStringPrintf(dy, "%f", atof(pat)); else dyStringPrintf(dy, "%d", atoi(pat)); } } } } /* Handle rawQuery if any */ { char *varName; char *logic, *query; varName = filterFieldVarName(db, table, "", filterRawLogicVar); logic = cartUsualString(cart, varName, logOpMenu[0]); varName = filterFieldVarName(db, table, "", filterRawQueryVar); query = trimSpaces(cartOptionalString(cart, varName)); if (query != NULL && query[0] != 0) { if (needAnd) dyStringPrintf(dy, " %s ", logic); sqlSanityCheckWhere(query, dy); } } /* Clean up and return */ hFreeConn(&conn); hashElFreeList(&varList); if (dy->stringSize == 0) { dyStringFree(&dy); return cloneString(extraClause); } else { if (isNotEmpty(extraClause)) dyStringPrintf(dy, " and %s", extraClause); return dyStringCannibalize(&dy); } }