1 /** @file brass_metadata.cc
2 * @brief Access to metadata for a brass database.
3 */
4 /* Copyright (C) 2004,2005,2006,2007,2008,2009,2010 Olly Betts
5 * Copyright (C) 2008 Lemur Consulting Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <config.h>
23
24 #include "brass_metadata.h"
25
26 #include "brass_cursor.h"
27
28 #include "database.h"
29 #include "debuglog.h"
30 #include "omassert.h"
31 #include "stringutils.h"
32
33 #include "xapian/error.h"
34
35 using namespace std;
36
BrassMetadataTermList(Xapian::Internal::RefCntPtr<const Xapian::Database::Internal> database_,BrassCursor * cursor_,const string & prefix_)37 BrassMetadataTermList::BrassMetadataTermList(
38 Xapian::Internal::RefCntPtr<const Xapian::Database::Internal> database_,
39 BrassCursor * cursor_,
40 const string &prefix_)
41 : database(database_), cursor(cursor_), prefix(string("\x00\xc0", 2) + prefix_)
42 {
43 LOGCALL_CTOR(DB, "BrassMetadataTermList", database_ | cursor_ | prefix_);
44 Assert(cursor);
45 // Seek to the first key before the first metadata key.
46 cursor->find_entry_lt(prefix);
47 }
48
~BrassMetadataTermList()49 BrassMetadataTermList::~BrassMetadataTermList()
50 {
51 LOGCALL_DTOR(DB, "BrassMetadataTermList");
52 delete cursor;
53 }
54
55 string
get_termname() const56 BrassMetadataTermList::get_termname() const
57 {
58 LOGCALL(DB, string, "BrassMetadataTermList::get_termname", NO_ARGS);
59 Assert(!at_end());
60 Assert(!cursor->current_key.empty());
61 Assert(startswith(cursor->current_key, prefix));
62 RETURN(cursor->current_key.substr(2));
63 }
64
65 Xapian::doccount
get_termfreq() const66 BrassMetadataTermList::get_termfreq() const
67 {
68 throw Xapian::InvalidOperationError("BrassMetadataTermList::get_termfreq() not meaningful");
69 }
70
71 Xapian::termcount
get_collection_freq() const72 BrassMetadataTermList::get_collection_freq() const
73 {
74 throw Xapian::InvalidOperationError("BrassMetadataTermList::get_collection_freq() not meaningful");
75 }
76
77 TermList *
next()78 BrassMetadataTermList::next()
79 {
80 LOGCALL(DB, TermList *, "BrassMetadataTermList::next", NO_ARGS);
81 Assert(!at_end());
82
83 cursor->next();
84 if (!cursor->after_end() && !startswith(cursor->current_key, prefix)) {
85 // We've reached the end of the end of the prefixed terms.
86 cursor->to_end();
87 }
88
89 RETURN(NULL);
90 }
91
92 TermList *
skip_to(const string & key)93 BrassMetadataTermList::skip_to(const string &key)
94 {
95 LOGCALL(DB, TermList *, "BrassMetadataTermList::skip_to", key);
96 Assert(!at_end());
97
98 if (!cursor->find_entry_ge(string("\x00\xc0", 2) + key)) {
99 // The exact term we asked for isn't there, so check if the next
100 // term after it also has the right prefix.
101 if (!cursor->after_end() && !startswith(cursor->current_key, prefix)) {
102 // We've reached the end of the prefixed terms.
103 cursor->to_end();
104 }
105 }
106 RETURN(NULL);
107 }
108
109 bool
at_end() const110 BrassMetadataTermList::at_end() const
111 {
112 LOGCALL(DB, bool, "BrassMetadataTermList::at_end", NO_ARGS);
113 RETURN(cursor->after_end());
114 }
115