9c6ef86df0c2a4358634bcd9dae49093e300ff29 angie Wed Sep 26 15:28:10 2018 -0700 For multi-region alt/fix autocomplete, use {alt,fix}Locations insteaf of {alt,fix}SeqLiftOverPsl because the former are more stable at this point, and the *Locations tables are used by hgTracks. refs #22144 diff --git src/hg/hgSuggest/hgSuggest.c src/hg/hgSuggest/hgSuggest.c index 97a3a18..c5a077f 100644 --- src/hg/hgSuggest/hgSuggest.c +++ src/hg/hgSuggest/hgSuggest.c @@ -96,42 +96,45 @@ } char *escapeAltFixTerm(char *term) /* Special tweaks for SQL search of alt/fix terms that may include '.' and '_' characters. */ { // 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: return sqlLikeFromWild(termCpy); } -struct slName *queryQNames(struct sqlConnection *conn, char *table, char *term, boolean prefixOnly) -/* If table exists, return qNames in table that match term, otherwise NULL. Exclude items whose - * tName contains '_' so the mappings between _alt and _fix sequences don't sneak into the wrong - * category's results. */ +struct slName *queryAltFixNames(struct sqlConnection *conn, char *table, char *term, + char *excludeSuffix, boolean prefixOnly) +/* If table exists, return names in table that match term, otherwise NULL. + * Chop after ':' if there is one and exclude items that end with excludeSuffix so the + * mappings between _alt and _fix sequences don't sneak into the wrong category's results. */ { struct slName *names = NULL; if (sqlTableExists(conn, table)) { char query[2048]; - sqlSafef(query, sizeof query, "select distinct(qName) from %s where qName like '%s%s%%' " - "and tName not rlike '.*_.*' order by qName", - table, (prefixOnly ? "" : "%"), escapeAltFixTerm(term)); + sqlSafef(query, sizeof query, "select distinct(substring_index(name, ':', 1)) from %s " + "where name like '%s%s%%' " + "and name not like '%%%s' and name not like '%%%s:%%'" + "order by name", + table, (prefixOnly ? "" : "%"), escapeAltFixTerm(term), excludeSuffix, excludeSuffix); 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); @@ -178,40 +181,40 @@ if (isNotEmpty(category)) jsonWriteString(jw, "category", category); jsonWriteObjectEnd(jw); } } } void suggestAltOrPatch(char *database, char *term) /* Print out a Javascript list of objects describing alternate haplotype or fix patch sequences * from database that match term. */ { struct jsonWrite *jw = jsonWriteNew(); jsonWriteListStart(jw, NULL); struct sqlConnection *conn = hAllocConn(database); // First, search for prefix matches -struct slName *fixMatches = queryQNames(conn, "fixSeqLiftOverPsl", term, TRUE); -struct slName *altMatches = queryQNames(conn, "altSeqLiftOverPsl", term, TRUE); +struct slName *fixMatches = queryAltFixNames(conn, "fixLocations", term, "alt", TRUE); +struct slName *altMatches = queryAltFixNames(conn, "altLocations", term, "fix", 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); + fixMatches = queryAltFixNames(conn, "fixLocations", term, "alt", FALSE); + altMatches = queryAltFixNames(conn, "altLocations", term, "fix", FALSE); writeAltFixMatches(jw, fixMatches, altMatches ? "Fix Patches" : ""); writeAltFixMatches(jw, altMatches, fixMatches ? "Alt Patches" : ""); } // If there are still no matches, try chromAlias. if (fixMatches == NULL && altMatches == NULL) { struct slPair *aliasMatches = queryChromAlias(conn, term, TRUE); writeValLabelMatches(jw, aliasMatches, ""); if (aliasMatches == NULL) { struct slPair *aliasMatches = queryChromAlias(conn, term, FALSE); writeValLabelMatches(jw, aliasMatches, ""); } } hFreeConn(&conn);