eea5c3f688ba673e4a7af3d3a9441690aaaeeb2e tdreszer Tue Aug 10 16:43:07 2010 -0700 Removed the CB_SELECTION ifndefs diff --git src/hg/hgTracks/searchTracks.c src/hg/hgTracks/searchTracks.c index 25071b9..b5a7f79 100644 --- src/hg/hgTracks/searchTracks.c +++ src/hg/hgTracks/searchTracks.c @@ -1,664 +1,638 @@ /* Track search code used by hgTracks CGI */ #include "common.h" #include "searchTracks.h" #include "hCommon.h" #include "memalloc.h" #include "obscure.h" #include "dystring.h" #include "hash.h" #include "cheapcgi.h" #include "hPrint.h" #include "htmshell.h" #include "cart.h" #include "hgTracks.h" #include "web.h" #include "jksql.h" #include "hdb.h" #include "trix.h" #include "jsHelper.h" static char const rcsid[] = "$Id: searchTracks.c,v 1.11 2010/06/11 18:21:40 larrym Exp $"; #define ANYLABEL "Any" #define METADATA_NAME_PREFIX "hgt.metadataName" #define METADATA_VALUE_PREFIX "hgt.metadataValue" static int gCmpGroup(const void *va, const void *vb) /* Compare groups based on label. */ { const struct group *a = *((struct group **)va); const struct group *b = *((struct group **)vb); return strcmp(a->label, b->label); } static int gCmpTrack(const void *va, const void *vb) /* Compare tracks based on longLabel. */ { const struct slRef *aa = *((struct slRef **)va); const struct slRef *bb = *((struct slRef **)vb); const struct track *a = ((struct track *) aa->val); const struct track *b = ((struct track *) bb->val); return strcmp(a->longLabel, b->longLabel); } // XXXX make a matchString function to support "contains", "is" etc. and wildcards in contains // ((sameString(op, "is") && !strcasecmp(track->shortLabel, str)) || static boolean isNameMatch(struct track *track, char *str, char *op) { return str && strlen(str) && ((sameString(op, "is") && !strcasecmp(track->shortLabel, str)) || (sameString(op, "is") && !strcasecmp(track->longLabel, str)) || (sameString(op, "contains") && containsStringNoCase(track->shortLabel, str) != NULL) || (sameString(op, "contains") && containsStringNoCase(track->longLabel, str) != NULL)); } static boolean isDescriptionMatch(struct track *track, char **words, int wordCount) // We parse str and look for every word at the start of any word in track description (i.e. google style). { if(words) { // We do NOT lookup up parent hierarchy for html descriptions. char *html = track->tdb->html; if(!isEmpty(html)) { /* This probably could be made more efficient by parsing the html into some kind of b-tree, but I am assuming that the inner html loop while only happen for 1-2 words for vast majority of the tracks. */ int i, numMatches = 0; html = stripRegEx(html, "<[^>]*>", REG_ICASE); for(i = 0; i < wordCount; i++) { char *needle = words[i]; char *haystack, *tmp = cloneString(html); boolean found = FALSE; while((haystack = nextWord(&tmp))) { char *ptr = strstrNoCase(haystack, needle); if(ptr != NULL && ptr == haystack) { found = TRUE; break; } } if(found) numMatches++; else break; } if(numMatches == wordCount) return TRUE; } } return FALSE; } static int getTermArray(struct sqlConnection *conn, char ***terms, char *type) // Pull out all term fields from ra entries with given type // Returns count of items found and items via the terms argument. { struct sqlResult *sr = NULL; char **row = NULL; char query[256]; struct slName *termList = NULL; int i, count = 0; char **retVal; safef(query, sizeof(query), "select distinct val from metaDb where var = '%s'", type); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { slNameAddHead(&termList, row[0]); count++; } sqlFreeResult(&sr); slSort(&termList, slNameCmpCase); count++; // make room for "Any" AllocArray(retVal, count); retVal[0] = cloneString(ANYLABEL); for(i = 1; termList != NULL;termList = termList->next, i++) { retVal[i] = cloneString(termList->name); } *terms = retVal; return count; } static struct slName *metaDbSearch(struct sqlConnection *conn, char *name, char *val, char *op) // Search the assembly's metaDb table for var; If name == NULL, we search every metadata field. // Search is via mysql, so it's case-insensitive. { struct slName *retVal = NULL; char query[256]; struct sqlResult *sr = NULL; char **row = NULL; if(sameString(op, "contains")) if(name == NULL) safef(query, sizeof(query), "select obj from metaDb where val like '%%%s%%'", val); else safef(query, sizeof(query), "select obj from metaDb where var = '%s' and val like '%%%s%%'", name, val); else if(name == NULL) safef(query, sizeof(query), "select distinct obj from metaDb where val = '%s'", val); else safef(query, sizeof(query), "select obj from metaDb where var = '%s' and val = '%s'", name, val); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { slNameAddHead(&retVal, row[0]); } sqlFreeResult(&sr); return retVal; } static int metaDbVars(struct sqlConnection *conn, char *** metaValues) // Search the assemblies metaDb table; If name == NULL, we search every metadata field. { char query[256]; struct sqlResult *sr = NULL; char **row = NULL; int i; struct slName *el, *varList = NULL; char **retVal; safef(query, sizeof(query), "select distinct var from metaDb"); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) slNameAddHead(&varList, row[0]); sqlFreeResult(&sr); retVal = needMem(sizeof(char *) * slCount(varList)); slNameSort(&varList); for (el = varList, i = 0; el != NULL; el = el->next, i++) retVal[i] = el->name; *metaValues = retVal; return i; } void doSearchTracks(struct group *groupList) { struct group *group; char *ops[] = {"is", "contains"}; char *op_labels[] = {"is", "contains"}; char *groups[128]; char *labels[128]; int numGroups = 1; groups[0] = ANYLABEL; labels[0] = ANYLABEL; char *currentTab = cartUsualString(cart, "hgt.currentSearchTab", "simpleTab"); char *nameSearch = cartOptionalString(cart, "hgt.nameSearch"); char *nameOp = cartOptionalString(cart, "hgt.nameOp"); char *descSearch; char *groupSearch = cartOptionalString(cart, "hgt.groupSearch"); boolean doSearch = sameString(cartOptionalString(cart, searchTracks), "Search"); struct sqlConnection *conn = hAllocConn(database); boolean metaDbExists = sqlTableExists(conn, "metaDb"); struct slRef *tracks = NULL; int numMetadataSelects, tracksFound = 0; int numMetadataNonEmpty = 0; char **metadataName; char **metadataValue; struct hash *parents = newHash(4); boolean simpleSearch; struct trix *trix; char trixFile[HDB_MAX_PATH_STRING]; char **descWords = NULL; int descWordCount = 0; if(sameString(currentTab, "simpleTab")) { descSearch = cartOptionalString(cart, "hgt.simpleSearch"); simpleSearch = TRUE; freez(&nameSearch); freez(&groupSearch); } else { descSearch = cartOptionalString(cart, "hgt.descSearch"); simpleSearch = FALSE; } getSearchTrixFile(database, trixFile, sizeof(trixFile)); trix = trixOpen(trixFile); getTrackList(&groupList, -2); slSort(&groupList, gCmpGroup); for (group = groupList; group != NULL; group = group->next) { if (group->trackList != NULL) { groups[numGroups] = cloneString(group->name); labels[numGroups] = cloneString(group->label); numGroups++; if (numGroups >= ArraySize(groups)) internalErr(); } } webStartWrapperDetailedNoArgs(cart, database, "", "Track Search", FALSE, FALSE, FALSE, FALSE); hPrintf("