LCOV - code coverage report
Current view: top level - api - omquery.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core r Lines: 104 109 95.4 %
Date: 2011-08-21 Functions: 26 36 72.2 %
Branches: 28 50 56.0 %

           Branch data     Line data    Source code
       1                 :            : /* omquery.cc: External interface for running queries
       2                 :            :  *
       3                 :            :  * Copyright 1999,2000,2001 BrightStation PLC
       4                 :            :  * Copyright 2001,2002 Ananova Ltd
       5                 :            :  * Copyright 2003,2004,2005,2006,2007,2008,2009 Olly Betts
       6                 :            :  * Copyright 2006,2007,2008,2009 Lemur Consulting Ltd
       7                 :            :  *
       8                 :            :  * This program is free software; you can redistribute it and/or
       9                 :            :  * modify it under the terms of the GNU General Public License as
      10                 :            :  * published by the Free Software Foundation; either version 2 of the
      11                 :            :  * License, or (at your option) any later version.
      12                 :            :  *
      13                 :            :  * This program is distributed in the hope that it will be useful,
      14                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16                 :            :  * GNU General Public License for more details.
      17                 :            :  *
      18                 :            :  * You should have received a copy of the GNU General Public License
      19                 :            :  * along with this program; if not, write to the Free Software
      20                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
      21                 :            :  * USA
      22                 :            :  */
      23                 :            : 
      24                 :            : #include <config.h>
      25                 :            : 
      26                 :            : #include "omqueryinternal.h"
      27                 :            : 
      28                 :            : #include "debuglog.h"
      29                 :            : #include "omassert.h"
      30                 :            : #include "utils.h"
      31                 :            : 
      32                 :            : #include "xapian/error.h"
      33                 :            : #include "xapian/postingsource.h"
      34                 :            : #include "xapian/registry.h"
      35                 :            : #include "xapian/termiterator.h"
      36                 :            : 
      37                 :            : #include <cmath>
      38                 :            : 
      39                 :            : namespace Xapian {
      40                 :            : 
      41                 :            : /// Add a subquery by reference
      42                 :            : void
      43                 :      91452 : Query::add_subquery(const Query & subq)
      44                 :            : {
      45                 :            :     LOGCALL_VOID(API, "Xapian::Query::add_subquery", subq);
      46                 :            :     Assert(internal.get());
      47                 :      91452 :     internal->add_subquery(subq.internal.get());
      48                 :      91452 : }
      49                 :            : 
      50                 :            : /// Add a subquery by pointer
      51                 :            : void
      52                 :          4 : Query::add_subquery(const Query * subq)
      53                 :            : {
      54                 :            :     LOGCALL_VOID(API, "Xapian::Query::add_subquery", subq);
      55         [ -  + ]:          4 :     if (subq == 0) {
      56                 :          0 :         throw InvalidArgumentError("Pointer to subquery may not be null");
      57                 :            :     }
      58                 :            :     Assert(internal.get());
      59                 :          4 :     internal->add_subquery(subq->internal.get());
      60                 :          4 : }
      61                 :            : 
      62                 :            : /// Add a subquery which is a single term
      63                 :            : void
      64                 :       1226 : Query::add_subquery(const string & tname)
      65                 :            : {
      66                 :            :     LOGCALL_VOID(API, "Xapian::Query::add_subquery", tname);
      67                 :            :     Assert(internal.get());
      68                 :       1226 :     Query::Internal subqint(tname);
      69                 :       1226 :     internal->add_subquery(&subqint);
      70                 :       1226 : }
      71                 :            : 
      72                 :            : /// Setup the internals for the query, with the appropriate operator.
      73                 :            : void
      74                 :      13841 : Query::start_construction(Query::op op_, termcount parameter)
      75                 :            : {
      76                 :            :     LOGCALL_VOID(API, "Xapian::Query::start_construction", op_);
      77                 :            :     Assert(!internal.get());
      78                 :      13841 :     internal = new Query::Internal(op_, parameter);
      79                 :      13841 : }
      80                 :            : 
      81                 :            : /// Check that query has an appropriate number of arguments, etc,
      82                 :            : void
      83                 :      31067 : Query::end_construction()
      84                 :            : {
      85                 :            :     LOGCALL_VOID(API, "Xapian::Query::end_construction", NO_ARGS);
      86                 :            :     Assert(internal.get());
      87                 :      31067 :     internal = internal->end_construction();
      88                 :      30637 : }
      89                 :            : 
      90                 :            : /// Abort construction of the query: delete internal.
      91                 :            : void
      92                 :        430 : Query::abort_construction()
      93                 :            : {
      94                 :            :     LOGCALL_VOID(API, "Xapian::Query::abort_construction", NO_ARGS);
      95                 :            :     Assert(internal.get());
      96                 :        430 :     internal = 0;
      97                 :        430 : }
      98                 :            : 
      99                 :      65876 : Query::Query(const string & tname_, termcount wqf_, termpos pos_)
     100                 :      65876 :         : internal(new Query::Internal(tname_, wqf_, pos_))
     101                 :            : {
     102                 :            :     LOGCALL_VOID(API, "Xapian::Query::Query", tname_ | wqf_ | pos_);
     103                 :      65876 : }
     104                 :            : 
     105                 :      17226 : Query::Query(Query::op op_, const Query &left, const Query &right)
     106                 :      17226 :         : internal(new Query::Internal(op_, 0u))
     107                 :            : {
     108                 :            :     LOGCALL_VOID(API, "Xapian::Query::Query", op_ | left | right);
     109                 :            :     try {
     110                 :      17226 :         add_subquery(left);
     111                 :      17226 :         add_subquery(right);
     112                 :      17226 :         end_construction();
     113                 :          8 :     } catch (...) {
     114                 :          4 :         abort_construction();
     115                 :          4 :         throw;
     116                 :            :     }
     117                 :      17226 : }
     118                 :            : 
     119                 :       4816 : Query::Query(Query::op op_, Xapian::Query q, double parameter)
     120                 :            : {
     121                 :            :     LOGCALL_VOID(API, "Xapian::Query::Query", op_ | q | parameter);
     122   [ +  -  #  # ]:       4816 :     if (op_ == OP_SCALE_WEIGHT) {
     123 [ +  + ][ +  + ]:       4816 :         if (!q.internal.get() ||
         [ +  + ][ -  + ]
         [ +  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     124                 :            :             q.internal->op == OP_VALUE_RANGE ||
     125                 :            :             q.internal->op == OP_VALUE_GE ||
     126                 :            :             q.internal->op == OP_VALUE_LE) {
     127                 :            :             // Applying OP_SCALE_WEIGHT to Xapian::Query or OP_VALUE_*
     128                 :            :             // has no effect as they're all pure-boolean.
     129                 :       3761 :             internal = q.internal;
     130                 :       3761 :             return;
     131                 :            :         }
     132                 :            :     }
     133                 :            :     try {
     134                 :       1055 :         start_construction(op_, 0);
     135                 :       1055 :         internal->set_dbl_parameter(parameter);
     136                 :       1055 :         add_subquery(q);
     137                 :       1055 :         end_construction();
     138                 :        832 :     } catch (...) {
     139                 :        416 :         abort_construction();
     140                 :        416 :         throw;
     141                 :            :     }
     142                 :       4816 : }
     143                 :            : 
     144                 :       5682 : Query::Query(Query::op op_, Xapian::valueno valno,
     145                 :            :              const string &begin, const string &end)
     146                 :       5682 :     : internal(new Query::Internal(op_, valno, begin, end))
     147                 :            : {
     148                 :            :     LOGCALL_VOID(API, "Xapian::Query::Query", op_ | valno | begin | end);
     149                 :       5682 : }
     150                 :            : 
     151                 :        352 : Query::Query(Query::op op_, Xapian::valueno valno, const std::string &value)
     152                 :        352 :     : internal(new Query::Internal(op_, valno, value))
     153                 :            : {
     154                 :            :     LOGCALL_VOID(API, "Xapian::Query::Query", op_ | valno | value);
     155                 :        352 : }
     156                 :            : 
     157                 :        680 : Query::Query(PostingSource * external_source)
     158                 :        680 :         : internal(NULL)
     159                 :            : {
     160                 :            :     LOGCALL_VOID(API, "Xapian::Query::Query", external_source);
     161   [ +  +  #  # ]:        680 :     if (!external_source)
     162                 :          8 :         throw Xapian::InvalidArgumentError("The external_source parameter can not be NULL");
     163                 :        672 :     PostingSource * clone = external_source->clone();
     164   [ +  +  #  # ]:        672 :     if (clone) {
     165                 :        664 :         internal = new Query::Internal(clone, true);
     166                 :            :     } else {
     167                 :          8 :         internal = new Query::Internal(external_source, false);
     168                 :            :     }
     169                 :        680 : }
     170                 :            : 
     171                 :            : // Copy constructor
     172                 :     125134 : Query::Query(const Query & copyme)
     173                 :     125134 :         : internal(copyme.internal)
     174                 :            : {
     175                 :            :     LOGCALL_VOID(API, "Xapian::Query::Query", copyme);
     176                 :     125134 : }
     177                 :            : 
     178                 :            : // Assignment
     179                 :            : Query &
     180                 :      60088 : Query::operator=(const Query & copyme)
     181                 :            : {
     182                 :            :     LOGCALL(API, Xapian::Query &, "Xapian::Query::operator=", copyme);
     183                 :      60088 :     internal = copyme.internal;
     184                 :      60088 :     RETURN(*this);
     185                 :            : }
     186                 :            : 
     187                 :            : // Default constructor
     188                 :      45956 : Query::Query() : internal(0)
     189                 :            : {
     190                 :            :     LOGCALL_VOID(API, "Xapian::Query::Query", NO_ARGS);
     191                 :      45956 : }
     192                 :            : 
     193                 :            : // Destructor
     194                 :     278070 : Query::~Query()
     195                 :            : {
     196                 :            :     LOGCALL_VOID(API, "Xapian::Query::~Query", NO_ARGS);
     197                 :     278070 : }
     198                 :            : 
     199                 :            : std::string
     200                 :         10 : Query::serialise() const
     201                 :            : {
     202                 :            :     LOGCALL(API, std::string, "Xapian::Query::serialise", NO_ARGS);
     203         [ +  + ]:         10 :     if (!internal.get()) return std::string();
     204                 :         10 :     return internal->serialise();
     205                 :            : }
     206                 :            : 
     207                 :            : Query
     208                 :          7 : Query::unserialise(const std::string &s)
     209                 :            : {
     210                 :            :     LOGCALL_STATIC(API, Xapian::Query, "Xapian::Query::unserialise", s);
     211                 :          7 :     Query result;
     212         [ +  + ]:          7 :     if (!s.empty()) {
     213                 :          8 :         result.internal = Xapian::Query::Internal::unserialise(s, Registry());
     214                 :            :     }
     215                 :          1 :     RETURN(result);
     216                 :            : }
     217                 :            : 
     218                 :            : Query
     219                 :          5 : Query::unserialise(const std::string & s, const Registry & reg)
     220                 :            : {
     221                 :            :     LOGCALL_STATIC(API, Xapian::Query, "Xapian::Query::unserialise", s | reg);
     222                 :          5 :     Query result;
     223         [ +  - ]:          5 :     if (!s.empty()) {
     224                 :          5 :         result.internal = Xapian::Query::Internal::unserialise(s, reg);
     225                 :            :     }
     226                 :          1 :     RETURN(result);
     227                 :            : }
     228                 :            : 
     229                 :            : std::string
     230                 :       2095 : Query::get_description() const
     231                 :            : {
     232                 :       2095 :     std::string res("Xapian::Query(");
     233         [ +  + ]:       2095 :     if (internal.get()) res += internal->get_description();
     234                 :       2095 :     res += ")";
     235                 :          0 :     return res;
     236                 :            : }
     237                 :            : 
     238                 :      10516 : termcount Query::get_length() const
     239                 :            : {
     240                 :            :     LOGCALL(API, Xapian::termcount, "Xapian::Query::get_length", NO_ARGS);
     241         [ +  + ]:      10516 :     RETURN(internal.get() ? internal->get_length() : 0);
     242                 :            : }
     243                 :            : 
     244                 :        190 : TermIterator Query::get_terms_begin() const
     245                 :            : {
     246                 :            :     LOGCALL(API, Xapian::TermIterator, "Xapian::Query::get_terms_begin", NO_ARGS);
     247         [ +  + ]:        190 :     if (!internal.get()) RETURN(TermIterator(NULL));
     248                 :        190 :     RETURN(internal->get_terms());
     249                 :            : }
     250                 :            : 
     251                 :            : bool
     252                 :        354 : Query::empty() const
     253                 :            : {
     254                 :            :     LOGCALL_VOID(API, "Xapian::Query::empty", NO_ARGS);
     255                 :        354 :     return internal.get() == 0;
     256                 :            : }
     257                 :            : 
     258                 :         17 : Query::Query(Query::op op_, const std::string & left, const std::string & right)
     259                 :         17 :     : internal(0)
     260                 :            : {
     261                 :            :     try {
     262                 :         17 :         start_construction(op_, 0);
     263                 :         17 :         add_subquery(left);
     264                 :         17 :         add_subquery(right);
     265                 :         17 :         end_construction();
     266                 :          0 :     } catch (...) {
     267                 :          0 :         abort_construction();
     268                 :          0 :         throw;
     269                 :            :     }
     270                 :         17 : }
     271                 :            : 
     272                 :            : /* Define static members. */
     273                 :       2335 : const Xapian::Query Xapian::Query::MatchAll = Xapian::Query(string());
     274                 :       2335 : const Xapian::Query Xapian::Query::MatchNothing = Xapian::Query();
     275                 :            : 
     276 [ +  - ][ +  - ]:       7005 : }

Generated by: LCOV version 1.8