LCOV - code coverage report
Current view: top level - queryparser - queryparser.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core 7028d852e609 Lines: 86 90 95.6 %
Date: 2019-02-17 14:59:59 Functions: 23 24 95.8 %
Branches: 45 82 54.9 %

           Branch data     Line data    Source code
       1                 :            : /** @file queryparser.cc
       2                 :            :  * @brief The non-lemon-generated parts of the QueryParser class.
       3                 :            :  */
       4                 :            : /* Copyright (C) 2005,2006,2007,2008,2010,2011,2012,2013,2015,2016 Olly Betts
       5                 :            :  * Copyright (C) 2010 Adam Sj√łgren
       6                 :            :  *
       7                 :            :  * This program is free software; you can redistribute it and/or
       8                 :            :  * modify it under the terms of the GNU General Public License as
       9                 :            :  * published by the Free Software Foundation; either version 2 of the
      10                 :            :  * License, or (at your option) any later version.
      11                 :            :  *
      12                 :            :  * This program is distributed in the hope that it will be useful,
      13                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :            :  * GNU General Public License for more details.
      16                 :            :  *
      17                 :            :  * You should have received a copy of the GNU General Public License
      18                 :            :  * along with this program; if not, write to the Free Software
      19                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
      20                 :            :  * USA
      21                 :            :  */
      22                 :            : 
      23                 :            : #include <config.h>
      24                 :            : 
      25                 :            : #include "xapian/error.h"
      26                 :            : #include <xapian/queryparser.h>
      27                 :            : #include <xapian/termiterator.h>
      28                 :            : 
      29                 :            : #include "api/vectortermlist.h"
      30                 :            : #include "omassert.h"
      31                 :            : #include "queryparser_internal.h"
      32                 :            : 
      33                 :            : #include <cstring>
      34                 :            : 
      35                 :            : using namespace Xapian;
      36                 :            : 
      37                 :            : using namespace std;
      38                 :            : 
      39                 :            : // Default implementation in case the user hasn't implemented it.
      40                 :            : string
      41                 :          0 : Stopper::get_description() const
      42                 :            : {
      43         [ #  # ]:          0 :     return "Xapian::Stopper subclass";
      44                 :            : }
      45                 :            : 
      46                 :            : string
      47                 :          1 : SimpleStopper::get_description() const
      48                 :            : {
      49         [ +  - ]:          1 :     string desc("Xapian::SimpleStopper(");
      50                 :          1 :     unordered_set<string>::const_iterator i;
      51         [ -  + ]:          1 :     for (i = stop_words.begin(); i != stop_words.end(); ++i) {
      52 [ #  # ][ #  # ]:          0 :         if (i != stop_words.begin()) desc += ' ';
      53         [ #  # ]:          0 :         desc += *i;
      54                 :            :     }
      55         [ +  - ]:          1 :     desc += ')';
      56                 :          1 :     return desc;
      57                 :            : }
      58                 :            : 
      59         [ -  + ]:         60 : RangeProcessor::~RangeProcessor() { }
      60                 :            : 
      61         [ -  + ]:         14 : FieldProcessor::~FieldProcessor() { }
      62                 :            : 
      63                 :            : QueryParser::QueryParser(const QueryParser &) = default;
      64                 :            : 
      65                 :            : QueryParser &
      66                 :            : QueryParser::operator=(const QueryParser &) = default;
      67                 :            : 
      68                 :            : QueryParser::QueryParser(QueryParser &&) = default;
      69                 :            : 
      70                 :            : QueryParser &
      71                 :            : QueryParser::operator=(QueryParser &&) = default;
      72                 :            : 
      73         [ +  - ]:        185 : QueryParser::QueryParser() : internal(new QueryParser::Internal) { }
      74                 :            : 
      75                 :        374 : QueryParser::~QueryParser() { }
      76                 :            : 
      77                 :            : void
      78                 :         29 : QueryParser::set_stemmer(const Xapian::Stem & stemmer)
      79                 :            : {
      80                 :         29 :     internal->stemmer = stemmer;
      81                 :         29 : }
      82                 :            : 
      83                 :            : void
      84                 :         60 : QueryParser::set_stemming_strategy(stem_strategy strategy)
      85                 :            : {
      86                 :         60 :     internal->stem_action = strategy;
      87                 :         60 : }
      88                 :            : 
      89                 :            : void
      90                 :         14 : QueryParser::set_stopper(const Stopper * stopper)
      91                 :            : {
      92                 :         14 :     internal->stopper = stopper;
      93                 :         14 : }
      94                 :            : 
      95                 :            : void
      96                 :         43 : QueryParser::set_default_op(Query::op default_op)
      97                 :            : {
      98         [ +  + ]:         43 :     switch (default_op) {
      99                 :            :         case Query::OP_AND:
     100                 :            :         case Query::OP_OR:
     101                 :            :         case Query::OP_NEAR:
     102                 :            :         case Query::OP_PHRASE:
     103                 :            :         case Query::OP_ELITE_SET:
     104                 :            :         case Query::OP_SYNONYM:
     105                 :            :         case Query::OP_MAX:
     106                 :            :             // These are OK.
     107                 :         35 :             break;
     108                 :            :         default:
     109                 :            :             throw Xapian::InvalidArgumentError(
     110                 :            :                     "QueryParser::set_default_op() only accepts "
     111                 :            :                     "OP_AND"
     112                 :            :                     ", "
     113                 :            :                     "OP_OR"
     114                 :            :                     ", "
     115                 :            :                     "OP_NEAR"
     116                 :            :                     ", "
     117                 :            :                     "OP_PHRASE"
     118                 :            :                     ", "
     119                 :            :                     "OP_ELITE_SET"
     120                 :            :                     ", "
     121                 :            :                     "OP_SYNONYM"
     122                 :            :                     " or "
     123 [ +  - ][ +  - ]:          8 :                     "OP_MAX");
                 [ +  - ]
     124                 :            :     }
     125                 :         35 :     internal->default_op = default_op;
     126                 :         35 : }
     127                 :            : 
     128                 :            : Query::op
     129                 :         14 : QueryParser::get_default_op() const
     130                 :            : {
     131                 :         14 :     return internal->default_op;
     132                 :            : }
     133                 :            : 
     134                 :            : void
     135                 :        128 : QueryParser::set_database(const Database &db) {
     136                 :        128 :     internal->db = db;
     137                 :        128 : }
     138                 :            : 
     139                 :            : void
     140                 :         70 : QueryParser::set_max_expansion(Xapian::termcount max_expansion,
     141                 :            :                                int max_type,
     142                 :            :                                unsigned flags)
     143                 :            : {
     144         [ +  - ]:         70 :     if (flags & FLAG_WILDCARD) {
     145                 :         70 :         internal->max_wildcard_expansion = max_expansion;
     146                 :         70 :         internal->max_wildcard_type = max_type;
     147                 :            :     }
     148         [ +  - ]:         70 :     if (flags & FLAG_PARTIAL) {
     149                 :         70 :         internal->max_partial_expansion = max_expansion;
     150                 :         70 :         internal->max_partial_type = max_type;
     151                 :            :     }
     152                 :         70 : }
     153                 :            : 
     154                 :            : void
     155                 :         20 : QueryParser::set_min_wildcard_prefix(unsigned min_prefix_len,
     156                 :            :                                      unsigned flags)
     157                 :            : {
     158         [ +  + ]:         20 :     if (flags & FLAG_WILDCARD) {
     159                 :         15 :         internal->min_wildcard_prefix_len = min_prefix_len;
     160                 :            :     }
     161         [ +  - ]:         20 :     if (flags & FLAG_PARTIAL) {
     162                 :         20 :         internal->min_partial_prefix_len = min_prefix_len;
     163                 :            :     }
     164                 :         20 : }
     165                 :            : 
     166                 :            : Query
     167                 :      64233 : QueryParser::parse_query(const string &query_string, unsigned flags,
     168                 :            :                          const string &default_prefix)
     169                 :            : {
     170                 :      64233 :     internal->stoplist.clear();
     171                 :      64233 :     internal->unstem.clear();
     172                 :      64233 :     internal->errmsg = NULL;
     173                 :            : 
     174         [ +  + ]:      64233 :     if (query_string.empty()) return Query();
     175                 :            : 
     176         [ +  - ]:      64231 :     Query result = internal->parse_query(query_string, flags, default_prefix);
     177 [ +  + ][ +  + ]:      64231 :     if (internal->errmsg && strcmp(internal->errmsg, "parse error") == 0) {
                 [ +  + ]
     178                 :        119 :         flags &= FLAG_CJK_NGRAM;
     179 [ +  - ][ +  - ]:        119 :         result = internal->parse_query(query_string, flags, default_prefix);
     180                 :            :     }
     181                 :            : 
     182 [ +  + ][ +  - ]:      64231 :     if (internal->errmsg) throw Xapian::QueryParserError(internal->errmsg);
         [ +  - ][ +  - ]
     183         [ +  - ]:      64233 :     return result;
     184                 :            : }
     185                 :            : 
     186                 :            : void
     187                 :         52 : QueryParser::add_prefix(const string &field, const string &prefix)
     188                 :            : {
     189                 :            :     Assert(internal.get());
     190                 :         52 :     internal->add_prefix(field, prefix);
     191                 :         51 : }
     192                 :            : 
     193                 :            : void
     194                 :          6 : QueryParser::add_prefix(const string &field, Xapian::FieldProcessor * proc)
     195                 :            : {
     196                 :            :     Assert(internal.get());
     197                 :          6 :     internal->add_prefix(field, proc);
     198                 :          6 : }
     199                 :            : 
     200                 :            : void
     201                 :         26 : QueryParser::add_boolean_prefix(const string &field, const string &prefix,
     202                 :            :                                 const string* grouping)
     203                 :            : {
     204                 :            :     Assert(internal.get());
     205                 :         26 :     internal->add_boolean_prefix(field, prefix, grouping);
     206                 :         24 : }
     207                 :            : 
     208                 :            : void
     209                 :          2 : QueryParser::add_boolean_prefix(const string &field,
     210                 :            :                                 Xapian::FieldProcessor * proc,
     211                 :            :                                 const string* grouping)
     212                 :            : {
     213                 :            :     Assert(internal.get());
     214                 :          2 :     internal->add_boolean_prefix(field, proc, grouping);
     215                 :          2 : }
     216                 :            : 
     217                 :            : TermIterator
     218                 :          3 : QueryParser::stoplist_begin() const
     219                 :            : {
     220                 :          3 :     const list<string> & sl = internal->stoplist;
     221 [ +  - ][ +  - ]:          3 :     return TermIterator(new VectorTermList(sl.begin(), sl.end()));
                 [ +  - ]
     222                 :            : }
     223                 :            : 
     224                 :            : TermIterator
     225                 :          1 : QueryParser::unstem_begin(const string &term) const
     226                 :            : {
     227                 :            :     pair<multimap<string, string>::iterator,
     228                 :          1 :          multimap<string, string>::iterator> range;
     229         [ +  - ]:          1 :     range = internal->unstem.equal_range(term);
     230                 :          1 :     list<string> l;
     231                 :          1 :     multimap<string, string>::iterator & i = range.first;
     232         [ +  + ]:          2 :     while (i != range.second) {
     233         [ +  - ]:          1 :         l.push_back(i->second);
     234                 :          1 :         ++i;
     235                 :            :     }
     236 [ +  - ][ +  - ]:          1 :     return TermIterator(new VectorTermList(l.begin(), l.end()));
                 [ +  - ]
     237                 :            : }
     238                 :            : 
     239                 :            : void
     240                 :         28 : QueryParser::add_rangeprocessor(Xapian::RangeProcessor * range_proc,
     241                 :            :                                 const std::string* grouping)
     242                 :            : {
     243                 :            :     Assert(internal.get());
     244         [ +  - ]:         28 :     internal->rangeprocs.push_back(RangeProc(range_proc, grouping));
     245                 :         28 : }
     246                 :            : 
     247                 :            : string
     248                 :         46 : QueryParser::get_corrected_query_string() const
     249                 :            : {
     250                 :         46 :     return internal->corrected_query;
     251                 :            : }
     252                 :            : 
     253                 :            : string
     254                 :          5 : QueryParser::get_description() const
     255                 :            : {
     256                 :            :     // FIXME : describe better!
     257         [ +  - ]:          5 :     return "Xapian::QueryParser()";
     258                 :            : }

Generated by: LCOV version 1.11