00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00143
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
00175 Query::Query(const Query & copyme)
00176 : internal(copyme.internal)
00177 {
00178 DEBUGAPICALL(void, "Xapian::Query::Query", copyme);
00179 }
00180
00181
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
00191 Query::Query() : internal(0)
00192 {
00193 DEBUGAPICALL(void, "Xapian::Query::Query", "");
00194 }
00195
00196
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
00246 Xapian::Query Xapian::Query::MatchAll = Xapian::Query(string());
00247 Xapian::Query Xapian::Query::MatchNothing = Xapian::Query();
00248
00249 }