d86d0030a9eb8ebce064d942456b42e6f82874cf angie Tue Sep 25 14:11:18 2018 -0700 In altOrPatch mode, if prefix matching yields no results, then try matching any part of sequence names. Treat '.' as a single-char wildcard so 'KI270857.1' can match chr17_KI270857v1_alt. refs #18854 diff --git src/hg/hgSuggest/hgSuggest.c src/hg/hgSuggest/hgSuggest.c index 2f740f4..ceff555 100644 --- src/hg/hgSuggest/hgSuggest.c +++ src/hg/hgSuggest/hgSuggest.c @@ -83,73 +83,91 @@ dyStringPrintf(str, "%s{\"value\": \"%s (%s)\", " "\"id\": \"%s:%d-%s\", " "\"geneSymbol\": \"%s\", " "\"internalId\": \"%s\"}", count == 1 ? "" : ",\n", row[0], jsonStringEscape(description), row[1], atoi(row[2])+1, row[3], jsonStringEscape(row[0]), jsonStringEscape(row[4])); } } hFreeConn(&conn); dyStringPrintf(str, "\n]\n"); puts(dyStringContents(str)); } -struct slName *queryQNames(struct sqlConnection *conn, char *table, char *prefix) -/* If table exists, return qNames in table that match prefix, otherwise NULL. */ +struct slName *queryQNames(struct sqlConnection *conn, char *table, char *term, boolean prefixOnly) +/* If table exists, return qNames in table that match term, otherwise NULL. */ { struct slName *names = NULL; if (sqlTableExists(conn, table)) { + // If there is a ".", make it into a single-character wildcard so that "GL383518.1" + // can match "chr1_GL383518v1_alt". + char termCpy[strlen(term)+1]; + safecpy(termCpy, sizeof termCpy, term); + subChar(termCpy, '.', '?'); + // Escape '_' because that is an important character in alt/fix sequence names, and support + // wildcards: + char *escapedTerm = sqlLikeFromWild(termCpy); char query[2048]; - sqlSafef(query, sizeof query, "select distinct(qName) from %s where qName like '%s%%' " - "order by qName", table, sqlLikeFromWild(prefix)); + sqlSafef(query, sizeof query, "select distinct(qName) from %s where qName like '%s%s%%' " + "order by qName", + table, (prefixOnly ? "" : "%"), escapedTerm); names = sqlQuickList(conn, query); } return names; } void writeAltFixMatches(struct jsonWrite *jw, struct slName *matches, char *category) /* Append JSON objects containing alt or fix patch sequence names & optional category. */ { struct slName *match; for (match = matches; match != NULL; match = match->next) { if (strchr(match->name, '_')) { jsonWriteObjectStart(jw, NULL); jsonWriteString(jw, "value", match->name); if (isNotEmpty(category)) jsonWriteString(jw, "category", category); jsonWriteObjectEnd(jw); } } } -void suggestAltOrPatch(char *database, char *prefix) +void suggestAltOrPatch(char *database, char *term) /* Print out a Javascript list of objects describing alternate haplotype or fix patch sequences - * from database that match prefix. */ + * from database that match term. */ { struct jsonWrite *jw = jsonWriteNew(); jsonWriteListStart(jw, NULL); struct sqlConnection *conn = hAllocConn(database); -struct slName *fixMatches = queryQNames(conn, "fixSeqLiftOverPsl", prefix); -struct slName *altMatches = queryQNames(conn, "altSeqLiftOverPsl", prefix); +// First, search for prefix matches +struct slName *fixMatches = queryQNames(conn, "fixSeqLiftOverPsl", term, TRUE); +struct slName *altMatches = queryQNames(conn, "altSeqLiftOverPsl", term, TRUE); // Add category labels only if we get both types of matches. writeAltFixMatches(jw, fixMatches, altMatches ? "Fix Patches" : ""); writeAltFixMatches(jw, altMatches, fixMatches ? "Alt Patches" : ""); +// If there are no prefix matches, look for partial matches +if (fixMatches == NULL && altMatches == NULL) + { + fixMatches = queryQNames(conn, "fixSeqLiftOverPsl", term, FALSE); + altMatches = queryQNames(conn, "altSeqLiftOverPsl", term, FALSE); + writeAltFixMatches(jw, fixMatches, altMatches ? "Fix Patches" : ""); + writeAltFixMatches(jw, altMatches, fixMatches ? "Alt Patches" : ""); + } hFreeConn(&conn); jsonWriteListEnd(jw); puts(jw->dy->string); jsonWriteFree(&jw); } char *checkParams(char *database, char *prefix, char *type) /* If we don't have valid CGI parameters, quit with a Bad Request HTTP response. */ { pushWarnHandler(htmlVaBadRequestAbort); pushAbortHandler(htmlVaBadRequestAbort); if(prefix == NULL || database == NULL) errAbort("%s", "Missing prefix and/or db CGI parameter"); if (! hDbIsActive(database)) errAbort("'%s' is not a valid, active database", htmlEncode(database));