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 <math.h>
00035 
00036 namespace Xapian {
00037 
00039 void
00040 Query::add_subquery(const Query & subq)
00041 {
00042     DEBUGAPICALL(void, "Xapian::Query::add_subquery", subq);
00043     Assert(internal.get());
00044     internal->add_subquery(subq.internal.get());
00045 }
00046 
00048 void
00049 Query::add_subquery(const Query * subq)
00050 {
00051     DEBUGAPICALL(void, "Xapian::Query::add_subquery", subq);
00052     if (subq == 0) {
00053         throw InvalidArgumentError("Pointer to subquery may not be null");
00054     }
00055     Assert(internal.get());
00056     internal->add_subquery(subq->internal.get());
00057 }
00058 
00060 void
00061 Query::add_subquery(const string & tname)
00062 {
00063     DEBUGAPICALL(void, "Xapian::Query::add_subquery", tname);
00064     Assert(internal.get());
00065     Query::Internal subqint(tname);
00066     internal->add_subquery(&subqint);
00067 }
00068 
00070 void
00071 Query::start_construction(Query::op op_, termcount parameter)
00072 {
00073     DEBUGAPICALL(void, "Xapian::Query::start_construction", op_);
00074     Assert(!internal.get());
00075     internal = new Query::Internal(op_, parameter);
00076 }
00077 
00079 void
00080 Query::end_construction()
00081 {
00082     DEBUGAPICALL(void, "Xapian::Query::end_construction", "");
00083     Assert(internal.get());
00084     internal = internal->end_construction();
00085 }
00086 
00088 void
00089 Query::abort_construction()
00090 {
00091     DEBUGAPICALL(void, "Xapian::Query::abort_construction", "");
00092     Assert(internal.get());
00093     internal = 0;
00094 }
00095 
00096 Query::Query(const string & tname_, termcount wqf_, termpos pos_)
00097         : internal(new Query::Internal(tname_, wqf_, pos_))
00098 {
00099     DEBUGAPICALL(void, "Xapian::Query::Query",
00100                  tname_ << ", " << wqf_ << ", " << pos_);
00101 }
00102 
00103 Query::Query(Query::op op_, const Query &left, const Query &right)
00104         : internal(new Query::Internal(op_, 0u))
00105 {
00106     DEBUGAPICALL(void, "Xapian::Query::Query",
00107                  op_ << ", " << left << ", " << right);
00108     try {
00109         add_subquery(left);
00110         add_subquery(right);
00111         end_construction();
00112     } catch (...) {
00113         abort_construction();
00114         throw;
00115     }
00116 }
00117 
00118 Query::Query(Query::op op_, Query q) : internal(0)
00119 {
00120     try {
00121         start_construction(op_, 0);
00122         add_subquery(q);
00123         end_construction();
00124     } catch (...) {
00125         abort_construction();
00126         throw;
00127     }
00128 }
00129 
00130 Query::Query(Query::op op_, Xapian::Query q, double parameter)
00131 {
00132     DEBUGAPICALL(void, "Xapian::Query::Query",
00133                  op_ << ", " << q << ", " << parameter);
00134     if (op_ == OP_SCALE_WEIGHT) {
00135         if (!q.internal.get() ||
00136             q.internal->op == OP_VALUE_RANGE ||
00137             q.internal->op == OP_VALUE_GE ||
00138             q.internal->op == OP_VALUE_LE) {
00139             // Applying OP_SCALE_WEIGHT to Xapian::Query or OP_VALUE_*
00140             // has no effect as they're all pure-boolean.
00141             internal = q.internal;
00142             return;
00143         }
00144     }
00145     try {
00146         start_construction(op_, 0);
00147         internal->set_dbl_parameter(parameter);
00148         add_subquery(q);
00149         end_construction();
00150     } catch (...) {
00151         abort_construction();
00152         throw;
00153     }
00154 }
00155 
00156 Query::Query(Query::op op_, Xapian::valueno valno,
00157              const string &begin, const string &end)
00158     : internal(new Query::Internal(op_, valno, begin, end))
00159 {
00160     DEBUGAPICALL(void, "Xapian::Query::Query",
00161                  op_ << ", " << valno << ", " << begin << ", " << end);
00162 }
00163 
00164 Query::Query(Query::op op_, Xapian::valueno valno, const std::string &value)
00165     : internal(new Query::Internal(op_, valno, value))
00166 {
00167     DEBUGAPICALL(void, "Xapian::Query::Query",
00168                  op_ << ", " << valno << ", " << value);
00169 }
00170 
00171 // Copy constructor
00172 Query::Query(const Query & copyme)
00173         : internal(copyme.internal)
00174 {
00175     DEBUGAPICALL(void, "Xapian::Query::Query", copyme);
00176 }
00177 
00178 // Assignment
00179 Query &
00180 Query::operator=(const Query & copyme)
00181 {
00182     DEBUGAPICALL(Xapian::Query &, "Xapian::Query::operator=", copyme);
00183     internal = copyme.internal;
00184     RETURN(*this);
00185 }
00186 
00187 // Default constructor
00188 Query::Query() : internal(0)
00189 {
00190     DEBUGAPICALL(void, "Xapian::Query::Query", "");
00191 }
00192 
00193 // Destructor
00194 Query::~Query()
00195 {
00196     DEBUGAPICALL(void, "Xapian::Query::~Query", "");
00197 }
00198 
00199 std::string
00200 Query::get_description() const
00201 {
00202     std::string res("Xapian::Query(");
00203     if (internal.get()) res += internal->get_description();
00204     res += ")";
00205     return res;
00206 }
00207 
00208 termcount Query::get_length() const
00209 {
00210     DEBUGAPICALL(Xapian::termcount, "Xapian::Query::get_length", "");
00211     RETURN(internal.get() ? internal->get_length() : 0);
00212 }
00213 
00214 TermIterator Query::get_terms_begin() const
00215 {
00216     DEBUGAPICALL(Xapian::TermIterator, "Xapian::Query::get_terms_begin", "");
00217     if (!internal.get()) RETURN(TermIterator(NULL));
00218     RETURN(internal->get_terms());
00219 }
00220 
00221 bool
00222 Query::empty() const
00223 {
00224     DEBUGAPICALL(void, "Xapian::Query::empty", "");
00225     return internal.get() == 0;
00226 }
00227 
00228 Query::Query(Query::op op_, const std::string & left, const std::string & right)
00229     : internal(0)
00230 {
00231     try {
00232         start_construction(op_, 0);
00233         add_subquery(left);
00234         add_subquery(right);
00235         end_construction();
00236     } catch (...) {
00237         abort_construction();
00238         throw;
00239     }
00240 }
00241 
00242 /* Define static members. */
00243 Xapian::Query Xapian::Query::MatchAll = Xapian::Query(string());
00244 Xapian::Query Xapian::Query::MatchNothing = Xapian::Query();
00245 
00246 }

Documentation for Xapian (version 1.0.20).
Generated on 28 Apr 2010 by Doxygen 1.5.2.