source: trunk/gsdl/src/colservr/gdbmsource.cpp@ 9409

Last change on this file since 9409 was 9345, checked in by davidb, 19 years ago

Restructuring of lucenegdbmsource and mggdbmsource to inherit from new class
(gdbsource) that contains the code in common between these two very similar
object.

  • Property svn:keywords set to Author Date Id Revision
File size: 11.0 KB
Line 
1/**********************************************************************
2 *
3 * gdbmsource.cpp --
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26#include "gdbmsource.h"
27#include "fileutil.h"
28#include "OIDtools.h"
29#include "gsdltools.h"
30
31
32gdbmsourceclass::gdbmsourceclass () {
33 gdbmptr = NULL;
34 textsearchptr = NULL;
35 classname = "gdbmsource";
36}
37
38gdbmsourceclass::~gdbmsourceclass () {
39 if (gdbmptr != NULL) delete gdbmptr;
40 if (textsearchptr != NULL) delete textsearchptr;
41}
42
43void gdbmsourceclass::configure (const text_t &key, const text_tarray &cfgline) {
44 if (cfgline.size() >= 1) {
45 const text_t &value = cfgline[0];
46
47 if (key == "collection") collection = value;
48 else if (key == "collectdir") collectdir = value;
49 else if (key == "gsdlhome") gsdlhome = value;
50 else if (key == "gdbmhome") gdbmhome = value;
51 }
52
53 if (key == "indexmap") {
54 indexmap.importmap (cfgline);
55
56 } else if (key == "defaultindex") {
57 indexmap.from2to (cfgline[0], defaultindex);
58
59 } else if (key == "subcollectionmap") {
60 subcollectionmap.importmap (cfgline);
61
62 } else if (key == "defaultsubcollection") {
63 subcollectionmap.from2to (cfgline[0], defaultsubcollection);
64
65 } else if (key == "languagemap") {
66 languagemap.importmap (cfgline);
67
68 } else if (key == "defaultlanguage")
69 languagemap.from2to (cfgline[0], defaultlanguage);
70}
71
72bool gdbmsourceclass::init (ostream &logout) {
73 outconvertclass text_t2ascii;
74
75 if (gdbmhome.empty()) gdbmhome = gsdlhome;
76
77 if (!sourceclass::init (logout)) return false;
78
79 if (defaultindex.empty()) {
80 // use first index in map as default if no default is set explicitly
81 text_tarray toarray;
82 indexmap.gettoarray(toarray);
83 if (toarray.size()) {
84 defaultindex = toarray[0];
85 }
86 }
87
88 if (defaultsubcollection.empty()) {
89 // use first subcollection in map as default if no default is set explicitly
90 text_tarray toarray;
91 subcollectionmap.gettoarray(toarray);
92 if (toarray.size()) {
93 defaultsubcollection = toarray[0];
94 }
95 }
96
97 if (defaultlanguage.empty()) {
98 // use first language in map as default if no default is set explicitly
99 text_tarray toarray;
100 languagemap.gettoarray(toarray);
101 if (toarray.size()) {
102 defaultlanguage = toarray[0];
103 }
104 }
105
106 // get the collection directory name
107 if (collectdir.empty()) {
108 collectdir = filename_cat (gsdlhome, "collect", collection);
109 }
110
111 // get the filename for the database and make sure it exists
112 gdbm_filename = filename_cat(gdbmhome, "collect", collection, "index", "text", collection);
113 if (littleEndian()) gdbm_filename += ".ldb";
114 else gdbm_filename += ".bdb";
115
116 if (!file_exists(gdbm_filename)) {
117 logout << text_t2ascii
118 << "warning: gdbm database \"" //****
119 << gdbm_filename << "\" does not exist\n\n";
120 // return false; //****
121 }
122
123 return true;
124}
125
126bool gdbmsourceclass::translate_OID (const text_t &OIDin, text_t &OIDout,
127 comerror_t &err, ostream &logout) {
128
129 outconvertclass text_t2ascii;
130
131 err = noError;
132 if (gdbmptr == NULL) {
133 // most likely a configuration problem
134 logout << text_t2ascii
135 << "configuration error: " << classname << " contains a null gdbmclass\n\n";
136 err = configurationError;
137 return true;
138 }
139
140 // open the database
141 gdbmptr->setlogout(&logout);
142 if (!gdbmptr->opendatabase (gdbm_filename, GDBM_READER, 100, false)) {
143 // most likely a system problem (we have already checked that the
144 // gdbm database exists)
145 logout << text_t2ascii
146 << "system problem: open on gdbm database \""
147 << gdbm_filename << "\" failed\n\n";
148 err = systemProblem;
149 return true;
150 }
151
152 infodbclass info;
153 OIDout = gdbmptr->translate_OID (OIDin, info);
154 return true;
155}
156
157bool gdbmsourceclass::get_metadata (const text_t &/*requestParams*/, const text_t &/*refParams*/,
158 bool getParents, const text_tset &fields,
159 const text_t &OID, MetadataInfo_tmap &metadata,
160 comerror_t &err, ostream &logout) {
161 outconvertclass text_t2ascii;
162
163 metadata.erase(metadata.begin(), metadata.end());
164
165 err = noError;
166 if (gdbmptr == NULL) {
167 // most likely a configuration problem
168 logout << text_t2ascii
169 << "configuration error: " << classname <<" contains a null gdbmclass\n\n";
170 err = configurationError;
171 return true;
172 }
173
174 // open the database
175 gdbmptr->setlogout(&logout);
176 if (!gdbmptr->opendatabase (gdbm_filename, GDBM_READER, 100, false)) {
177 // most likely a system problem (we have already checked that the
178 // gdbm database exists)
179 logout << text_t2ascii
180 << "system problem: open on gdbm database \""
181 << gdbm_filename << "\" failed\n\n";
182 err = systemProblem;
183 return true;
184 }
185
186 // get the metadata - if getParents is set we need to get
187 // info for all parents of OID as well as OID
188 vector<infodbclass> info_array;
189 text_tarray OIDs;
190 if (getParents) get_parents_array (OID, OIDs);
191 OIDs.push_back (OID);
192
193 text_tarray::const_iterator this_OID = OIDs.begin();
194 text_tarray::const_iterator end_OID = OIDs.end();
195
196 while (this_OID != end_OID) {
197 infodbclass info;
198 if (!gdbmptr->getinfo(*this_OID, info)) return false;
199
200 // adjust the metadata
201 text_t &contains = info["contains"];
202 if (contains.empty()) info["haschildren"] = 0;
203 else info["haschildren"] = 1;
204 contains.clear();
205
206 info_array.push_back(info);
207 this_OID ++;
208 }
209
210 // if fields set is empty we want to get all available metadata
211 text_tset tfields = fields;
212 if (tfields.empty() && !info_array.empty()) {
213 infodbclass::iterator t_info = info_array[0].begin();
214 infodbclass::iterator e_info = info_array[0].end();
215 while (t_info != e_info) {
216 if ((*t_info).first != "contains")
217 tfields.insert ((*t_info).first);
218 t_info ++;
219 }
220 tfields.insert ("hasnext");
221 tfields.insert ("hasprevious");
222 }
223
224 // collect together the metadata
225 bool donenextprevtest = false;
226 bool hasnext=false, hasprevious=false;
227 MetadataInfo_t this_metadata;
228 text_tarray *pos_metadata;
229 text_tset::const_iterator fields_here = tfields.begin();
230 text_tset::const_iterator fields_end = tfields.end();
231
232 while (fields_here != fields_end) {
233 this_metadata.clear();
234 this_metadata.isRef = false;
235
236 vector<infodbclass>::reverse_iterator this_info = info_array.rbegin();
237 vector<infodbclass>::reverse_iterator end_info = info_array.rend();
238 MetadataInfo_t *tmetaptr = &this_metadata;
239 while (this_info != end_info) {
240
241 pos_metadata = (*this_info).getmultinfo(*fields_here);
242 if ((*fields_here == "hasnext" || *fields_here == "hasprevious")) {
243
244 // collect metadata
245 if (!donenextprevtest) {
246 donenextprevtest = true;
247
248 // cache parent contents array
249 text_t thisparent = get_parent (OID);
250 if (!thisparent.empty()) {
251 if (thisparent != parentOID) {
252 parentOID = thisparent;
253 parentcontents.erase(parentcontents.begin(), parentcontents.end());
254 if (gdbmptr->getinfo(parentOID, parentinfo)) {
255 text_t &parentinfocontains = parentinfo["contains"];
256 if (!parentinfocontains.empty())
257 splitchar (parentinfocontains.begin(), parentinfocontains.end(),
258 ';', parentcontents);
259 }
260 }
261
262 // do tests
263 text_tarray::const_iterator parentcontents_here = parentcontents.begin();
264 text_tarray::const_iterator parentcontents_end = parentcontents.end();
265 text_t shrunk_OID = OID;
266 shrink_parent (shrunk_OID);
267 while (parentcontents_here != parentcontents_end) {
268 if (*parentcontents_here == shrunk_OID) {
269 if (parentcontents_here == parentcontents.begin()) hasprevious = false;
270 else hasprevious = true;
271
272 parentcontents_here++;
273
274 if (parentcontents_here == parentcontents.end()) hasnext = false;
275 else hasnext = true;
276
277 break;
278 }
279
280 parentcontents_here ++;
281 }
282
283 // fill in metadata
284 if ((*fields_here == "hasnext" && hasnext) ||
285 (*fields_here == "hasprevious" && hasprevious))
286 tmetaptr->values.push_back("1");
287 else
288 tmetaptr->values.push_back("0");
289 } else
290 tmetaptr->values.push_back("0");
291 }
292 }
293 else if (pos_metadata != NULL && *fields_here != "contains") {
294 tmetaptr->values = *pos_metadata;
295 }
296 else
297 tmetaptr->values.push_back("");
298
299 this_info ++;
300 if (this_info != end_info) {
301 tmetaptr->parent = new MetadataInfo_t();
302 tmetaptr = tmetaptr->parent;
303 }
304 }
305 metadata[*fields_here] = this_metadata;
306 fields_here++;
307 }
308 return true;
309}
310
311
312bool gdbmsourceclass::get_document (const text_t &OID, text_t &doc,
313 comerror_t &err, ostream &logout) {
314
315 outconvertclass text_t2ascii;
316
317 err = noError;
318 if (gdbmptr == NULL) {
319 // most likely a configuration problem
320 logout << text_t2ascii
321 << "configuration error: " << classname << " contains a null gdbmclass\n\n";
322 err = configurationError;
323 return true;
324 }
325
326 // open the database
327 gdbmptr->setlogout(&logout);
328 if (!gdbmptr->opendatabase (gdbm_filename, GDBM_READER, 100, false)) {
329 // most likely a system problem (we have already checked that the
330 // gdbm database exists)
331 logout << text_t2ascii
332 << "system problem: open on gdbm database \""
333 << gdbm_filename << "\" failed\n\n";
334 err = systemProblem;
335 return true;
336 }
337
338 text_t tOID = OID;
339 if (needs_translating (OID))
340 translate_OID (OID, tOID, err, logout);
341 infodbclass info;
342 if (!gdbmptr->getinfo(tOID, info)) return false;
343
344 if (info["hastxt"].getint() == 1) {
345 int docnum = info["docnum"].getint();
346
347 // set the collection directory
348 textsearchptr->setcollectdir (collectdir);
349
350 // get the text
351 textsearchptr->docTargetDocument(defaultindex, defaultsubcollection,
352 defaultlanguage, collection, docnum, doc);
353 }
354 return true;
355}
356
357bool gdbmsourceclass::is_searchable(bool &issearchable, comerror_t &err, ostream &logout) {
358 err = noError;
359 issearchable = false;
360
361 text_tarray fromarray;
362 indexmap.getfromarray(fromarray);
363 if (fromarray.size() == 0) {
364 return true;
365 } else if (fromarray.size() == 1) {
366 if (fromarray[0] == "dummy:text") {
367 // always return true - issearchable is false here though
368 return true;
369 }
370 }
371 issearchable = true;
372 return true;
373}
Note: See TracBrowser for help on using the repository browser.