LCOV - code coverage report
Current view: top level - include/xapian - queryparser.h (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core 7028d852e609 Lines: 44 45 97.8 %
Date: 2019-02-17 14:59:59 Functions: 29 29 100.0 %
Branches: 15 30 50.0 %

           Branch data     Line data    Source code
       1                 :            : /** @file queryparser.h
       2                 :            :  * @brief parsing a user query string to build a Xapian::Query object
       3                 :            :  */
       4                 :            : /* Copyright (C) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018 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                 :            : #ifndef XAPIAN_INCLUDED_QUERYPARSER_H
      24                 :            : #define XAPIAN_INCLUDED_QUERYPARSER_H
      25                 :            : 
      26                 :            : #if !defined XAPIAN_IN_XAPIAN_H && !defined XAPIAN_LIB_BUILD
      27                 :            : # error "Never use <xapian/queryparser.h> directly; include <xapian.h> instead."
      28                 :            : #endif
      29                 :            : 
      30                 :            : #include <xapian/attributes.h>
      31                 :            : #include <xapian/intrusive_ptr.h>
      32                 :            : #include <xapian/query.h>
      33                 :            : #include <xapian/termiterator.h>
      34                 :            : #include <xapian/visibility.h>
      35                 :            : 
      36                 :            : #include <string>
      37                 :            : #include <unordered_set>
      38                 :            : 
      39                 :            : namespace Xapian {
      40                 :            : 
      41                 :            : class Database;
      42                 :            : class Stem;
      43                 :            : 
      44                 :            : /// Base class for stop-word decision functor.
      45                 :            : class XAPIAN_VISIBILITY_DEFAULT Stopper
      46                 :            :     : public Xapian::Internal::opt_intrusive_base {
      47                 :            :     /// Don't allow assignment.
      48                 :            :     void operator=(const Stopper &) = delete;
      49                 :            : 
      50                 :            :     /// Don't allow copying.
      51                 :            :     Stopper(const Stopper &) = delete;
      52                 :            : 
      53                 :            :   public:
      54                 :            :     /// Default constructor.
      55                 :         98 :     Stopper() { }
      56                 :            : 
      57                 :            :     /** Is term a stop-word?
      58                 :            :      *
      59                 :            :      *  @param term     The term to test.
      60                 :            :      */
      61                 :            :     virtual bool operator()(const std::string & term) const = 0;
      62                 :            : 
      63                 :            :     /// Class has virtual methods, so provide a virtual destructor.
      64         [ -  + ]:         98 :     virtual ~Stopper() { }
      65                 :            : 
      66                 :            :     /// Return a string describing this object.
      67                 :            :     virtual std::string get_description() const;
      68                 :            : 
      69                 :            :     /** Start reference counting this object.
      70                 :            :      *
      71                 :            :      *  You can hand ownership of a dynamically allocated Stopper
      72                 :            :      *  object to Xapian by calling release() and then passing the object to a
      73                 :            :      *  Xapian method.  Xapian will arrange to delete the object once it is no
      74                 :            :      *  longer required.
      75                 :            :      */
      76                 :         13 :     Stopper * release() {
      77                 :         13 :         opt_intrusive_base::release();
      78                 :         13 :         return this;
      79                 :            :     }
      80                 :            : 
      81                 :            :     /** Start reference counting this object.
      82                 :            :      *
      83                 :            :      *  You can hand ownership of a dynamically allocated Stopper
      84                 :            :      *  object to Xapian by calling release() and then passing the object to a
      85                 :            :      *  Xapian method.  Xapian will arrange to delete the object once it is no
      86                 :            :      *  longer required.
      87                 :            :      */
      88                 :            :     const Stopper * release() const {
      89                 :            :         opt_intrusive_base::release();
      90                 :            :         return this;
      91                 :            :     }
      92                 :            : };
      93                 :            : 
      94                 :            : /// Simple implementation of Stopper class - this will suit most users.
      95         [ -  + ]:         20 : class XAPIAN_VISIBILITY_DEFAULT SimpleStopper : public Stopper {
      96                 :            :     std::unordered_set<std::string> stop_words;
      97                 :            : 
      98                 :            :   public:
      99                 :            :     /// Default constructor.
     100         [ +  - ]:          6 :     SimpleStopper() { }
     101                 :            : 
     102                 :            :     /** Initialise from a pair of iterators.
     103                 :            :      *
     104                 :            :      * Xapian includes stop list files for many languages. You can initialise from a file like that:
     105                 :            :      * @code
     106                 :            :      * ifstream words("stopwords/english/stop.txt");
     107                 :            :      * Xapian::SimplerStopper stopper(istream_iterator<string>(words), istream_iterator<string>());
     108                 :            :      * @endcode
     109                 :            :      *
     110                 :            :      */
     111                 :            :     template<class Iterator>
     112         [ +  - ]:          3 :     SimpleStopper(Iterator begin, Iterator end) : stop_words(begin, end) { }
     113                 :            : 
     114                 :            :     /// Add a single stop word.
     115                 :         30 :     void add(const std::string & word) { stop_words.insert(word); }
     116                 :            : 
     117                 :        199 :     virtual bool operator()(const std::string & term) const {
     118         [ +  - ]:        199 :         return stop_words.find(term) != stop_words.end();
     119                 :            :     }
     120                 :            : 
     121                 :            :     virtual std::string get_description() const;
     122                 :            : };
     123                 :            : 
     124                 :            : enum {
     125                 :            :     RP_SUFFIX = 1,
     126                 :            :     RP_REPEATED = 2,
     127                 :            :     RP_DATE_PREFER_MDY = 4
     128                 :            : };
     129                 :            : 
     130                 :            : /// Base class for range processors.
     131                 :            : class XAPIAN_VISIBILITY_DEFAULT RangeProcessor
     132                 :            :     : public Xapian::Internal::opt_intrusive_base {
     133                 :            :     /// Don't allow assignment.
     134                 :            :     void operator=(const RangeProcessor &);
     135                 :            : 
     136                 :            :     /// Don't allow copying.
     137                 :            :     RangeProcessor(const RangeProcessor &);
     138                 :            : 
     139                 :            :   protected:
     140                 :            :     /** The value slot to process.
     141                 :            :      *
     142                 :            :      *  If this range processor isn't value-based, it can ignore this member.
     143                 :            :      */
     144                 :            :     Xapian::valueno slot;
     145                 :            : 
     146                 :            :     /** The prefix (or suffix with RP_SUFFIX) string to look for. */
     147                 :            :     std::string str;
     148                 :            : 
     149                 :            :     /** Flags.
     150                 :            :      *
     151                 :            :      *  Bitwise-or (| in C++) of zero or more of the following:
     152                 :            :      *  * Xapian::RP_SUFFIX - require @a str as a suffix
     153                 :            :      *    instead of a prefix.
     154                 :            :      *  * Xapian::RP_REPEATED - optionally allow @a str
     155                 :            :      *    on both ends of the range - e.g. $1..$10 or
     156                 :            :      *    5m..50m.  By default a prefix is only checked for on
     157                 :            :      *    the start (e.g. date:1/1/1980..31/12/1989), and a
     158                 :            :      *    suffix only on the end (e.g. 2..12kg).
     159                 :            :      */
     160                 :            :     unsigned flags;
     161                 :            : 
     162                 :            :   public:
     163                 :            :     /** Default constructor. */
     164         [ +  - ]:          1 :     RangeProcessor() : slot(Xapian::BAD_VALUENO), flags(0) { }
     165                 :            : 
     166                 :            :     /** Constructor.
     167                 :            :      *
     168                 :            :      *  @param slot_    Which value slot to generate ranges over.
     169                 :            :      *  @param str_     A string to look for to recognise values as belonging
     170                 :            :      *                  to this range (as a prefix by default, or as a suffix
     171                 :            :      *                  if flags Xapian::RP_SUFFIX is specified).
     172                 :            :      *  @param flags_   Zero or more of the following flags, combined with
     173                 :            :      *                  bitwise-or (| in C++):
     174                 :            :      *                   * Xapian::RP_SUFFIX - require @a str_ as a suffix
     175                 :            :      *                     instead of a prefix.
     176                 :            :      *                   * Xapian::RP_REPEATED - optionally allow @a str_
     177                 :            :      *                     on both ends of the range - e.g. $1..$10 or
     178                 :            :      *                     5m..50m.  By default a prefix is only checked for on
     179                 :            :      *                     the start (e.g. date:1/1/1980..31/12/1989), and a
     180                 :            :      *                     suffix only on the end (e.g. 2..12kg).
     181                 :            :      */
     182                 :         29 :     explicit RangeProcessor(Xapian::valueno slot_,
     183                 :            :                             const std::string& str_ = std::string(),
     184                 :            :                             unsigned flags_ = 0)
     185         [ +  - ]:         29 :         : slot(slot_), str(str_), flags(flags_) { }
     186                 :            : 
     187                 :            :     /// Destructor.
     188                 :            :     virtual ~RangeProcessor();
     189                 :            : 
     190                 :            :     /** Check prefix/suffix on range.
     191                 :            :      *
     192                 :            :      *  If they match, remove the prefix/suffix and then call operator()()
     193                 :            :      *  to try to handle the range.
     194                 :            :      */
     195                 :            :     Xapian::Query check_range(const std::string& b, const std::string& e);
     196                 :            : 
     197                 :            :     /** Check for a valid range of this type.
     198                 :            :      *
     199                 :            :      *  Override this method to implement your own range handling.
     200                 :            :      *
     201                 :            :      *  @param begin    The start of the range as specified in the query string
     202                 :            :      *                  by the user.
     203                 :            :      *  @param end      The end of the range as specified in the query string
     204                 :            :      *                  by the user (empty string for no upper limit).
     205                 :            :      *
     206                 :            :      *  @return         An OP_VALUE_RANGE Query object (or if end.empty(), an
     207                 :            :      *                  OP_VALUE_GE Query object).  Or if the range isn't one
     208                 :            :      *                  which this object can handle then
     209                 :            :      *                  Xapian::Query(Xapian::Query::OP_INVALID) will be
     210                 :            :      *                  returned.
     211                 :            :      */
     212                 :            :     virtual Xapian::Query
     213                 :            :         operator()(const std::string &begin, const std::string &end);
     214                 :            : 
     215                 :            :     /** Start reference counting this object.
     216                 :            :      *
     217                 :            :      *  You can hand ownership of a dynamically allocated RangeProcessor
     218                 :            :      *  object to Xapian by calling release() and then passing the object to a
     219                 :            :      *  Xapian method.  Xapian will arrange to delete the object once it is no
     220                 :            :      *  longer required.
     221                 :            :      */
     222                 :          4 :     RangeProcessor * release() {
     223                 :          4 :         opt_intrusive_base::release();
     224                 :          4 :         return this;
     225                 :            :     }
     226                 :            : 
     227                 :            :     /** Start reference counting this object.
     228                 :            :      *
     229                 :            :      *  You can hand ownership of a dynamically allocated RangeProcessor
     230                 :            :      *  object to Xapian by calling release() and then passing the object to a
     231                 :            :      *  Xapian method.  Xapian will arrange to delete the object once it is no
     232                 :            :      *  longer required.
     233                 :            :      */
     234                 :            :     const RangeProcessor * release() const {
     235                 :            :         opt_intrusive_base::release();
     236                 :            :         return this;
     237                 :            :     }
     238                 :            : };
     239                 :            : 
     240                 :            : /** Handle a date range.
     241                 :            :  *
     242                 :            :  *  Begin and end must be dates in a recognised format.
     243                 :            :  */
     244         [ -  + ]:         16 : class XAPIAN_VISIBILITY_DEFAULT DateRangeProcessor : public RangeProcessor {
     245                 :            :     int epoch_year;
     246                 :            : 
     247                 :            :   public:
     248                 :            :     /** Constructor.
     249                 :            :      *
     250                 :            :      *  @param slot_    The value number to return from operator().
     251                 :            :      *
     252                 :            :      *  @param flags_   Zero or more of the following flags, combined with
     253                 :            :      *                  bitwise-or:
     254                 :            :      *                   * Xapian::RP_DATE_PREFER_MDY - interpret ambiguous
     255                 :            :      *                     dates as month/day/year rather than day/month/year.
     256                 :            :      *
     257                 :            :      *  @param epoch_year_  Year to use as the epoch for dates with 2 digit
     258                 :            :      *                      years (default: 1970, so 1/1/69 is 2069 while
     259                 :            :      *                      1/1/70 is 1970).
     260                 :            :      */
     261                 :          3 :     explicit DateRangeProcessor(Xapian::valueno slot_,
     262                 :            :                                 unsigned flags_ = 0,
     263                 :            :                                 int epoch_year_ = 1970)
     264                 :            :         : RangeProcessor(slot_, std::string(), flags_),
     265         [ +  - ]:          3 :           epoch_year(epoch_year_) { }
     266                 :            : 
     267                 :            :     /** Constructor.
     268                 :            :      *
     269                 :            :      *  @param slot_    The value slot number to query.
     270                 :            :      *
     271                 :            :      *  @param str_     A string to look for to recognise values as belonging
     272                 :            :      *                  to this date range.
     273                 :            :      *
     274                 :            :      *  @param flags_   Zero or more of the following flags, combined with
     275                 :            :      *                  bitwise-or:
     276                 :            :      *                   * Xapian::RP_SUFFIX - require @a str_ as a suffix
     277                 :            :      *                     instead of a prefix.
     278                 :            :      *                   * Xapian::RP_REPEATED - optionally allow @a str_
     279                 :            :      *                     on both ends of the range - e.g. $1..$10 or
     280                 :            :      *                     5m..50m.  By default a prefix is only checked for on
     281                 :            :      *                     the start (e.g. date:1/1/1980..31/12/1989), and a
     282                 :            :      *                     suffix only on the end (e.g. 2..12kg).
     283                 :            :      *                   * Xapian::RP_DATE_PREFER_MDY - interpret ambiguous
     284                 :            :      *                     dates as month/day/year rather than day/month/year.
     285                 :            :      *
     286                 :            :      *  @param epoch_year_  Year to use as the epoch for dates with 2 digit
     287                 :            :      *                      years (default: 1970, so 1/1/69 is 2069 while
     288                 :            :      *                      1/1/70 is 1970).
     289                 :            :      *
     290                 :            :      *  The string supplied in str_ is used by @a operator() to decide whether
     291                 :            :      *  the pair of strings supplied to it constitute a valid range.  If
     292                 :            :      *  prefix_ is true, the first value in a range must begin with str_ (and
     293                 :            :      *  the second value may optionally begin with str_);
     294                 :            :      *  if prefix_ is false, the second value in a range must end with str_
     295                 :            :      *  (and the first value may optionally end with str_).
     296                 :            :      *
     297                 :            :      *  If str_ is empty, the Xapian::RP_SUFFIX and Xapian::RP_REPEATED are
     298                 :            :      *  irrelevant, and no special strings are required at the start or end of
     299                 :            :      *  the strings defining the range.
     300                 :            :      *
     301                 :            :      *  The remainder of both strings defining the endpoints must be valid
     302                 :            :      *  dates.
     303                 :            :      *
     304                 :            :      *  For example, if str_ is "created:", Xapian::RP_SUFFIX is not specified,
     305                 :            :      *  and the range processor has been added to the queryparser, the
     306                 :            :      *  queryparser will accept "created:1/1/2000..31/12/2001".
     307                 :            :      */
     308                 :          5 :     DateRangeProcessor(Xapian::valueno slot_, const std::string &str_,
     309                 :            :                        unsigned flags_ = 0, int epoch_year_ = 1970)
     310                 :            :         : RangeProcessor(slot_, str_, flags_),
     311                 :          5 :           epoch_year(epoch_year_) { }
     312                 :            : 
     313                 :            :     /** Check for a valid date range.
     314                 :            :      *
     315                 :            :      *  If any specified prefix is present, and the range looks like a
     316                 :            :      *  date range, the dates are converted to the format YYYYMMDD and
     317                 :            :      *  combined into a value range query.
     318                 :            :      *
     319                 :            :      *  @param begin    The start of the range as specified in the query string
     320                 :            :      *                  by the user.
     321                 :            :      *  @param end      The end of the range as specified in the query string
     322                 :            :      *                  by the user.
     323                 :            :      */
     324                 :            :     Xapian::Query operator()(const std::string& begin, const std::string& end);
     325                 :            : };
     326                 :            : 
     327                 :            : /** Handle a number range.
     328                 :            :  *
     329                 :            :  *  This class must be used on values which have been encoded using
     330                 :            :  *  Xapian::sortable_serialise() which turns numbers into strings which
     331                 :            :  *  will sort in the same order as the numbers (the same values can be
     332                 :            :  *  used to implement a numeric sort).
     333                 :            :  */
     334         [ -  + ]:         18 : class XAPIAN_VISIBILITY_DEFAULT NumberRangeProcessor : public RangeProcessor {
     335                 :            :   public:
     336                 :            :     /** Constructor.
     337                 :            :      *
     338                 :            :      *  @param slot_    The value slot number to query.
     339                 :            :      *
     340                 :            :      *  @param str_     A string to look for to recognise values as belonging
     341                 :            :      *                  to this numeric range.
     342                 :            :      *
     343                 :            :      *  @param flags_   Zero or more of the following flags, combined with
     344                 :            :      *                  bitwise-or:
     345                 :            :      *                   * Xapian::RP_SUFFIX - require @a str_ as a suffix
     346                 :            :      *                     instead of a prefix.
     347                 :            :      *                   * Xapian::RP_REPEATED - optionally allow @a str_
     348                 :            :      *                     on both ends of the range - e.g. $1..$10 or
     349                 :            :      *                     5m..50m.  By default a prefix is only checked for on
     350                 :            :      *                     the start (e.g. date:1/1/1980..31/12/1989), and a
     351                 :            :      *                     suffix only on the end (e.g. 2..12kg).
     352                 :            :      *
     353                 :            :      *  The string supplied in str_ is used by @a operator() to decide whether
     354                 :            :      *  the pair of strings supplied to it constitute a valid range.  If
     355                 :            :      *  prefix_ is true, the first value in a range must begin with str_ (and
     356                 :            :      *  the second value may optionally begin with str_);
     357                 :            :      *  if prefix_ is false, the second value in a range must end with str_
     358                 :            :      *  (and the first value may optionally end with str_).
     359                 :            :      *
     360                 :            :      *  If str_ is empty, the setting of prefix_ is irrelevant, and no special
     361                 :            :      *  strings are required at the start or end of the strings defining the
     362                 :            :      *  range.
     363                 :            :      *
     364                 :            :      *  The remainder of both strings defining the endpoints must be valid
     365                 :            :      *  floating point numbers. (FIXME: define format recognised).
     366                 :            :      *
     367                 :            :      *  For example, if str_ is "$" and prefix_ is true, and the range
     368                 :            :      *  processor has been added to the queryparser, the queryparser will
     369                 :            :      *  accept "$10..50" or "$10..$50", but not "10..50" or "10..$50" as valid
     370                 :            :      *  ranges.  If str_ is "kg" and prefix_ is false, the queryparser will
     371                 :            :      *  accept "10..50kg" or "10kg..50kg", but not "10..50" or "10kg..50" as
     372                 :            :      *  valid ranges.
     373                 :            :      */
     374                 :          9 :     NumberRangeProcessor(Xapian::valueno slot_,
     375                 :            :                          const std::string &str_ = std::string(),
     376                 :            :                          unsigned flags_ = 0)
     377                 :          9 :         : RangeProcessor(slot_, str_, flags_) { }
     378                 :            : 
     379                 :            :     /** Check for a valid numeric range.
     380                 :            :      *
     381                 :            :      *  If BEGIN..END is a valid numeric range with the specified prefix/suffix
     382                 :            :      *  (if one was specified), the prefix/suffix is removed, the string
     383                 :            :      *  converted to a number, and encoded with Xapian::sortable_serialise(),
     384                 :            :      *  and a value range query is built.
     385                 :            :      *
     386                 :            :      *  @param begin    The start of the range as specified in the query string
     387                 :            :      *                  by the user.
     388                 :            :      *  @param end      The end of the range as specified in the query string
     389                 :            :      *                  by the user.
     390                 :            :      */
     391                 :            :     Xapian::Query operator()(const std::string& begin, const std::string& end);
     392                 :            : };
     393                 :            : 
     394                 :            : /** Handle a byte unit range.
     395                 :            :  *
     396                 :            :  *  This class must be used on values which have been encoded using
     397                 :            :  *  Xapian::sortable_serialise() which turns numbers into strings which
     398                 :            :  *  will sort in the same order as the numbers (the same values can be
     399                 :            :  *  used to implement a numeric sort).
     400                 :            :  */
     401         [ -  + ]:          2 : class XAPIAN_VISIBILITY_DEFAULT UnitRangeProcessor : public RangeProcessor {
     402                 :            :   public:
     403                 :            :     /** Constructor.
     404                 :            :      *
     405                 :            :      *  @param slot_    The value slot number to query.
     406                 :            :      *
     407                 :            :      *  @param str_     A string to look for to recognise values as belonging
     408                 :            :      *                  to this numeric range.
     409                 :            :      *
     410                 :            :      *  The string supplied in str_ is the prefix plus ":" that defines the field
     411                 :            :      *  upon which the range query is performed.
     412                 :            :      *
     413                 :            :      *  For example, if str_ is "size:", and the range
     414                 :            :      *  processor has been added to the queryparser, the queryparser will
     415                 :            :      *  accept "size:3K..10K" as a valid range.
     416                 :            :      */
     417                 :          1 :     UnitRangeProcessor(Xapian::valueno slot_,
     418                 :            :                        const std::string &str_ = std::string())
     419                 :          1 :         : RangeProcessor(slot_, str_) { }
     420                 :            : 
     421                 :            :     /** Check for a valid byte value range.
     422                 :            :      *
     423                 :            :      *  If BEGIN..END is a valid numeric byte range with the specified prefix
     424                 :            :      *  the prefix is removed, the string converted to a number, unit
     425                 :            :      *  normalized and encoded with Xapian::sortable_serialise(),
     426                 :            :      *  and a value range query is built.
     427                 :            :      *
     428                 :            :      *  @param begin    The start of the range as specified in the query string
     429                 :            :      *                  by the user.
     430                 :            :      *  @param end      The end of the range as specified in the query string
     431                 :            :      *                  by the user.
     432                 :            :      */
     433                 :            :     Xapian::Query operator()(const std::string& begin, const std::string& end);
     434                 :            : };
     435                 :            : 
     436                 :            : /** Base class for field processors.
     437                 :            :  */
     438                 :            : class XAPIAN_VISIBILITY_DEFAULT FieldProcessor
     439                 :            :     : public Xapian::Internal::opt_intrusive_base {
     440                 :            :     /// Don't allow assignment.
     441                 :            :     void operator=(const FieldProcessor &);
     442                 :            : 
     443                 :            :     /// Don't allow copying.
     444                 :            :     FieldProcessor(const FieldProcessor &);
     445                 :            : 
     446                 :            :   public:
     447                 :            :     /// Default constructor.
     448                 :         14 :     FieldProcessor() { }
     449                 :            : 
     450                 :            :     /// Destructor.
     451                 :            :     virtual ~FieldProcessor();
     452                 :            : 
     453                 :            :     /** Convert a field-prefixed string to a Query object.
     454                 :            :      *
     455                 :            :      *  @param str      The string to convert.
     456                 :            :      *
     457                 :            :      *  @return Query object corresponding to @a str.
     458                 :            :      */
     459                 :            :     virtual Xapian::Query operator()(const std::string &str) = 0;
     460                 :            : 
     461                 :            :     /** Start reference counting this object.
     462                 :            :      *
     463                 :            :      *  You can hand ownership of a dynamically allocated FieldProcessor
     464                 :            :      *  object to Xapian by calling release() and then passing the object to a
     465                 :            :      *  Xapian method.  Xapian will arrange to delete the object once it is no
     466                 :            :      *  longer required.
     467                 :            :      */
     468                 :          4 :     FieldProcessor * release() {
     469                 :          4 :         opt_intrusive_base::release();
     470                 :          4 :         return this;
     471                 :            :     }
     472                 :            : 
     473                 :            :     /** Start reference counting this object.
     474                 :            :      *
     475                 :            :      *  You can hand ownership of a dynamically allocated FieldProcessor
     476                 :            :      *  object to Xapian by calling release() and then passing the object to a
     477                 :            :      *  Xapian method.  Xapian will arrange to delete the object once it is no
     478                 :            :      *  longer required.
     479                 :            :      */
     480                 :            :     const FieldProcessor * release() const {
     481                 :            :         opt_intrusive_base::release();
     482                 :            :         return this;
     483                 :            :     }
     484                 :            : };
     485                 :            : 
     486                 :            : /// Build a Xapian::Query object from a user query string.
     487                 :          8 : class XAPIAN_VISIBILITY_DEFAULT QueryParser {
     488                 :            :   public:
     489                 :            :     /// Class representing the queryparser internals.
     490                 :            :     class Internal;
     491                 :            :     /// @private @internal Reference counted internals.
     492                 :            :     Xapian::Internal::intrusive_ptr_nonnull<Internal> internal;
     493                 :            : 
     494                 :            :     /// Enum of feature flags.
     495                 :            :     typedef enum {
     496                 :            :         /// Support AND, OR, etc and bracketed subexpressions.
     497                 :            :         FLAG_BOOLEAN = 1,
     498                 :            :         /// Support quoted phrases.
     499                 :            :         FLAG_PHRASE = 2,
     500                 :            :         /// Support + and -.
     501                 :            :         FLAG_LOVEHATE = 4,
     502                 :            :         /// Support AND, OR, etc even if they aren't in ALLCAPS.
     503                 :            :         FLAG_BOOLEAN_ANY_CASE = 8,
     504                 :            :         /** Support wildcards.
     505                 :            :          *
     506                 :            :          *  This flag only enables support for right truncation (e.g. Xap*) -
     507                 :            :          *  see FLAG_WILDCARD_MULTI, FLAG_WILDCARD_SINGLE and FLAG_WILDCARD_GLOB
     508                 :            :          *  for extended wildcard support.
     509                 :            :          *
     510                 :            :          *  Currently you can't use wildcards with boolean filter prefixes,
     511                 :            :          *  or in a phrase (either an explicitly quoted one, or one implicitly
     512                 :            :          *  generated by hyphens or other punctuation).
     513                 :            :          *
     514                 :            :          *  In Xapian 1.2.x, you needed to tell the QueryParser object which
     515                 :            :          *  database to expand wildcards from by calling set_database().  In
     516                 :            :          *  Xapian 1.3.3, OP_WILDCARD was added and wildcards are now
     517                 :            :          *  expanded when Enquire::get_mset() is called, with the expansion
     518                 :            :          *  using the database being searched.
     519                 :            :          */
     520                 :            :         FLAG_WILDCARD = 16,
     521                 :            :         /** Allow queries such as 'NOT apples'.
     522                 :            :          *
     523                 :            :          *  These require the use of a list of all documents in the database
     524                 :            :          *  which is potentially expensive, so this feature isn't enabled by
     525                 :            :          *  default.
     526                 :            :          */
     527                 :            :         FLAG_PURE_NOT = 32,
     528                 :            :         /** Enable partial matching.
     529                 :            :          *
     530                 :            :          *  Partial matching causes the parser to treat the query as a
     531                 :            :          *  "partially entered" search.  This will automatically treat the
     532                 :            :          *  final word as a wildcarded match, unless it is followed by
     533                 :            :          *  whitespace, to produce more stable results from interactive
     534                 :            :          *  searches.
     535                 :            :          *
     536                 :            :          *  Currently FLAG_PARTIAL doesn't do anything if the final word
     537                 :            :          *  in the query has a boolean filter prefix, or if it is in a phrase
     538                 :            :          *  (either an explicitly quoted one, or one implicitly generated by
     539                 :            :          *  hyphens or other punctuation).  It also doesn't do anything if
     540                 :            :          *  if the final word is part of a value range.
     541                 :            :          *
     542                 :            :          *  In Xapian 1.2.x, you needed to tell the QueryParser object which
     543                 :            :          *  database to expand wildcards from by calling set_database().  In
     544                 :            :          *  Xapian 1.3.3, OP_WILDCARD was added and wildcards are now
     545                 :            :          *  expanded when Enquire::get_mset() is called, with the expansion
     546                 :            :          *  using the database being searched.
     547                 :            :          */
     548                 :            :         FLAG_PARTIAL = 64,
     549                 :            : 
     550                 :            :         /** Enable spelling correction.
     551                 :            :          *
     552                 :            :          *  For each word in the query which doesn't exist as a term in the
     553                 :            :          *  database, Database::get_spelling_suggestion() will be called and if
     554                 :            :          *  a suggestion is returned, a corrected version of the query string
     555                 :            :          *  will be built up which can be read using
     556                 :            :          *  QueryParser::get_corrected_query_string().  The query returned is
     557                 :            :          *  based on the uncorrected query string however - if you want a
     558                 :            :          *  parsed query based on the corrected query string, you must call
     559                 :            :          *  QueryParser::parse_query() again.
     560                 :            :          *
     561                 :            :          *  NB: You must also call set_database() for this to work.
     562                 :            :          */
     563                 :            :         FLAG_SPELLING_CORRECTION = 128,
     564                 :            : 
     565                 :            :         /** Enable synonym operator '~'.
     566                 :            :          *
     567                 :            :          *  NB: You must also call set_database() for this to work.
     568                 :            :          */
     569                 :            :         FLAG_SYNONYM = 256,
     570                 :            : 
     571                 :            :         /** Enable automatic use of synonyms for single terms.
     572                 :            :          *
     573                 :            :          *  NB: You must also call set_database() for this to work.
     574                 :            :          */
     575                 :            :         FLAG_AUTO_SYNONYMS = 512,
     576                 :            : 
     577                 :            :         /** Enable automatic use of synonyms for single terms and groups of
     578                 :            :          *  terms.
     579                 :            :          *
     580                 :            :          *  NB: You must also call set_database() for this to work.
     581                 :            :          */
     582                 :            :         FLAG_AUTO_MULTIWORD_SYNONYMS = 1024,
     583                 :            : 
     584                 :            :         /** Enable generation of n-grams from CJK text.
     585                 :            :          *
     586                 :            :          *  With this enabled, spans of CJK characters are split into unigrams
     587                 :            :          *  and bigrams, with the unigrams carrying positional information.
     588                 :            :          *  Non-CJK characters are split into words as normal.
     589                 :            :          *
     590                 :            :          *  The corresponding option needs to have been used at index time.
     591                 :            :          *
     592                 :            :          *  Flag added in Xapian 1.3.4 and 1.2.22, but this mode can be
     593                 :            :          *  enabled in 1.2.8 and later by setting environment variable
     594                 :            :          *  XAPIAN_CJK_NGRAM.
     595                 :            :          */
     596                 :            :         FLAG_CJK_NGRAM = 2048,
     597                 :            : 
     598                 :            :         /** Support extended wildcard '*'.
     599                 :            :          *
     600                 :            :          *  This flag enables support for wildcard '*' matching zero
     601                 :            :          *  or more characters, which may be used anywhere in a word.
     602                 :            :          *
     603                 :            :          *  Such wildcards can be relatively expensive to expand and to match
     604                 :            :          *  so benchmark your system carefully if you have a lot of documents
     605                 :            :          *  and/or a high search load.
     606                 :            :          *
     607                 :            :          *  FLAG_WILDCARD is ignored if this flag is specified.
     608                 :            :          *
     609                 :            :          *  @since Added in Xapian 1.5.0.
     610                 :            :          */
     611                 :            :         FLAG_WILDCARD_MULTI = 8192,
     612                 :            : 
     613                 :            :         /** Support extended wildcard '?'.
     614                 :            :          *
     615                 :            :          *  This flag enables support for wildcard '?' matching exactly one
     616                 :            :          *  character, which may be use anywhere in a word.
     617                 :            :          *
     618                 :            :          *  Such wildcards can be relatively expensive to expand and to match
     619                 :            :          *  so benchmark your system carefully if you have a lot of documents
     620                 :            :          *  and/or a high search load.
     621                 :            :          *
     622                 :            :          *  FLAG_WILDCARD is ignored if this flag is specified.
     623                 :            :          *
     624                 :            :          *  @since Added in Xapian 1.5.0.
     625                 :            :          */
     626                 :            :         FLAG_WILDCARD_SINGLE = 16384,
     627                 :            : 
     628                 :            :         /** Enable glob-style wildcarding.
     629                 :            :          *
     630                 :            :          *  This enables all supported glob-style wildcard pattern flags
     631                 :            :          *  - currently that's FLAG_WILDCARD_MULTI and FLAG_WILDCARD_SINGLE.
     632                 :            :          *
     633                 :            :          *  FLAG_WILDCARD is ignored if this flag is specified.
     634                 :            :          *
     635                 :            :          *  @since Added in Xapian 1.5.0.
     636                 :            :          */
     637                 :            :         FLAG_WILDCARD_GLOB = FLAG_WILDCARD_MULTI | FLAG_WILDCARD_SINGLE,
     638                 :            : 
     639                 :            :         /** The default flags.
     640                 :            :          *
     641                 :            :          *  Used if you don't explicitly pass any to @a parse_query().
     642                 :            :          *  The default flags are FLAG_PHRASE|FLAG_BOOLEAN|FLAG_LOVEHATE.
     643                 :            :          *
     644                 :            :          *  Added in Xapian 1.0.11.
     645                 :            :          */
     646                 :            :         FLAG_DEFAULT = FLAG_PHRASE|FLAG_BOOLEAN|FLAG_LOVEHATE
     647                 :            :     } feature_flag;
     648                 :            : 
     649                 :            :     /// Stemming strategies, for use with set_stemming_strategy().
     650                 :            :     typedef enum {
     651                 :            :         STEM_NONE, STEM_SOME, STEM_ALL, STEM_ALL_Z, STEM_SOME_FULL_POS
     652                 :            :     } stem_strategy;
     653                 :            : 
     654                 :            :     /// Copy constructor.
     655                 :            :     QueryParser(const QueryParser & o);
     656                 :            : 
     657                 :            :     /// Assignment.
     658                 :            :     QueryParser & operator=(const QueryParser & o);
     659                 :            : 
     660                 :            :     /// Move constructor.
     661                 :            :     QueryParser(QueryParser && o);
     662                 :            : 
     663                 :            :     /// Move assignment operator.
     664                 :            :     QueryParser & operator=(QueryParser && o);
     665                 :            : 
     666                 :            :     /// Default constructor.
     667                 :            :     QueryParser();
     668                 :            : 
     669                 :            :     /// Destructor.
     670                 :            :     ~QueryParser();
     671                 :            : 
     672                 :            :     /** Set the stemmer.
     673                 :            :      *
     674                 :            :      *  This sets the stemming algorithm which will be used by the query
     675                 :            :      *  parser.  The stemming algorithm will be used according to the stemming
     676                 :            :      *  strategy set by set_stemming_strategy().  As of 1.3.1, this defaults
     677                 :            :      *  to STEM_SOME, but in earlier versions the default was STEM_NONE.  If
     678                 :            :      *  you want to work with older versions, you should explicitly set
     679                 :            :      *  a stemming strategy as well as setting a stemmer, otherwise your
     680                 :            :      *  stemmer won't actually be used.
     681                 :            :      *
     682                 :            :      *  @param stemmer  The Xapian::Stem object to set.
     683                 :            :      */
     684                 :            :     void set_stemmer(const Xapian::Stem & stemmer);
     685                 :            : 
     686                 :            :     /** Set the stemming strategy.
     687                 :            :      *
     688                 :            :      *  This controls how the query parser will apply the stemming algorithm.
     689                 :            :      *  Note that the stemming algorithm is only applied to words in free-text
     690                 :            :      *  fields - boolean filter terms are never stemmed.
     691                 :            :      *
     692                 :            :      *  @param strategy The strategy to use - possible values are:
     693                 :            :      *   - STEM_NONE:   Don't perform any stemming.  (default in Xapian <=
     694                 :            :      *                  1.3.0)
     695                 :            :      *   - STEM_SOME:   Stem all terms except for those which start with a
     696                 :            :      *                  capital letter, or are followed by certain characters
     697                 :            :      *                  (currently: <code>(/\@<>=*[{"</code> ), or are used
     698                 :            :      *                  with operators which need positional information.
     699                 :            :      *                  Stemmed terms are prefixed with 'Z'.  (default in
     700                 :            :      *                  Xapian >= 1.3.1)
     701                 :            :      *   - STEM_SOME_FULL_POS:
     702                 :            :      *                  Like STEM_SOME but also stems terms used with operators
     703                 :            :      *                  which need positional information.  Added in Xapian
     704                 :            :      *                  1.4.8.
     705                 :            :      *   - STEM_ALL:    Stem all terms (note: no 'Z' prefix is added).
     706                 :            :      *   - STEM_ALL_Z:  Stem all terms (note: 'Z' prefix is added).  (new in
     707                 :            :      *                  Xapian 1.2.11 and 1.3.1)
     708                 :            :      */
     709                 :            :     void set_stemming_strategy(stem_strategy strategy);
     710                 :            : 
     711                 :            :     /** Set the stopper.
     712                 :            :      *
     713                 :            :      *  @param stop     The Stopper object to set (default NULL, which means no
     714                 :            :      *                  stopwords).
     715                 :            :      */
     716                 :            :     void set_stopper(const Stopper *stop = NULL);
     717                 :            : 
     718                 :            :     /** Set the default operator.
     719                 :            :      *
     720                 :            :      *  @param default_op       The operator to use to combine non-filter
     721                 :            :      *                          query items when no explicit operator is used.
     722                 :            :      *
     723                 :            :      *                          So for example, 'weather forecast' is parsed as
     724                 :            :      *                          if it were 'weather OR forecast' by default.
     725                 :            :      *
     726                 :            :      *                          The most useful values for this are OP_OR (the
     727                 :            :      *                          default) and OP_AND.  OP_NEAR, OP_PHRASE,
     728                 :            :      *                          OP_ELITE_SET, OP_SYNONYM and OP_MAX are also
     729                 :            :      *                          permitted.  Passing other values will result in
     730                 :            :      *                          InvalidArgumentError being thrown.
     731                 :            :      */
     732                 :            :     void set_default_op(Query::op default_op);
     733                 :            : 
     734                 :            :     /** Get the current default operator. */
     735                 :            :     Query::op get_default_op() const;
     736                 :            : 
     737                 :            :     /** Specify the database being searched.
     738                 :            :      *
     739                 :            :      *  @param db       The database to use for spelling correction
     740                 :            :      *                  (FLAG_SPELLING_CORRECTION), and synonyms (FLAG_SYNONYM,
     741                 :            :      *                  FLAG_AUTO_SYNONYMS, and FLAG_AUTO_MULTIWORD_SYNONYMS).
     742                 :            :      */
     743                 :            :     void set_database(const Database &db);
     744                 :            : 
     745                 :            :     /** Specify the maximum expansion of a wildcard and/or partial term.
     746                 :            :      *
     747                 :            :      *  Note: you must also set FLAG_WILDCARD and/or FLAG_PARTIAL in the flags
     748                 :            :      *  parameter to @a parse_query() for this setting to have anything to
     749                 :            :      *  affect.
     750                 :            :      *
     751                 :            :      *  If you don't call this method, the default settings are no limit on
     752                 :            :      *  wildcard expansion, and partial terms expanding to the most frequent
     753                 :            :      *  100 terms - i.e. as if you'd called:
     754                 :            :      *
     755                 :            :      *  set_max_expansion(0);
     756                 :            :      *  set_max_expansion(100, Xapian::Query::WILDCARD_LIMIT_MOST_FREQUENT, Xapian::QueryParser::FLAG_PARTIAL);
     757                 :            :      *
     758                 :            :      *  @param max_expansion  The maximum number of terms each wildcard in the
     759                 :            :      *                  query can expand to, or 0 for no limit (which is the
     760                 :            :      *                  default).
     761                 :            :      *  @param max_type @a Xapian::Query::WILDCARD_LIMIT_ERROR,
     762                 :            :      *                  @a Xapian::Query::WILDCARD_LIMIT_FIRST or
     763                 :            :      *                  @a Xapian::Query::WILDCARD_LIMIT_MOST_FREQUENT
     764                 :            :      *                  (default: Xapian::Query::WILDCARD_LIMIT_ERROR).
     765                 :            :      *  @param flags    What to set the limit for (default:
     766                 :            :      *                  FLAG_WILDCARD|FLAG_PARTIAL, setting the limit for both
     767                 :            :      *                  wildcards and partial terms).
     768                 :            :      *
     769                 :            :      *  @since 1.3.3
     770                 :            :      */
     771                 :            :     void set_max_expansion(Xapian::termcount max_expansion,
     772                 :            :                            int max_type = Xapian::Query::WILDCARD_LIMIT_ERROR,
     773                 :            :                            unsigned flags = FLAG_WILDCARD|FLAG_PARTIAL);
     774                 :            : 
     775                 :            :     /** Specify minimum length for fixed initial portion in wildcard patterns.
     776                 :            :      *
     777                 :            :      *  It can be desirable for performance reasons to restrict use of
     778                 :            :      *  wildcards to patterns with a fixed initial portion, so this method
     779                 :            :      *  provides a way to specify a minimum length.  A wildcard pattern
     780                 :            :      *  with a shorter (or no) fixed initial portion will result in
     781                 :            :      *  Xapian::QueryParser being thrown.  The default minimum length is 0.
     782                 :            :      *
     783                 :            :      *  It also provides a way to specify the minimum length of a word to
     784                 :            :      *  expand for partial matching (see @a FLAG_PARTIAL).  In this case
     785                 :            :      *  a shorter word at the end of the query simply result in no partial
     786                 :            :      *  matching.  The default minimum length for this case is 2 (since
     787                 :            :      *  1.5.0 - in earlier versions it was effectively 0).
     788                 :            :      *
     789                 :            :      *  @param min_prefix_len   Minimum length of fixed initial portion in
     790                 :            :      *                          Unicode characters.
     791                 :            :      *  @param flags            What to set the minimum length for
     792                 :            :      *                          (default: FLAG_WILDCARD|FLAG_PARTIAL, setting
     793                 :            :      *                          the limit for both wildcards and partial
     794                 :            :      *                          terms).
     795                 :            :      *
     796                 :            :      *  Added in Xapian 1.5.0.
     797                 :            :      */
     798                 :            :     void set_min_wildcard_prefix(unsigned min_prefix_len,
     799                 :            :                                  unsigned flags = FLAG_WILDCARD|FLAG_PARTIAL);
     800                 :            : 
     801                 :            :     /** Parse a query.
     802                 :            :      *
     803                 :            :      *  @param query_string  A free-text query as entered by a user
     804                 :            :      *  @param flags         Zero or more QueryParser::feature_flag specifying
     805                 :            :      *          what features the QueryParser should support.  Combine
     806                 :            :      *          multiple values with bitwise-or (|) (default FLAG_DEFAULT).
     807                 :            :      *  @param default_prefix  The default term prefix to use (default none).
     808                 :            :      *          For example, you can pass "A" when parsing an "Author" field.
     809                 :            :      *
     810                 :            :      *  @exception If the query string can't be parsed, then
     811                 :            :      *             Xapian::QueryParserError is thrown.  You can get an English
     812                 :            :      *             error message to report to the user by catching it and
     813                 :            :      *             calling get_msg() on the caught exception.  The current
     814                 :            :      *             possible values (in case you want to translate them) are:
     815                 :            :      *
     816                 :            :      *             @li Unknown range operation
     817                 :            :      *             @li parse error
     818                 :            :      *             @li Syntax: &lt;expression&gt; AND &lt;expression&gt;
     819                 :            :      *             @li Syntax: &lt;expression&gt; AND NOT &lt;expression&gt;
     820                 :            :      *             @li Syntax: &lt;expression&gt; NOT &lt;expression&gt;
     821                 :            :      *             @li Syntax: &lt;expression&gt; OR &lt;expression&gt;
     822                 :            :      *             @li Syntax: &lt;expression&gt; XOR &lt;expression&gt;
     823                 :            :      */
     824                 :            :     Query parse_query(const std::string &query_string,
     825                 :            :                       unsigned flags = FLAG_DEFAULT,
     826                 :            :                       const std::string &default_prefix = std::string());
     827                 :            : 
     828                 :            :     /** Add a free-text field term prefix.
     829                 :            :      *
     830                 :            :      *  For example:
     831                 :            :      *
     832                 :            :      *  @code
     833                 :            :      *  qp.add_prefix("author", "A");
     834                 :            :      *  @endcode
     835                 :            :      *
     836                 :            :      *  This allows the user to search for author:Orwell which will be
     837                 :            :      *  converted to a search for the term "Aorwell".
     838                 :            :      *
     839                 :            :      *  Multiple fields can be mapped to the same prefix.  For example, you
     840                 :            :      *  can make title: and subject: aliases for each other.
     841                 :            :      *
     842                 :            :      *  As of 1.0.4, you can call this method multiple times with the same
     843                 :            :      *  value of field to allow a single field to be mapped to multiple
     844                 :            :      *  prefixes.  Multiple terms being generated for such a field, and
     845                 :            :      *  combined with @c Xapian::Query::OP_OR.
     846                 :            :      *
     847                 :            :      *  If any prefixes are specified for the empty field name (i.e. you
     848                 :            :      *  call this method with an empty string as the first parameter)
     849                 :            :      *  these prefixes will be used for terms without a field specifier.
     850                 :            :      *  If you do this and also specify the @c default_prefix parameter to @c
     851                 :            :      *  parse_query(), then the @c default_prefix parameter will override.
     852                 :            :      *
     853                 :            :      *  If the prefix parameter is empty, then "field:word" will produce the
     854                 :            :      *  term "word" (and this can be one of several prefixes for a particular
     855                 :            :      *  field, or for terms without a field specifier).
     856                 :            :      *
     857                 :            :      *  If you call @c add_prefix() and @c add_boolean_prefix() for the
     858                 :            :      *  same value of @a field, a @c Xapian::InvalidOperationError exception
     859                 :            :      *  will be thrown.
     860                 :            :      *
     861                 :            :      *  In 1.0.3 and earlier, subsequent calls to this method with the same
     862                 :            :      *  value of @a field had no effect.
     863                 :            :      *
     864                 :            :      *  @param field   The user visible field name
     865                 :            :      *  @param prefix  The term prefix to map this to
     866                 :            :      */
     867                 :            :     void add_prefix(const std::string& field, const std::string& prefix);
     868                 :            : 
     869                 :            :     /** Register a FieldProcessor.
     870                 :            :      */
     871                 :            :     void add_prefix(const std::string& field, Xapian::FieldProcessor * proc);
     872                 :            : 
     873                 :            :     /** Add a boolean term prefix allowing the user to restrict a
     874                 :            :      *  search with a boolean filter specified in the free text query.
     875                 :            :      *
     876                 :            :      *  For example:
     877                 :            :      *
     878                 :            :      *  @code
     879                 :            :      *  qp.add_boolean_prefix("site", "H");
     880                 :            :      *  @endcode
     881                 :            :      *
     882                 :            :      *  This allows the user to restrict a search with site:xapian.org which
     883                 :            :      *  will be converted to Hxapian.org combined with any weighted
     884                 :            :      *  query with @c Xapian::Query::OP_FILTER.
     885                 :            :      *
     886                 :            :      *  If multiple boolean filters are specified in a query for the same
     887                 :            :      *  prefix, they will be combined with the @c Xapian::Query::OP_OR
     888                 :            :      *  operator.  Then, if there are boolean filters for different prefixes,
     889                 :            :      *  they will be combined with the @c Xapian::Query::OP_AND operator.
     890                 :            :      *
     891                 :            :      *  Multiple fields can be mapped to the same prefix (so for example
     892                 :            :      *  you can make site: and domain: aliases for each other).  Instances of
     893                 :            :      *  fields with different aliases but the same prefix will still be
     894                 :            :      *  combined with the OR operator.
     895                 :            :      *
     896                 :            :      *  For example, if "site" and "domain" map to "H", but author maps to "A",
     897                 :            :      *  a search for "site:foo domain:bar author:Fred" will map to
     898                 :            :      *  "(Hfoo OR Hbar) AND Afred".
     899                 :            :      *
     900                 :            :      *  As of 1.0.4, you can call this method multiple times with the same
     901                 :            :      *  value of field to allow a single field to be mapped to multiple
     902                 :            :      *  prefixes.  Multiple terms being generated for such a field, and
     903                 :            :      *  combined with @c Xapian::Query::OP_OR.
     904                 :            :      *
     905                 :            :      *  Calling this method with an empty string for @a field will cause
     906                 :            :      *  a @c Xapian::InvalidArgumentError.
     907                 :            :      *
     908                 :            :      *  If you call @c add_prefix() and @c add_boolean_prefix() for the
     909                 :            :      *  same value of @a field, a @c Xapian::InvalidOperationError exception
     910                 :            :      *  will be thrown.
     911                 :            :      *
     912                 :            :      *  In 1.0.3 and earlier, subsequent calls to this method with the same
     913                 :            :      *  value of @a field had no effect.
     914                 :            :      *
     915                 :            :      *  @param field   The user visible field name
     916                 :            :      *  @param prefix  The term prefix to map this to
     917                 :            :      *  @param grouping Controls how multiple filters are combined - filters
     918                 :            :      *                  with the same grouping value are combined with OP_OR,
     919                 :            :      *                  then the resulting queries are combined with OP_AND.
     920                 :            :      *                  If NULL, then @a field is used for grouping.  If an
     921                 :            :      *                  empty string, then a unique grouping is created for
     922                 :            :      *                  each filter (this is sometimes useful when each
     923                 :            :      *                  document can have multiple terms with this prefix).
     924                 :            :      *                  [default: NULL]
     925                 :            :      */
     926                 :            :     void add_boolean_prefix(const std::string &field, const std::string &prefix,
     927                 :            :                             const std::string* grouping = NULL);
     928                 :            : 
     929                 :            :     /** Add a boolean term prefix allowing the user to restrict a
     930                 :            :      *  search with a boolean filter specified in the free text query.
     931                 :            :      *
     932                 :            :      *  This is an older version of this method - use the version with
     933                 :            :      *  the `grouping` parameter in preference to this one.
     934                 :            :      *
     935                 :            :      *  @param field   The user visible field name
     936                 :            :      *  @param prefix  The term prefix to map this to
     937                 :            :      *  @param exclusive Controls how multiple filters are combined.  If
     938                 :            :      *                  true then @a prefix is used as the `grouping` value,
     939                 :            :      *                  so terms with the same prefix are combined with OP_OR,
     940                 :            :      *                  then the resulting queries are combined with OP_AND.
     941                 :            :      *                  If false, then a unique grouping is created for
     942                 :            :      *                  each filter (this is sometimes useful when each
     943                 :            :      *                  document can have multiple terms with this prefix).
     944                 :            :      */
     945                 :          6 :     void add_boolean_prefix(const std::string &field, const std::string &prefix,
     946                 :            :                             bool exclusive) {
     947         [ -  + ]:          6 :         if (exclusive) {
     948                 :          0 :             add_boolean_prefix(field, prefix);
     949                 :            :         } else {
     950         [ +  - ]:          6 :             std::string empty_grouping;
     951         [ +  - ]:          6 :             add_boolean_prefix(field, prefix, &empty_grouping);
     952                 :            :         }
     953                 :          6 :     }
     954                 :            : 
     955                 :            :     /** Register a FieldProcessor for a boolean prefix.
     956                 :            :      */
     957                 :            :     void add_boolean_prefix(const std::string &field, Xapian::FieldProcessor *proc,
     958                 :            :                             const std::string* grouping = NULL);
     959                 :            : 
     960                 :            :     /** Register a FieldProcessor for a boolean prefix.
     961                 :            :      *
     962                 :            :      *  This is an older version of this method - use the version with
     963                 :            :      *  the `grouping` parameter in preference to this one.
     964                 :            :      */
     965                 :            :     void add_boolean_prefix(const std::string &field, Xapian::FieldProcessor *proc,
     966                 :            :                             bool exclusive) {
     967                 :            :         if (exclusive) {
     968                 :            :             add_boolean_prefix(field, proc);
     969                 :            :         } else {
     970                 :            :             std::string empty_grouping;
     971                 :            :             add_boolean_prefix(field, proc, &empty_grouping);
     972                 :            :         }
     973                 :            :     }
     974                 :            : 
     975                 :            :     /// Begin iterator over terms omitted from the query as stopwords.
     976                 :            :     TermIterator stoplist_begin() const;
     977                 :            : 
     978                 :            :     /// End iterator over terms omitted from the query as stopwords.
     979                 :          5 :     TermIterator XAPIAN_NOTHROW(stoplist_end() const) {
     980                 :          5 :         return TermIterator();
     981                 :            :     }
     982                 :            : 
     983                 :            :     /// Begin iterator over unstemmed forms of the given stemmed query term.
     984                 :            :     TermIterator unstem_begin(const std::string &term) const;
     985                 :            : 
     986                 :            :     /// End iterator over unstemmed forms of the given stemmed query term.
     987                 :          2 :     TermIterator XAPIAN_NOTHROW(unstem_end(const std::string &) const) {
     988                 :          2 :         return TermIterator();
     989                 :            :     }
     990                 :            : 
     991                 :            :     /// Register a RangeProcessor.
     992                 :            :     void add_rangeprocessor(Xapian::RangeProcessor * range_proc,
     993                 :            :                             const std::string* grouping = NULL);
     994                 :            : 
     995                 :            :     /** Get the spelling-corrected query string.
     996                 :            :      *
     997                 :            :      *  This will only be set if FLAG_SPELLING_CORRECTION is specified when
     998                 :            :      *  QueryParser::parse_query() was last called.
     999                 :            :      *
    1000                 :            :      *  If there were no corrections, an empty string is returned.
    1001                 :            :      */
    1002                 :            :     std::string get_corrected_query_string() const;
    1003                 :            : 
    1004                 :            :     /// Return a string describing this object.
    1005                 :            :     std::string get_description() const;
    1006                 :            : };
    1007                 :            : 
    1008                 :            : /// @private @internal Helper for sortable_serialise().
    1009                 :            : XAPIAN_VISIBILITY_DEFAULT
    1010                 :            : size_t XAPIAN_NOTHROW(sortable_serialise_(double value, char * buf));
    1011                 :            : 
    1012                 :            : /** Convert a floating point number to a string, preserving sort order.
    1013                 :            :  *
    1014                 :            :  *  This method converts a floating point number to a string, suitable for
    1015                 :            :  *  using as a value for numeric range restriction, or for use as a sort
    1016                 :            :  *  key.
    1017                 :            :  *
    1018                 :            :  *  The conversion is platform independent.
    1019                 :            :  *
    1020                 :            :  *  The conversion attempts to ensure that, for any pair of values supplied
    1021                 :            :  *  to the conversion algorithm, the result of comparing the original
    1022                 :            :  *  values (with a numeric comparison operator) will be the same as the
    1023                 :            :  *  result of comparing the resulting values (with a string comparison
    1024                 :            :  *  operator).  On platforms which represent doubles with the precisions
    1025                 :            :  *  specified by IEEE_754, this will be the case: if the representation of
    1026                 :            :  *  doubles is more precise, it is possible that two very close doubles
    1027                 :            :  *  will be mapped to the same string, so will compare equal.
    1028                 :            :  *
    1029                 :            :  *  Note also that both zero and -zero will be converted to the same
    1030                 :            :  *  representation: since these compare equal, this satisfies the
    1031                 :            :  *  comparison constraint, but it's worth knowing this if you wish to use
    1032                 :            :  *  the encoding in some situation where this distinction matters.
    1033                 :            :  *
    1034                 :            :  *  Handling of NaN isn't (currently) guaranteed to be sensible.
    1035                 :            :  *
    1036                 :            :  *  @param value        The number to serialise.
    1037                 :            :  */
    1038                 :     310341 : inline std::string sortable_serialise(double value) {
    1039                 :            :     char buf[9];
    1040         [ +  - ]:     310341 :     return std::string(buf, sortable_serialise_(value, buf));
    1041                 :            : }
    1042                 :            : 
    1043                 :            : /** Convert a string encoded using @a sortable_serialise back to a floating
    1044                 :            :  *  point number.
    1045                 :            :  *
    1046                 :            :  *  This expects the input to be a string produced by @a sortable_serialise().
    1047                 :            :  *  If the input is not such a string, the value returned is undefined (but
    1048                 :            :  *  no error will be thrown).
    1049                 :            :  *
    1050                 :            :  *  The result of the conversion will be exactly the value which was
    1051                 :            :  *  supplied to @a sortable_serialise() when making the string on platforms
    1052                 :            :  *  which represent doubles with the precisions specified by IEEE_754, but
    1053                 :            :  *  may be a different (nearby) value on other platforms.
    1054                 :            :  *
    1055                 :            :  *  @param serialised   The serialised string to decode.
    1056                 :            :  */
    1057                 :            : XAPIAN_VISIBILITY_DEFAULT
    1058                 :            : double XAPIAN_NOTHROW(sortable_unserialise(const std::string & serialised));
    1059                 :            : 
    1060                 :            : }
    1061                 :            : 
    1062                 :            : #endif // XAPIAN_INCLUDED_QUERYPARSER_H

Generated by: LCOV version 1.11