5e6effdf943a1a0cda7e8f650abaffae243f2a83 angie Wed Apr 13 16:44:40 2016 -0700 Species autocomplete fixes: make sure 'grch37' properly selects hg19 and make it appear before genome matches. Make genome matches appear before sciName matches. If user types hg19 and hits enter, don't mismatch on some bogus labelly value. refs #15277 diff --git src/hg/hgGateway/hgGateway.c src/hg/hgGateway/hgGateway.c index fc5a359..99df2e0 100644 --- src/hg/hgGateway/hgGateway.c +++ src/hg/hgGateway/hgGateway.c @@ -288,32 +288,32 @@ webEndJWest(); } void doMiddle(struct cart *theCart) /* Depending on invocation, either perform a query and print out results * or display the main page. */ { cart = theCart; if (cgiOptionalString(CARTJSON_COMMAND)) doCartJson(); else doMainPage(); } -// We find matches from various fields of dbDb: -enum dbDbMatchType { ddmtUndef, ddmtDb, ddmtGenome, ddmtSciName, ddmtDescription }; +// We find matches from various fields of dbDb, and prefer them in this order: +enum dbDbMatchType { ddmtDescription=0, ddmtGenome=1, ddmtDb=2, ddmtSciName=3 }; struct dbDbMatch // Info about a match of a search term to some field of dbDb, including info that // helps prioritize matches. { struct dbDbMatch *next; struct dbDb *dbDb; // the row of dbDb in which a match was found enum dbDbMatchType type; // which field the match was found in int offset; // offset of the search term in the dbDb value boolean isWord; // TRUE if the the search term matches the word at offset boolean isComplete; // TRUE if the search term matches the entire target string }; static struct dbDbMatch *dbDbMatchNew(struct dbDb *dbDb, enum dbDbMatchType type, int offset, boolean isWord, boolean isComplete) @@ -327,33 +327,33 @@ ddm->isWord = isWord; ddm->isComplete = isComplete; return ddm; } static int dbDbMatchCmp(const void *va, const void *vb) /* Compare two matches by type, orderKey, offset and genome. */ { const struct dbDbMatch *a = *((struct dbDbMatch **)va); const struct dbDbMatch *b = *((struct dbDbMatch **)vb); int diff = b->isComplete - a->isComplete; if (diff == 0) diff = b->isWord - a->isWord; if (diff == 0 && a->isWord && b->isWord) diff = a->offset - b->offset; -// Use int values of type, in descending numeric order: +// Use int values of type: if (diff == 0) - diff = (int)(b->type) - (int)(a->type); + diff = (int)(a->type) - (int)(b->type); if (diff == 0) diff = a->dbDb->orderKey - b->dbDb->orderKey; if (diff == 0) diff = a->offset - b->offset; if (diff == 0) diff = strcmp(a->dbDb->genome, b->dbDb->genome); return diff; } INLINE void safeAddN(char **pDest, int *pSize, char *src, int len) /* Copy len bytes of src into dest. Subtract len from *pSize and add len to *pDest, * for building up a string bit by bit. */ { safencpy(*pDest, *pSize, src, len); *pSize -= len; @@ -417,67 +417,66 @@ // add the rest of the species: safeAdd(&p, &size, targetSpecies+termLen); } if (*p != '\0' || size != 1) errAbort("boldTerm: bad arithmetic (size is %d, *p is '%c')", size, *p); return cloneStringZ(result, resultSize); } static void writeDbDbMatch(struct jsonWrite *jw, struct dbDbMatch *match, char *term, char *category) /* Write out the JSON encoding of a match in dbDb. */ { struct dbDb *dbDb = match->dbDb; jsonWriteObjectStart(jw, NULL); jsonWriteString(jw, "genome", dbDb->genome); -if (match->type == ddmtDb) - jsonWriteString(jw, "db", dbDb->name); // label includes <b> tag to highlight the match for term. char label[PATH_LEN*4]; // value is placed in the input box when user selects the item. char value[PATH_LEN*4]; if (match->type == ddmtSciName) { safef(value, sizeof(value), "%s (%s)", dbDb->scientificName, dbDb->genome); char *bolded = boldTerm(dbDb->scientificName, term, match->offset, match->type); safef(label, sizeof(label), "%s (%s)", bolded, dbDb->genome); freeMem(bolded); } else if (match->type == ddmtGenome) { safecpy(value, sizeof(value), dbDb->genome); char *bolded = boldTerm(dbDb->genome, term, match->offset, match->type); safecpy(label, sizeof(label), bolded); freeMem(bolded); } else if (match->type == ddmtDb) { - safef(value, sizeof(value), "%s (%s %s)", - dbDb->name, dbDb->genome, dbDb->description); + safecpy(value, sizeof(value), dbDb->name); char *bolded = boldTerm(dbDb->name, term, match->offset, match->type); safef(label, sizeof(label), "%s (%s %s)", bolded, dbDb->genome, dbDb->description); freeMem(bolded); + jsonWriteString(jw, "db", dbDb->name); } else if (match->type == ddmtDescription) { safef(value, sizeof(value), "%s (%s %s)", dbDb->name, dbDb->genome, dbDb->description); char *bolded = boldTerm(dbDb->description, term, match->offset, match->type); safef(label, sizeof(label), "%s (%s %s)", dbDb->name, dbDb->genome, bolded); freeMem(bolded); + jsonWriteString(jw, "db", dbDb->name); } else errAbort("writeDbDbMatch: unrecognized dbDbMatchType value %d (db %s, term %s)", match->type, dbDb->name, term); jsonWriteString(jw, "label", label); jsonWriteString(jw, "value", value); jsonWriteNumber(jw, "taxId", dbDb->taxId); if (isNotEmpty(category)) jsonWriteString(jw, "category", category); jsonWriteObjectEnd(jw); } int wordMatchOffset(char *term, char *target) /* If some word of target starts with term (case insensitive), return the offset of * that word in target; otherwise return -1. */