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 <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
00140
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
00172 Query::Query(const Query & copyme)
00173 : internal(copyme.internal)
00174 {
00175 DEBUGAPICALL(void, "Xapian::Query::Query", copyme);
00176 }
00177
00178
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
00188 Query::Query() : internal(0)
00189 {
00190 DEBUGAPICALL(void, "Xapian::Query::Query", "");
00191 }
00192
00193
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
00243 Xapian::Query Xapian::Query::MatchAll = Xapian::Query(string());
00244 Xapian::Query Xapian::Query::MatchNothing = Xapian::Query();
00245
00246 }