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 "omqueryinternal.h"
00027
00028 #include "debuglog.h"
00029 #include "omassert.h"
00030 #include "utils.h"
00031
00032 #include "xapian/error.h"
00033 #include "xapian/postingsource.h"
00034 #include "xapian/registry.h"
00035 #include "xapian/termiterator.h"
00036
00037 #include <cmath>
00038
00039 namespace Xapian {
00040
00042 void
00043 Query::add_subquery(const Query & subq)
00044 {
00045 LOGCALL_VOID(API, "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 LOGCALL_VOID(API, "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 LOGCALL_VOID(API, "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 LOGCALL_VOID(API, "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 LOGCALL_VOID(API, "Xapian::Query::end_construction", NO_ARGS);
00086 Assert(internal.get());
00087 internal = internal->end_construction();
00088 }
00089
00091 void
00092 Query::abort_construction()
00093 {
00094 LOGCALL_VOID(API, "Xapian::Query::abort_construction", NO_ARGS);
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 LOGCALL_VOID(API, "Xapian::Query::Query", tname_ | wqf_ | pos_);
00103 }
00104
00105 Query::Query(Query::op op_, const Query &left, const Query &right)
00106 : internal(new Query::Internal(op_, 0u))
00107 {
00108 LOGCALL_VOID(API, "Xapian::Query::Query", op_ | left | right);
00109 try {
00110 add_subquery(left);
00111 add_subquery(right);
00112 end_construction();
00113 } catch (...) {
00114 abort_construction();
00115 throw;
00116 }
00117 }
00118
00119 Query::Query(Query::op op_, Xapian::Query q, double parameter)
00120 {
00121 LOGCALL_VOID(API, "Xapian::Query::Query", op_ | q | parameter);
00122 if (op_ == OP_SCALE_WEIGHT) {
00123 if (!q.internal.get() ||
00124 q.internal->op == OP_VALUE_RANGE ||
00125 q.internal->op == OP_VALUE_GE ||
00126 q.internal->op == OP_VALUE_LE) {
00127
00128
00129 internal = q.internal;
00130 return;
00131 }
00132 }
00133 try {
00134 start_construction(op_, 0);
00135 internal->set_dbl_parameter(parameter);
00136 add_subquery(q);
00137 end_construction();
00138 } catch (...) {
00139 abort_construction();
00140 throw;
00141 }
00142 }
00143
00144 Query::Query(Query::op op_, Xapian::valueno slot,
00145 const string &begin, const string &end)
00146 : internal(new Query::Internal(op_, slot, begin, end))
00147 {
00148 LOGCALL_VOID(API, "Xapian::Query::Query", op_ | slot | begin | end);
00149 }
00150
00151 Query::Query(Query::op op_, Xapian::valueno slot, const std::string &value)
00152 : internal(new Query::Internal(op_, slot, value))
00153 {
00154 LOGCALL_VOID(API, "Xapian::Query::Query", op_ | slot | value);
00155 }
00156
00157 Query::Query(PostingSource * external_source)
00158 : internal(NULL)
00159 {
00160 LOGCALL_VOID(API, "Xapian::Query::Query", external_source);
00161 if (!external_source)
00162 throw Xapian::InvalidArgumentError("The external_source parameter can not be NULL");
00163 PostingSource * clone = external_source->clone();
00164 if (clone) {
00165 internal = new Query::Internal(clone, true);
00166 } else {
00167 internal = new Query::Internal(external_source, false);
00168 }
00169 }
00170
00171
00172 Query::Query(const Query & copyme)
00173 : internal(copyme.internal)
00174 {
00175 LOGCALL_VOID(API, "Xapian::Query::Query", copyme);
00176 }
00177
00178
00179 Query &
00180 Query::operator=(const Query & copyme)
00181 {
00182 LOGCALL(API, Xapian::Query &, "Xapian::Query::operator=", copyme);
00183 internal = copyme.internal;
00184 RETURN(*this);
00185 }
00186
00187
00188 Query::Query() : internal(0)
00189 {
00190 LOGCALL_VOID(API, "Xapian::Query::Query", NO_ARGS);
00191 }
00192
00193
00194 Query::~Query()
00195 {
00196 LOGCALL_VOID(API, "Xapian::Query::~Query", NO_ARGS);
00197 }
00198
00199 std::string
00200 Query::serialise() const
00201 {
00202 LOGCALL(API, std::string, "Xapian::Query::serialise", NO_ARGS);
00203 if (!internal.get()) return std::string();
00204 return internal->serialise();
00205 }
00206
00207 Query
00208 Query::unserialise(const std::string &s)
00209 {
00210 LOGCALL_STATIC(API, Xapian::Query, "Xapian::Query::unserialise", s);
00211 Query result;
00212 if (!s.empty()) {
00213 result.internal = Xapian::Query::Internal::unserialise(s, Registry());
00214 }
00215 RETURN(result);
00216 }
00217
00218 Query
00219 Query::unserialise(const std::string & s, const Registry & reg)
00220 {
00221 LOGCALL_STATIC(API, Xapian::Query, "Xapian::Query::unserialise", s | reg);
00222 Query result;
00223 if (!s.empty()) {
00224 result.internal = Xapian::Query::Internal::unserialise(s, reg);
00225 }
00226 RETURN(result);
00227 }
00228
00229 std::string
00230 Query::get_description() const
00231 {
00232 std::string res("Xapian::Query(");
00233 if (internal.get()) res += internal->get_description();
00234 res += ")";
00235 return res;
00236 }
00237
00238 termcount Query::get_length() const
00239 {
00240 LOGCALL(API, Xapian::termcount, "Xapian::Query::get_length", NO_ARGS);
00241 RETURN(internal.get() ? internal->get_length() : 0);
00242 }
00243
00244 TermIterator Query::get_terms_begin() const
00245 {
00246 LOGCALL(API, Xapian::TermIterator, "Xapian::Query::get_terms_begin", NO_ARGS);
00247 if (!internal.get()) RETURN(TermIterator());
00248 RETURN(internal->get_terms());
00249 }
00250
00251 bool
00252 Query::empty() const
00253 {
00254 LOGCALL_VOID(API, "Xapian::Query::empty", NO_ARGS);
00255 return internal.get() == 0;
00256 }
00257
00258 Query::Query(Query::op op_, const std::string & left, const std::string & right)
00259 : internal(0)
00260 {
00261 try {
00262 start_construction(op_, 0);
00263 add_subquery(left);
00264 add_subquery(right);
00265 end_construction();
00266 } catch (...) {
00267 abort_construction();
00268 throw;
00269 }
00270 }
00271
00272
00273 const Xapian::Query Xapian::Query::MatchAll = Xapian::Query(string());
00274 const Xapian::Query Xapian::Query::MatchNothing = Xapian::Query();
00275
00276 }