Branch data Line data Source code
1 : : /* queryparser.cc: The non-lemon-generated parts of the QueryParser
2 : : * class.
3 : : *
4 : : * Copyright (C) 2005,2006,2007,2008,2010 Olly Betts
5 : : *
6 : : * This program is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU General Public License as
8 : : * published by the Free Software Foundation; either version 2 of the
9 : : * License, or (at your option) any later version.
10 : : *
11 : : * This program is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : : * GNU General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU General Public License
17 : : * along with this program; if not, write to the Free Software
18 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19 : : * USA
20 : : */
21 : :
22 : : #include <config.h>
23 : :
24 : : #include <xapian/queryparser.h>
25 : : #include <xapian/termiterator.h>
26 : :
27 : : #include "queryparser_internal.h"
28 : : #include "vectortermlist.h"
29 : :
30 : : #include <cstring>
31 : :
32 : : using namespace Xapian;
33 : :
34 : : using namespace std;
35 : :
36 : : // Default implementation in case the user hasn't implemented it.
37 : : string
38 : 0 : Stopper::get_description() const
39 : : {
40 : 0 : return "Xapian::Stopper subclass";
41 : : }
42 : :
43 : : string
44 : 1 : SimpleStopper::get_description() const
45 : : {
46 : 1 : string desc("Xapian::SimpleStopper(");
47 : 1 : set<string>::const_iterator i;
48 [ - + ]: 1 : for (i = stop_words.begin(); i != stop_words.end(); ++i) {
49 [ # # ]: 0 : if (i != stop_words.begin()) desc += ' ';
50 : 0 : desc += *i;
51 : : }
52 : 1 : desc += ')';
53 : 0 : return desc;
54 : : }
55 : :
56 [ # # ][ # # ]: 21 : ValueRangeProcessor::~ValueRangeProcessor() { }
[ - + ]
57 : :
58 : 1 : QueryParser::QueryParser(const QueryParser & o) : internal(o.internal) { }
59 : :
60 : : QueryParser &
61 : 1 : QueryParser::operator=(const QueryParser & o)
62 : : {
63 : 1 : internal = o.internal;
64 : 1 : return *this;
65 : : }
66 : :
67 : 81 : QueryParser::QueryParser() : internal(new QueryParser::Internal) { }
68 : :
69 : 82 : QueryParser::~QueryParser() { }
70 : :
71 : : void
72 : 25 : QueryParser::set_stemmer(const Xapian::Stem & stemmer)
73 : : {
74 : 25 : internal->stemmer = stemmer;
75 : 25 : }
76 : :
77 : : void
78 : 31 : QueryParser::set_stemming_strategy(stem_strategy strategy)
79 : : {
80 : 31 : internal->stem_action = strategy;
81 : 31 : }
82 : :
83 : : void
84 : 3 : QueryParser::set_stopper(const Stopper * stopper)
85 : : {
86 : 3 : internal->stopper = stopper;
87 : 3 : }
88 : :
89 : : void
90 : 16 : QueryParser::set_default_op(Query::op default_op)
91 : : {
92 : 16 : internal->default_op = default_op;
93 : 16 : }
94 : :
95 : : Query::op
96 : 0 : QueryParser::get_default_op() const
97 : : {
98 : 0 : return internal->default_op;
99 : : }
100 : :
101 : : void
102 : 45 : QueryParser::set_database(const Database &db) {
103 : 45 : internal->db = db;
104 : 45 : }
105 : :
106 : : Query
107 : 24840 : QueryParser::parse_query(const string &query_string, unsigned flags,
108 : : const string &default_prefix)
109 : : {
110 : 24840 : internal->stoplist.clear();
111 : 24840 : internal->unstem.clear();
112 : 24840 : internal->errmsg = NULL;
113 : :
114 [ - + ]: 24840 : if (query_string.empty()) return Query();
115 : :
116 : 24840 : Query result = internal->parse_query(query_string, flags, default_prefix);
117 [ + + + + ]: 24831 : if (internal->errmsg && strcmp(internal->errmsg, "parse error") == 0) {
[ + + ]
118 : 140 : result = internal->parse_query(query_string, 0, default_prefix);
119 : : }
120 : :
121 [ + + ]: 24824 : if (internal->errmsg) throw Xapian::QueryParserError(internal->errmsg);
122 : 24831 : return result;
123 : : }
124 : :
125 : : void
126 : 33 : QueryParser::add_prefix(const string &field, const string &prefix)
127 : : {
128 : : Assert(internal.get());
129 : 33 : internal->add_prefix(field, prefix, NON_BOOLEAN);
130 : 32 : }
131 : :
132 : : void
133 : 23 : QueryParser::add_boolean_prefix(const string &field, const string &prefix,
134 : : bool exclusive)
135 : : {
136 : : Assert(internal.get());
137 : : // Don't allow the empty prefix to be set as boolean as it doesn't
138 : : // really make sense.
139 [ + + ]: 23 : if (field.empty())
140 : 1 : throw Xapian::UnimplementedError("Can't set the empty prefix to be a boolean filter");
141 [ + + ]: 22 : filter_type type = (exclusive ? BOOLEAN_EXCLUSIVE : BOOLEAN);
142 : 22 : internal->add_prefix(field, prefix, type);
143 : 21 : }
144 : :
145 : : void
146 : 20 : QueryParser::add_boolean_prefix(const string &field, const string &prefix)
147 : : {
148 : 20 : add_boolean_prefix(field, prefix, true);
149 : 18 : }
150 : :
151 : : TermIterator
152 : 3 : QueryParser::stoplist_begin() const
153 : : {
154 : 3 : const list<string> & sl = internal->stoplist;
155 : 3 : return TermIterator(new VectorTermList(sl.begin(), sl.end()));
156 : : }
157 : :
158 : : TermIterator
159 : 1 : QueryParser::unstem_begin(const string &term) const
160 : : {
161 : : pair<multimap<string, string>::iterator,
162 : 1 : multimap<string, string>::iterator> range;
163 : 1 : range = internal->unstem.equal_range(term);
164 : 1 : list<string> l;
165 : 1 : multimap<string, string>::iterator & i = range.first;
166 [ + + ]: 2 : while (i != range.second) {
167 : 1 : l.push_back(i->second);
168 : 1 : ++i;
169 : : }
170 : 1 : return TermIterator(new VectorTermList(l.begin(), l.end()));
171 : : }
172 : :
173 : : void
174 : 15 : QueryParser::add_valuerangeprocessor(Xapian::ValueRangeProcessor * vrproc)
175 : : {
176 : : Assert(internal.get());
177 : 15 : internal->valrangeprocs.push_back(vrproc);
178 : 15 : }
179 : :
180 : : string
181 : 58 : QueryParser::get_corrected_query_string() const
182 : : {
183 : 58 : return internal->corrected_query;
184 : : }
185 : :
186 : : string
187 : 1 : QueryParser::get_description() const
188 : : {
189 : : // FIXME : describe better!
190 : 1 : return "Xapian::QueryParser()";
191 : : }
|