d6ffdf62df145a1e6dca3359a1f2a0a7a7bfeed0 max Tue May 14 16:06:02 2013 -0700 trying to work around some sort of bug in mysql 5.6, see rm #10688 diff --git src/hg/hgTracks/pubsTracks.c src/hg/hgTracks/pubsTracks.c index 196528c..fdcfb4b 100644 --- src/hg/hgTracks/pubsTracks.c +++ src/hg/hgTracks/pubsTracks.c @@ -235,110 +235,123 @@ lf->extra = extra; hFreeConn(&conn); } static void dyStringPrintfWithSep(struct dyString *ds, char* sep, char *format, ...) /* Printf to end of dyString. Prefix with sep if dyString is not empty. */ { if (ds->stringSize!=0) dyStringAppend(ds, sep); va_list args; va_start(args, format); dyStringVaPrintf(ds, format, args); va_end(args); } +struct hash* searchForKeywords(struct sqlConnection* conn, char* articleTable, char* keywords) +/* return hash with the articleIds that contain a given keyword in the abstract/title/authors */ +{ +if (isEmpty(keywords)) + return NULL; + +char query[12000]; +safef(query, sizeof(query), "SELECT articleId FROM %s WHERE " +"MATCH (citation, title, authors, abstract) AGAINST ('%s' IN BOOLEAN MODE)", articleTable, keywords); +printf("query %s", query); +struct slName *artIds = sqlQuickList(conn, query); +if (artIds==NULL || slCount(artIds)==0) + return NULL; + +// convert list to hash +struct hash *hashA = hashNew(0); +struct slName *el; +for (el = artIds; el != NULL; el = el->next) + hashAddInt(hashA, el->name, 1); +freeMem(keywords); +slFreeList(artIds); +return hashA; +} + static void pubsLoadKeywordYearItems(struct track *tg) /* load items that fulfill keyword and year filter */ { pubsParseClassColors(); struct sqlConnection *conn = hAllocConn(database); char *keywords = cartOptionalStringClosestToHome(cart, tg->tdb, FALSE, "pubsFilterKeywords"); char *yearFilter = cartOptionalStringClosestToHome(cart, tg->tdb, FALSE, "pubsFilterYear"); char *publFilter = cartOptionalStringClosestToHome(cart, tg->tdb, FALSE, "pubsFilterPublisher"); char *articleTable = pubsArticleTable(tg); if(yearFilter == NULL || sameWord(yearFilter, "anytime")) yearFilter = NULL; if(publFilter==NULL || sameWord(publFilter, "all")) publFilter = NULL; if(isNotEmpty(keywords)) keywords = makeMysqlMatchStr(sqlEscapeString(keywords)); if (isEmpty(yearFilter) && isEmpty(keywords) && isEmpty(publFilter)) { loadGappedBed(tg); } else { char* oldLabel = tg->longLabel; tg->longLabel = catTwoStrings(oldLabel, " (filter activated)"); freeMem(oldLabel); - char yearWhere[256], keywordsWhere[1024], prefix[256]; char **row; struct linkedFeatures *lfList = NULL; struct trackDb *tdb = tg->tdb; int scoreMin = atoi(trackDbSettingClosestToHomeOrDefault(tdb, "scoreMin", "0")); int scoreMax = atoi(trackDbSettingClosestToHomeOrDefault(tdb, "scoreMax", "1000")); boolean useItemRgb = bedItemRgb(tdb); char *extra = NULL; struct dyString *extraDy = dyStringNew(0); + struct hash *articleIds = searchForKeywords(conn, articleTable, keywords); if (sqlColumnExists(conn, tg->table, "year")) // new table schema: filter fields are on main bed table { - if (isNotEmpty(keywords)) - dyStringPrintf(extraDy, "name IN (SELECT articleId FROM %s WHERE " - "MATCH (citation, title, authors, abstract) AGAINST ('%s' IN BOOLEAN MODE))", - articleTable, keywords); if (isNotEmpty(yearFilter)) dyStringPrintfWithSep(extraDy, " AND ", " year >= '%s'", sqlEscapeString(yearFilter)); if (isNotEmpty(publFilter)) dyStringPrintfWithSep(extraDy, " AND ", " publisher = '%s'", sqlEscapeString(publFilter)); - extra = extraDy->string; } else // old table schema, filter by doing a join on article table { - printf("extra %s", extra); - char extraTmp[4096]; - safef(prefix, sizeof(prefix), "name IN (SELECT articleId FROM %s WHERE", articleTable); - if(isNotEmpty(keywords)) - safef(keywordsWhere, sizeof(keywordsWhere), \ - "MATCH (citation, title, authors, abstract) AGAINST ('%s' IN BOOLEAN MODE)", keywords); if(isNotEmpty(yearFilter)) - safef(yearWhere, sizeof(yearWhere), "year >= '%s'", sqlEscapeString(yearFilter)); + dyStringPrintf(extraDy, "name IN (SELECT articleId FROM %s WHERE year>='%s')", articleTable, \ + yearFilter); + } - if(isEmpty(keywords)) - safef(extraTmp, sizeof(extraTmp), "%s %s)", prefix, yearWhere); - else if(isEmpty(yearFilter)) - safef(extraTmp, sizeof(extraTmp), "%s %s)", prefix, keywordsWhere); + + if (extraDy->stringSize>0) + extra = extraDy->string; else - safef(extraTmp, sizeof(extraTmp), "%s %s AND %s)", prefix, yearWhere, keywordsWhere); - extra = extraTmp; - } + extra = NULL; int rowOffset = 0; struct sqlResult *sr = hExtendedRangeQuery(conn, tg->table, chromName, winStart, winEnd, extra, FALSE, NULL, &rowOffset); freeDyString(&extraDy); while ((row = sqlNextRow(sr)) != NULL) { struct bed *bed = bedLoad12(row+rowOffset); + if (articleIds==NULL || hashFindVal(articleIds, bed->name)) slAddHead(&lfList, bedMungToLinkedFeatures(&bed, tdb, 12, scoreMin, scoreMax, useItemRgb)); } sqlFreeResult(&sr); slReverse(&lfList); slSort(&lfList, linkedFeaturesCmp); tg->items = lfList; } hFreeConn(&conn); } #define PUBSFILTERNAME "pubsFilterArticleId" static void activatePslTrackIfCgi(struct track *tg) /* the publications hgc creates links back to the browser with * the cgi param pubsFilterArticleId to show only a single type