00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <config.h>
00024
00025 #include <xapian/queryparser.h>
00026 #include <xapian/termiterator.h>
00027
00028 #include "queryparser_internal.h"
00029 #include "vectortermlist.h"
00030
00031 #include <cstring>
00032
00033 using namespace Xapian;
00034
00035 using namespace std;
00036
00037
00038 string
00039 Stopper::get_description() const
00040 {
00041 return "Xapian::Stopper subclass";
00042 }
00043
00044 string
00045 SimpleStopper::get_description() const
00046 {
00047 string desc("Xapian::SimpleStopper(");
00048 set<string>::const_iterator i;
00049 for (i = stop_words.begin(); i != stop_words.end(); ++i) {
00050 if (i != stop_words.begin()) desc += ' ';
00051 desc += *i;
00052 }
00053 desc += ')';
00054 return desc;
00055 }
00056
00057 ValueRangeProcessor::~ValueRangeProcessor() { }
00058
00059 QueryParser::QueryParser(const QueryParser & o) : internal(o.internal) { }
00060
00061 QueryParser &
00062 QueryParser::operator=(const QueryParser & o)
00063 {
00064 internal = o.internal;
00065 return *this;
00066 }
00067
00068 QueryParser::QueryParser() : internal(new QueryParser::Internal) { }
00069
00070 QueryParser::~QueryParser() { }
00071
00072 void
00073 QueryParser::set_stemmer(const Xapian::Stem & stemmer)
00074 {
00075 internal->stemmer = stemmer;
00076 }
00077
00078 void
00079 QueryParser::set_stemming_strategy(stem_strategy strategy)
00080 {
00081 internal->stem_action = strategy;
00082 }
00083
00084 void
00085 QueryParser::set_stopper(const Stopper * stopper)
00086 {
00087 internal->stopper = stopper;
00088 }
00089
00090 void
00091 QueryParser::set_default_op(Query::op default_op)
00092 {
00093 internal->default_op = default_op;
00094 }
00095
00096 Query::op
00097 QueryParser::get_default_op() const
00098 {
00099 return internal->default_op;
00100 }
00101
00102 void
00103 QueryParser::set_database(const Database &db) {
00104 internal->db = db;
00105 }
00106
00107 void
00108 QueryParser::set_max_wildcard_expansion(Xapian::termcount max)
00109 {
00110 internal->max_wildcard_expansion = max;
00111 }
00112
00113 Query
00114 QueryParser::parse_query(const string &query_string, unsigned flags,
00115 const string &default_prefix)
00116 {
00117 internal->stoplist.clear();
00118 internal->unstem.clear();
00119 internal->errmsg = NULL;
00120
00121 if (query_string.empty()) return Query();
00122
00123 Query result = internal->parse_query(query_string, flags, default_prefix);
00124 if (internal->errmsg && strcmp(internal->errmsg, "parse error") == 0) {
00125 result = internal->parse_query(query_string, 0, default_prefix);
00126 }
00127
00128 if (internal->errmsg) throw Xapian::QueryParserError(internal->errmsg);
00129 return result;
00130 }
00131
00132 void
00133 QueryParser::add_prefix(const string &field, const string &prefix)
00134 {
00135 Assert(internal.get());
00136 internal->add_prefix(field, prefix, NON_BOOLEAN);
00137 }
00138
00139 void
00140 QueryParser::add_boolean_prefix(const string &field, const string &prefix,
00141 bool exclusive)
00142 {
00143 Assert(internal.get());
00144
00145
00146 if (field.empty())
00147 throw Xapian::UnimplementedError("Can't set the empty prefix to be a boolean filter");
00148 filter_type type = (exclusive ? BOOLEAN_EXCLUSIVE : BOOLEAN);
00149 internal->add_prefix(field, prefix, type);
00150 }
00151
00152 void
00153 QueryParser::add_boolean_prefix(const string &field, const string &prefix)
00154 {
00155 add_boolean_prefix(field, prefix, true);
00156 }
00157
00158 TermIterator
00159 QueryParser::stoplist_begin() const
00160 {
00161 const list<string> & sl = internal->stoplist;
00162 return TermIterator(new VectorTermList(sl.begin(), sl.end()));
00163 }
00164
00165 TermIterator
00166 QueryParser::unstem_begin(const string &term) const
00167 {
00168 pair<multimap<string, string>::iterator,
00169 multimap<string, string>::iterator> range;
00170 range = internal->unstem.equal_range(term);
00171 list<string> l;
00172 multimap<string, string>::iterator & i = range.first;
00173 while (i != range.second) {
00174 l.push_back(i->second);
00175 ++i;
00176 }
00177 return TermIterator(new VectorTermList(l.begin(), l.end()));
00178 }
00179
00180 void
00181 QueryParser::add_valuerangeprocessor(Xapian::ValueRangeProcessor * vrproc)
00182 {
00183 Assert(internal.get());
00184 internal->valrangeprocs.push_back(vrproc);
00185 }
00186
00187 string
00188 QueryParser::get_corrected_query_string() const
00189 {
00190 return internal->corrected_query;
00191 }
00192
00193 string
00194 QueryParser::get_description() const
00195 {
00196
00197 return "Xapian::QueryParser()";
00198 }