Branch data Line data Source code
1 : : /* database.cc: Database::Internal base class.
2 : : *
3 : : * Copyright 1999,2000,2001 BrightStation PLC
4 : : * Copyright 2002 Ananova Ltd
5 : : * Copyright 2002,2003,2004,2005,2006,2007,2008,2009 Olly Betts
6 : : * Copyright 2008 Lemur Consulting Ltd
7 : : *
8 : : * This program is free software; you can redistribute it and/or
9 : : * modify it under the terms of the GNU General Public License as
10 : : * published by the Free Software Foundation; either version 2 of the
11 : : * License, or (at your option) any later version.
12 : : *
13 : : * This program is distributed in the hope that it will be useful,
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : : * GNU General Public License for more details.
17 : : *
18 : : * You should have received a copy of the GNU General Public License
19 : : * along with this program; if not, write to the Free Software
20 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
21 : : * USA
22 : : */
23 : :
24 : : #include <config.h>
25 : :
26 : : #include "database.h"
27 : :
28 : : #include "xapian/error.h"
29 : :
30 : : #include "leafpostlist.h"
31 : : #include "omassert.h"
32 : : #include "slowvaluelist.h"
33 : :
34 : : #include <algorithm>
35 : : #include <string>
36 : :
37 : : using namespace std;
38 : :
39 : : namespace Xapian {
40 : :
41 : 9264 : Database::Internal::~Internal()
42 : : {
43 [ # # ][ # # ]: 9264 : }
[ - + ]
44 : :
45 : : void
46 : 60 : Database::Internal::keep_alive()
47 : : {
48 : : // For the normal case of local databases, nothing needs to be done.
49 : 60 : }
50 : :
51 : :
52 : : Xapian::doccount
53 : 121 : Database::Internal::get_value_freq(Xapian::valueno) const
54 : : {
55 : 121 : throw Xapian::UnimplementedError("This backend doesn't support get_value_freq");
56 : : }
57 : :
58 : : string
59 : 861 : Database::Internal::get_value_lower_bound(Xapian::valueno) const
60 : : {
61 : 861 : return string();
62 : : }
63 : :
64 : : string
65 : 133 : Database::Internal::get_value_upper_bound(Xapian::valueno) const
66 : : {
67 : 133 : throw Xapian::UnimplementedError("This backend doesn't support get_value_upper_bound");
68 : : }
69 : :
70 : : Xapian::termcount
71 : 431040 : Database::Internal::get_doclength_lower_bound() const
72 : : {
73 : : // A zero-length document can't contain any terms, so we ignore such
74 : : // documents for the purposes of this lower bound.
75 : 431040 : return 1;
76 : : }
77 : :
78 : : Xapian::termcount
79 : 1592 : Database::Internal::get_doclength_upper_bound() const
80 : : {
81 : : // Not a very tight bound in general, but this is only a fall-back for
82 : : // backends which don't store these stats.
83 : 1592 : return min(get_total_length(), totlen_t(Xapian::termcount(-1)));
84 : : }
85 : :
86 : : Xapian::termcount
87 : 282605 : Database::Internal::get_wdf_upper_bound(const string & term) const
88 : : {
89 : : // Not a very tight bound in general, but this is only a fall-back for
90 : : // backends which don't store these stats.
91 : 282605 : return get_collection_freq(term);
92 : : }
93 : :
94 : : // Discard any exceptions - we're called from the destructors of derived
95 : : // classes so we can't safely throw.
96 : : void
97 : 2650 : Database::Internal::dtor_called()
98 : : {
99 : : try {
100 [ + + ]: 2650 : if (transaction_active()) {
101 : 6 : cancel_transaction();
102 [ + + ]: 2644 : } else if (transaction_state == TRANSACTION_NONE) {
103 : 2378 : commit();
104 : : }
105 : 27 : } catch (...) {
106 : : // We can't safely throw exceptions from a destructor in case an
107 : : // exception is already active and causing us to be destroyed.
108 : : }
109 : 2650 : }
110 : :
111 : : void
112 : 0 : Database::Internal::commit()
113 : : {
114 : : // Writable databases should override this method.
115 : : Assert(false);
116 : 0 : }
117 : :
118 : : void
119 : 0 : Database::Internal::cancel()
120 : : {
121 : : // Writable databases should override this method.
122 : : Assert(false);
123 : 0 : }
124 : :
125 : : void
126 : 139 : Database::Internal::begin_transaction(bool flushed)
127 : : {
128 [ + + ]: 139 : if (transaction_state != TRANSACTION_NONE) {
129 [ - + ]: 36 : if (transaction_state == TRANSACTION_UNIMPLEMENTED)
130 : 0 : throw Xapian::UnimplementedError("This backend doesn't implement transactions");
131 : 36 : throw InvalidOperationError("Cannot begin transaction - transaction already in progress");
132 : : }
133 [ + + ]: 103 : if (flushed) {
134 : : // N.B. Call commit() before we set transaction_state since commit()
135 : : // isn't allowing during a transaction.
136 : 72 : commit();
137 : 72 : transaction_state = TRANSACTION_FLUSHED;
138 : : } else {
139 : 31 : transaction_state = TRANSACTION_UNFLUSHED;
140 : : }
141 : 103 : }
142 : :
143 : : void
144 : 54 : Database::Internal::commit_transaction()
145 : : {
146 [ + + ]: 54 : if (!transaction_active()) {
147 [ - + ]: 27 : if (transaction_state == TRANSACTION_UNIMPLEMENTED)
148 : 0 : throw Xapian::UnimplementedError("This backend doesn't implement transactions");
149 : 27 : throw InvalidOperationError("Cannot commit transaction - no transaction currently in progress");
150 : : }
151 : 27 : bool flushed = (transaction_state == TRANSACTION_FLUSHED);
152 : 27 : transaction_state = TRANSACTION_NONE;
153 : : // N.B. Call commit() after we clear transaction_state since commit()
154 : : // isn't allowing during a transaction.
155 [ + - ]: 27 : if (flushed) commit();
156 : 27 : }
157 : :
158 : : void
159 : 103 : Database::Internal::cancel_transaction()
160 : : {
161 [ + + ]: 103 : if (!transaction_active()) {
162 [ - + ]: 27 : if (transaction_state == TRANSACTION_UNIMPLEMENTED)
163 : 0 : throw Xapian::UnimplementedError("This backend doesn't implement transactions");
164 : 27 : throw InvalidOperationError("Cannot cancel transaction - no transaction currently in progress");
165 : : }
166 : 76 : transaction_state = TRANSACTION_NONE;
167 : 76 : cancel();
168 : 70 : }
169 : :
170 : : Xapian::docid
171 : 0 : Database::Internal::add_document(const Xapian::Document &)
172 : : {
173 : : // Writable databases should override this method.
174 : : Assert(false);
175 : 0 : return 0;
176 : : }
177 : :
178 : : void
179 : 0 : Database::Internal::delete_document(Xapian::docid)
180 : : {
181 : : // Writable databases should override this method.
182 : : Assert(false);
183 : 0 : }
184 : :
185 : : void
186 : 51 : Database::Internal::delete_document(const string & unique_term)
187 : : {
188 : : // Default implementation - overridden for remote databases
189 : 51 : Xapian::Internal::RefCntPtr<LeafPostList> pl(open_post_list(unique_term));
190 [ + + ]: 2468 : while (pl->next(), !pl->at_end()) {
191 : 2417 : delete_document(pl->get_docid());
192 : 51 : }
193 : 51 : }
194 : :
195 : : void
196 : 0 : Database::Internal::replace_document(Xapian::docid, const Xapian::Document &)
197 : : {
198 : : // Writable databases should override this method.
199 : : Assert(false);
200 : 0 : }
201 : :
202 : : Xapian::docid
203 : 190 : Database::Internal::replace_document(const string & unique_term,
204 : : const Xapian::Document & document)
205 : : {
206 : : // Default implementation - overridden for remote databases
207 : 190 : Xapian::Internal::RefCntPtr<LeafPostList> pl(open_post_list(unique_term));
208 : 190 : pl->next();
209 [ + + ]: 190 : if (pl->at_end()) {
210 : 10 : return add_document(document);
211 : : }
212 : 180 : Xapian::docid did = pl->get_docid();
213 : 180 : replace_document(did, document);
214 [ + + ]: 210 : while (pl->next(), !pl->at_end()) {
215 : 30 : delete_document(pl->get_docid());
216 : : }
217 : 190 : return did;
218 : : }
219 : :
220 : : ValueList *
221 : 8751 : Database::Internal::open_value_list(Xapian::valueno slot) const
222 : : {
223 : 8751 : return new SlowValueList(Xapian::Database(const_cast<Database::Internal*>(this)), slot);
224 : : }
225 : :
226 : : TermList *
227 : 0 : Database::Internal::open_spelling_termlist(const string &) const
228 : : {
229 : : // Only implemented for some database backends - others will just not
230 : : // suggest spelling corrections (or not contribute to them in a multiple
231 : : // database situation).
232 : 0 : return NULL;
233 : : }
234 : :
235 : : TermList *
236 : 0 : Database::Internal::open_spelling_wordlist() const
237 : : {
238 : : // Only implemented for some database backends - others will just not
239 : : // suggest spelling corrections (or not contribute to them in a multiple
240 : : // database situation).
241 : 0 : return NULL;
242 : : }
243 : :
244 : : Xapian::doccount
245 : 0 : Database::Internal::get_spelling_frequency(const string &) const
246 : : {
247 : : // Only implemented for some database backends - others will just not
248 : : // suggest spelling corrections (or not contribute to them in a multiple
249 : : // database situation).
250 : 0 : return 0;
251 : : }
252 : :
253 : : void
254 : 0 : Database::Internal::add_spelling(const string &, Xapian::termcount) const
255 : : {
256 : 0 : throw Xapian::UnimplementedError("This backend doesn't implement spelling correction");
257 : : }
258 : :
259 : : void
260 : 0 : Database::Internal::remove_spelling(const string &, Xapian::termcount) const
261 : : {
262 : 0 : throw Xapian::UnimplementedError("This backend doesn't implement spelling correction");
263 : : }
264 : :
265 : : TermList *
266 : 0 : Database::Internal::open_synonym_termlist(const string &) const
267 : : {
268 : : // Only implemented for some database backends - others will just not
269 : : // expand synonyms (or not contribute to them in a multiple database
270 : : // situation).
271 : 0 : return NULL;
272 : : }
273 : :
274 : : TermList *
275 : 0 : Database::Internal::open_synonym_keylist(const string &) const
276 : : {
277 : : // Only implemented for some database backends - others will just not
278 : : // expand synonyms (or not contribute to them in a multiple database
279 : : // situation).
280 : 0 : return NULL;
281 : : }
282 : :
283 : : void
284 : 0 : Database::Internal::add_synonym(const string &, const string &) const
285 : : {
286 : 0 : throw Xapian::UnimplementedError("This backend doesn't implement synonyms");
287 : : }
288 : :
289 : : void
290 : 0 : Database::Internal::remove_synonym(const string &, const string &) const
291 : : {
292 : 0 : throw Xapian::UnimplementedError("This backend doesn't implement synonyms");
293 : : }
294 : :
295 : : void
296 : 0 : Database::Internal::clear_synonyms(const string &) const
297 : : {
298 : 0 : throw Xapian::UnimplementedError("This backend doesn't implement synonyms");
299 : : }
300 : :
301 : : string
302 : 0 : Database::Internal::get_metadata(const string &) const
303 : : {
304 : 0 : return string();
305 : : }
306 : :
307 : : TermList *
308 : 0 : Database::Internal::open_metadata_keylist(const string &) const
309 : : {
310 : : // Only implemented for some database backends - others will simply report
311 : : // there being no metadata keys.
312 : 0 : return NULL;
313 : : }
314 : :
315 : : void
316 : 0 : Database::Internal::set_metadata(const string &, const string &)
317 : : {
318 : 0 : throw Xapian::UnimplementedError("This backend doesn't implement metadata");
319 : : }
320 : :
321 : : void
322 : 0 : Database::Internal::reopen()
323 : : {
324 : : // Database backends which don't support simultaneous update and reading
325 : : // probably don't need to do anything here.
326 : 0 : }
327 : :
328 : : void
329 : 40458 : Database::Internal::request_document(Xapian::docid /*did*/) const
330 : : {
331 : 40458 : }
332 : :
333 : : Xapian::Document::Internal *
334 : 40458 : Database::Internal::collect_document(Xapian::docid did) const
335 : : {
336 : : // Open the document lazily - collect document is only called by
337 : : // Enquire::Internal::read_doc() for a given MSetItem, so we know that the
338 : : // document already exists.
339 : 40458 : return open_document(did, true);
340 : : }
341 : :
342 : : void
343 : 0 : Database::Internal::write_changesets_to_fd(int, const string &, bool, ReplicationInfo *)
344 : : {
345 : 0 : throw Xapian::UnimplementedError("This backend doesn't provide changesets");
346 : : }
347 : :
348 : : string
349 : 0 : Database::Internal::get_revision_info() const
350 : : {
351 : 0 : throw Xapian::UnimplementedError("This backend doesn't provide access to revision information");
352 : : }
353 : :
354 : : string
355 : 9 : Database::Internal::get_uuid() const
356 : : {
357 : 9 : return string();
358 : : }
359 : :
360 : : void
361 : 1560790 : Database::Internal::invalidate_doc_object(Xapian::Document::Internal *) const
362 : : {
363 : : // Do nothing, by default.
364 : 1560790 : }
365 : :
366 : : RemoteDatabase *
367 : 246355 : Database::Internal::as_remotedatabase()
368 : : {
369 : 246355 : return NULL;
370 : : }
371 : :
372 : : }
|