api/omquery.cc

Go to the documentation of this file.
00001 /* omquery.cc: External interface for running queries
00002  *
00003  * Copyright 1999,2000,2001 BrightStation PLC
00004  * Copyright 2001,2002 Ananova Ltd
00005  * Copyright 2003,2004,2005,2006,2007 Olly Betts
00006  * Copyright 2006,2007,2008 Lemur Consulting Ltd
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License as
00010  * published by the Free Software Foundation; either version 2 of the
00011  * License, or (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
00021  * USA
00022  */
00023 
00024 #include <config.h>
00025 
00026 #include "omassert.h"
00027 #include "omdebug.h"
00028 #include "omqueryinternal.h"
00029 #include "utils.h"
00030 
00031 #include <xapian/error.h>
00032 #include <xapian/termiterator.h>
00033 
00034 #include <vector>
00035 #include <map>
00036 #include <algorithm>
00037 #include <math.h>
00038 
00039 namespace Xapian {
00040 
00042 void
00043 Query::add_subquery(const Query & subq)
00044 {
00045     DEBUGAPICALL(void, "Xapian::Query::add_subquery", subq);
00046     Assert(internal.get());
00047     internal->add_subquery(subq.internal.get());
00048 }
00049 
00051 void
00052 Query::add_subquery(const Query * subq)
00053 {
00054     DEBUGAPICALL(void, "Xapian::Query::add_subquery", subq);
00055     if (subq == 0) {
00056         throw InvalidArgumentError("Pointer to subquery may not be null");
00057     }
00058     Assert(internal.get());
00059     internal->add_subquery(subq->internal.get());
00060 }
00061 
00063 void
00064 Query::add_subquery(const string & tname)
00065 {
00066     DEBUGAPICALL(void, "Xapian::Query::add_subquery", tname);
00067     Assert(internal.get());
00068     Query::Internal subqint(tname);
00069     internal->add_subquery(&subqint);
00070 }
00071 
00073 void
00074 Query::start_construction(Query::op op_, termcount parameter)
00075 {
00076     DEBUGAPICALL(void, "Xapian::Query::start_construction", op_);
00077     Assert(!internal.get());
00078     internal = new Query::Internal(op_, parameter);
00079 }
00080 
00082 void
00083 Query::end_construction()
00084 {
00085     DEBUGAPICALL(void, "Xapian::Query::end_construction", "");
00086     Assert(internal.get());
00087     internal = internal->end_construction();
00088 }
00089 
00091 void
00092 Query::abort_construction()
00093 {
00094     DEBUGAPICALL(void, "Xapian::Query::abort_construction", "");
00095     Assert(internal.get());
00096     internal = 0;
00097 }
00098 
00099 Query::Query(const string & tname_, termcount wqf_, termpos pos_)
00100         : internal(new Query::Internal(tname_, wqf_, pos_))
00101 {
00102     DEBUGAPICALL(void, "Xapian::Query::Query",
00103                  tname_ << ", " << wqf_ << ", " << pos_);
00104 }
00105 
00106 Query::Query(Query::op op_, const Query &left, const Query &right)
00107         : internal(new Query::Internal(op_, 0u))
00108 {
00109     DEBUGAPICALL(void, "Xapian::Query::Query",
00110                  op_ << ", " << left << ", " << right);
00111     try {
00112         add_subquery(left);
00113         add_subquery(right);
00114         end_construction();
00115     } catch (...) {
00116         abort_construction();
00117         throw;
00118     }
00119 }
00120 
00121 Query::Query(Query::op op_, Query q) : internal(0)
00122 {
00123     try {
00124         start_construction(op_, 0);
00125         add_subquery(q);
00126         end_construction();
00127     } catch (...) {
00128         abort_construction();
00129         throw;
00130     }
00131 }
00132 
00133 Query::Query(Query::op op_, Xapian::Query q, double parameter)
00134 {
00135     DEBUGAPICALL(void, "Xapian::Query::Query",
00136                  op_ << ", " << q << ", " << parameter);
00137     if (op_ == OP_SCALE_WEIGHT) {
00138         if (!q.internal.get() ||
00139             q.internal->op == OP_VALUE_RANGE ||
00140             q.internal->op == OP_VALUE_GE ||
00141             q.internal->op == OP_VALUE_LE) {
00142             // Applying OP_SCALE_WEIGHT to Xapian::Query or OP_VALUE_*
00143             // has no effect as they're all pure-boolean.
00144             internal = q.internal;
00145             return;
00146         }
00147     }
00148     try {
00149         start_construction(op_, 0);
00150         internal->set_dbl_parameter(parameter);
00151         add_subquery(q);
00152         end_construction();
00153     } catch (...) {
00154         abort_construction();
00155         throw;
00156     }
00157 }
00158 
00159 Query::Query(Query::op op_, Xapian::valueno valno,
00160              const string &begin, const string &end)
00161     : internal(new Query::Internal(op_, valno, begin, end))
00162 {
00163     DEBUGAPICALL(void, "Xapian::Query::Query",
00164                  op_ << ", " << valno << ", " << begin << ", " << end);
00165 }
00166 
00167 Query::Query(Query::op op_, Xapian::valueno valno, const std::string &value)
00168     : internal(new Query::Internal(op_, valno, value))
00169 {
00170     DEBUGAPICALL(void, "Xapian::Query::Query",
00171                  op_ << ", " << valno << ", " << value);
00172 }
00173 
00174 // Copy constructor
00175 Query::Query(const Query & copyme)
00176         : internal(copyme.internal)
00177 {
00178     DEBUGAPICALL(void, "Xapian::Query::Query", copyme);
00179 }
00180 
00181 // Assignment
00182 Query &
00183 Query::operator=(const Query & copyme)
00184 {
00185     DEBUGAPICALL(Xapian::Query &, "Xapian::Query::operator=", copyme);
00186     internal = copyme.internal;
00187     RETURN(*this);
00188 }
00189 
00190 // Default constructor
00191 Query::Query() : internal(0)
00192 {
00193     DEBUGAPICALL(void, "Xapian::Query::Query", "");
00194 }
00195 
00196 // Destructor
00197 Query::~Query()
00198 {
00199     DEBUGAPICALL(void, "Xapian::Query::~Query", "");
00200 }
00201 
00202 std::string
00203 Query::get_description() const
00204 {
00205     std::string res("Xapian::Query(");
00206     if (internal.get()) res += internal->get_description();
00207     res += ")";
00208     return res;
00209 }
00210 
00211 termcount Query::get_length() const
00212 {
00213     DEBUGAPICALL(Xapian::termcount, "Xapian::Query::get_length", "");
00214     RETURN(internal.get() ? internal->get_length() : 0);
00215 }
00216 
00217 TermIterator Query::get_terms_begin() const
00218 {
00219     DEBUGAPICALL(Xapian::TermIterator, "Xapian::Query::get_terms_begin", "");
00220     if (!internal.get()) RETURN(TermIterator(NULL));
00221     RETURN(internal->get_terms());
00222 }
00223 
00224 bool
00225 Query::empty() const
00226 {
00227     DEBUGAPICALL(void, "Xapian::Query::empty", "");
00228     return internal.get() == 0;
00229 }
00230 
00231 Query::Query(Query::op op_, const std::string & left, const std::string & right)
00232     : internal(0)
00233 {
00234     try {
00235         start_construction(op_, 0);
00236         add_subquery(left);
00237         add_subquery(right);
00238         end_construction();
00239     } catch (...) {
00240         abort_construction();
00241         throw;
00242     }
00243 }
00244 
00245 /* Define static members. */
00246 Xapian::Query Xapian::Query::MatchAll = Xapian::Query(string());
00247 Xapian::Query Xapian::Query::MatchNothing = Xapian::Query();
00248 
00249 }

Documentation for Xapian (version 1.0.10).
Generated on 24 Dec 2008 by Doxygen 1.5.2.