//--- Methods ---
        public ulong SearchAnalytics_LogQuery(SearchQuery query, string parsedQuery, uint userId, uint resultCount, ulong? previousQueryId) {
            var sorted = query.GetOrderedNormalizedTermString();
            var hash = query.GetOrderedTermsHash();
            var queryId = Catalog.NewQuery(@"/* SearchAnalytics_LogQuery */
INSERT INTO query_log (raw, sorted_terms, sorted_terms_hash, parsed, created, user_id, ref_query_id, result_count)
  VALUES (?QUERY, ?SORTED, ?HASH, ?PARSED, ?CREATED, ?USERID, ?REFID, ?RESULTCOUNT);
SELECT LAST_INSERT_ID();")
                .With("QUERY", query.Raw)
                .With("SORTED", sorted)
                .With("HASH", hash)
                .With("PARSED", parsedQuery)
                .With("USERID", userId)
                .With("CREATED", DateTime.UtcNow)
                .With("REFID", previousQueryId)
                .With("RESULTCOUNT", resultCount)
                .ReadAsULong().Value;
            var terms = query.GetNormalizedTerms();
            if(terms.Any()) {
                var quotedTerms = terms.Select(x => "'" + DataCommand.MakeSqlSafe(x) + "'").ToArray();
                Catalog.NewQuery(string.Format(@"/* SearchAnalytics_LogQuery */
INSERT IGNORE INTO query_terms (query_term) values
{0};", DbUtils.ConvertArrayToDelimittedString(',', quotedTerms.Select(x => "(" + x + ")")))).Execute();
                var termIds = new List<uint>();
                Catalog.NewQuery(string.Format(@"/* SearchAnalytics_LogQuery */
SELECT query_term_id from query_terms where query_term IN({0})",
                    DbUtils.ConvertArrayToDelimittedString(',', quotedTerms))).Execute(r => {
                        while(r.Read()) {
                            termIds.Add(r.Read<uint>(0));
                        }
                    });
                Catalog.NewQuery(string.Format(@"/* SearchAnalytics_LogQuery */
INSERT IGNORE INTO query_term_map (query_term_id,query_id) values
{0};", DbUtils.ConvertArrayToDelimittedString(',', termIds.Select(x => "(" + x + "," + queryId + ")")))).Execute();
            }
            return queryId;
        }
        public void CacheQuery_with_adaptive_search_fetches_popularity_data() {

            // Arrange
            var q = new SearchQuery("raw", "processed", new LuceneClauseBuilder(), null);
            _cache.Setup(x => x.Set(GetKey(q), It.IsAny<SearchResult>(), It.IsAny<TimeSpan>())).AtMostOnce().Verifiable();
            _session.Setup(x => x.SearchAnalytics_GetPopularityRanking(q.GetOrderedTermsHash()))
                .Returns((IEnumerable<ResultPopularityBE>)null)
                .AtMostOnce()
                .Verifiable();

            // Act
            Search.CacheQuery(new XDoc("foo"), q, null);

            // Assert
            _session.VerifyAll();
            _cache.VerifyAll();
        }