source: main/tags/2.13/gsdl/src/colservr/mggdbmsource.cpp@ 23898

Last change on this file since 23898 was 990, checked in by sjboddie, 24 years ago

tidied up endianness and fastcgi

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 11.8 KB
Line 
1/**********************************************************************
2 *
3 * mggdbmsource.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 * $Id: mggdbmsource.cpp 990 2000-02-29 01:35:56Z sjboddie $
25 *
26 *********************************************************************/
27
28/*
29 $Log$
30 Revision 1.20 2000/02/29 01:35:56 sjboddie
31 tidied up endianness and fastcgi
32
33 Revision 1.19 1999/12/06 01:14:57 sjboddie
34 fixed a couple of compiler warnings
35
36 Revision 1.18 1999/12/05 21:27:30 sjboddie
37 added support for multiple gsdlhomes and gdbmhome
38
39 Revision 1.17 1999/10/19 03:23:40 davidb
40 Collection building support through web pages
41 and internal and external link handling for collection documents
42
43 Revision 1.16 1999/10/10 08:20:36 sjboddie
44 - metadata now returns map rather than array
45 - redesigned browsing support (although it's not finished so
46 won't currently work ;-)
47
48 Revision 1.15 1999/09/07 04:57:22 sjboddie
49 added gpl notice
50
51 Revision 1.14 1999/08/31 22:40:44 rjmcnab
52 A couple of gdbm changes.
53
54 Revision 1.13 1999/08/13 04:20:27 sjboddie
55 added ability to get return all available metadata when 'fields' is empty
56
57 Revision 1.12 1999/07/07 06:17:47 rjmcnab
58 broke search_index into index+subcollection+language
59 within mgsearch
60
61 Revision 1.11 1999/07/01 03:49:54 rjmcnab
62 fixed a small warning.
63
64 Revision 1.10 1999/06/29 23:06:07 sjboddie
65 Fixed up default index for get_document
66
67 Revision 1.9 1999/06/16 02:00:34 sjboddie
68 Few changes to get getParent filter option to return metadata of
69 parents as well as current OID
70
71 Revision 1.8 1999/05/10 03:43:48 sjboddie
72 lots of changes to lots of files - getting document action going
73
74 Revision 1.7 1999/04/30 02:00:47 sjboddie
75 lots of stuff to do with getting documentaction working
76
77 Revision 1.6 1999/04/21 22:40:44 sjboddie
78 made another change to the one I just committed. if requested metadata doesn't
79 exist it now puts an empty string in the response array so we don't always
80 have to test that a value exists before using it.
81
82 Revision 1.5 1999/04/21 05:23:46 sjboddie
83
84 changed the way metadata is returned
85
86 Revision 1.4 1999/04/19 23:56:07 rjmcnab
87 Finished the gdbm metadata stuff
88
89 Revision 1.3 1999/04/12 10:30:33 rjmcnab
90 Made a little more progress.
91
92 Revision 1.2 1999/04/12 05:21:51 rjmcnab
93 Started on a mg and gdbm source.
94
95 Revision 1.1 1999/04/12 03:40:40 rjmcnab
96 Initial revision.
97
98 */
99
100
101#include "mggdbmsource.h"
102#include "fileutil.h"
103#include "OIDtools.h"
104#include "gsdltools.h"
105
106
107mggdbmsourceclass::mggdbmsourceclass () {
108 gdbmptr = NULL;
109 mgsearchptr = NULL;
110}
111
112mggdbmsourceclass::~mggdbmsourceclass () {
113}
114
115void mggdbmsourceclass::configure (const text_t &key, const text_tarray &cfgline) {
116 if (cfgline.size() >= 1) {
117 const text_t &value = cfgline[0];
118
119 if (key == "collection") collection = value;
120 else if (key == "collectdir") collectdir = value;
121 else if (key == "gsdlhome") gsdlhome = value;
122 else if (key == "gdbmhome") gdbmhome = value;
123 }
124
125 if (key == "indexmap") {
126 indexmap.importmap (cfgline);
127
128 } else if (key == "defaultindex") {
129 indexmap.from2to (cfgline[0], defaultindex);
130
131 } else if (key == "subcollectionmap") {
132 subcollectionmap.importmap (cfgline);
133
134 } else if (key == "defaultsubcollection") {
135 subcollectionmap.from2to (cfgline[0], defaultsubcollection);
136
137 } else if (key == "languagemap") {
138 languagemap.importmap (cfgline);
139
140 } else if (key == "defaultlanguage")
141 languagemap.from2to (cfgline[0], defaultlanguage);
142}
143
144bool mggdbmsourceclass::init (ostream &logout) {
145 outconvertclass text_t2ascii;
146
147 if (gdbmhome.empty()) gdbmhome = gsdlhome;
148
149 if (!sourceclass::init (logout)) return false;
150
151 // get the collection directory name
152 if (collectdir.empty()) {
153 collectdir = filename_cat (gdbmhome, "collect", collection);
154 }
155
156 // get the filename for the database and make sure it exists
157 gdbm_filename = filename_cat(collectdir,"index","text",collection);
158
159 if (littleEndian()) gdbm_filename += ".ldb";
160 else gdbm_filename += ".bdb";
161
162 if (!file_exists(gdbm_filename)) {
163 logout << text_t2ascii
164 << "warning: gdbm database \"" //****
165 << gdbm_filename << "\" does not exist\n\n";
166 // return false; //****
167 }
168
169 return true;
170}
171
172bool mggdbmsourceclass::translate_OID (const text_t &OIDin, text_t &OIDout,
173 comerror_t &err, ostream &logout) {
174
175 outconvertclass text_t2ascii;
176
177 err = noError;
178 if (gdbmptr == NULL) {
179 // most likely a configuration problem
180 logout << text_t2ascii
181 << "configuration error: mggdbmsource contains a null gdbmclass\n\n";
182 err = configurationError;
183 return true;
184 }
185
186 // open the database
187 gdbmptr->setlogout(&logout);
188 if (!gdbmptr->opendatabase (gdbm_filename, GDBM_READER, 100, false)) {
189 // most likely a system problem (we have already checked that the
190 // gdbm database exists)
191 logout << text_t2ascii
192 << "system problem: open on gdbm database \""
193 << gdbm_filename << "\" failed\n\n";
194 err = systemProblem;
195 return true;
196 }
197
198 infodbclass info;
199 OIDout = gdbmptr->translate_OID (OIDin, info);
200 return true;
201}
202
203bool mggdbmsourceclass::get_metadata (const text_t &/*requestParams*/, const text_t &/*refParams*/,
204 bool getParents, const text_tset &fields,
205 const text_t &OID, MetadataInfo_tmap &metadata,
206 comerror_t &err, ostream &logout) {
207 outconvertclass text_t2ascii;
208
209 metadata.erase(metadata.begin(), metadata.end());
210
211 err = noError;
212 if (gdbmptr == NULL) {
213 // most likely a configuration problem
214 logout << text_t2ascii
215 << "configuration error: mggdbmsource contains a null gdbmclass\n\n";
216 err = configurationError;
217 return true;
218 }
219
220 // open the database
221 gdbmptr->setlogout(&logout);
222 if (!gdbmptr->opendatabase (gdbm_filename, GDBM_READER, 100, false)) {
223 // most likely a system problem (we have already checked that the
224 // gdbm database exists)
225 logout << text_t2ascii
226 << "system problem: open on gdbm database \""
227 << gdbm_filename << "\" failed\n\n";
228 err = systemProblem;
229 return true;
230 }
231
232 // get the metadata - if getParents is set we need to get
233 // info for all parents of OID as well as OID
234 vector<infodbclass> info_array;
235 text_tarray OIDs;
236 if (getParents) get_parents_array (OID, OIDs);
237 OIDs.push_back (OID);
238
239 text_tarray::const_iterator this_OID = OIDs.begin();
240 text_tarray::const_iterator end_OID = OIDs.end();
241
242 while (this_OID != end_OID) {
243 infodbclass info;
244 if (!gdbmptr->getinfo(*this_OID, info)) return false;
245
246 // adjust the metadata
247 text_t &contains = info["contains"];
248 if (contains.empty()) info["haschildren"] = 0;
249 else info["haschildren"] = 1;
250 contains.clear();
251
252 info_array.push_back(info);
253 this_OID ++;
254 }
255
256 // if fields set is empty we want to get all available metadata
257 text_tset tfields = fields;
258 if (tfields.empty() && !info_array.empty()) {
259 infodbclass::iterator t_info = info_array[0].begin();
260 infodbclass::iterator e_info = info_array[0].end();
261 while (t_info != e_info) {
262 if ((*t_info).first != "contains")
263 tfields.insert ((*t_info).first);
264 t_info ++;
265 }
266 tfields.insert ("hasnext");
267 tfields.insert ("hasprevious");
268 }
269
270 // collect together the metadata
271 bool donenextprevtest = false;
272 bool hasnext=false, hasprevious=false;
273 MetadataInfo_t this_metadata;
274 text_tarray *pos_metadata;
275 text_tset::const_iterator fields_here = tfields.begin();
276 text_tset::const_iterator fields_end = tfields.end();
277
278 while (fields_here != fields_end) {
279 this_metadata.clear();
280 this_metadata.isRef = false;
281
282 vector<infodbclass>::reverse_iterator this_info = info_array.rbegin();
283 vector<infodbclass>::reverse_iterator end_info = info_array.rend();
284 MetadataInfo_t *tmetaptr = &this_metadata;
285 while (this_info != end_info) {
286
287 pos_metadata = (*this_info).getmultinfo(*fields_here);
288 if ((*fields_here == "hasnext" || *fields_here == "hasprevious")) {
289
290 // collect metadata
291 if (!donenextprevtest) {
292 donenextprevtest = true;
293
294 // cache parent contents array
295 text_t thisparent = get_parent (OID);
296 if (!thisparent.empty()) {
297 if (thisparent != parentOID) {
298 parentOID = thisparent;
299 parentcontents.erase(parentcontents.begin(), parentcontents.end());
300 if (gdbmptr->getinfo(parentOID, parentinfo)) {
301 text_t &parentinfocontains = parentinfo["contains"];
302 if (!parentinfocontains.empty())
303 splitchar (parentinfocontains.begin(), parentinfocontains.end(),
304 ';', parentcontents);
305 }
306 }
307
308 // do tests
309 text_tarray::const_iterator parentcontents_here = parentcontents.begin();
310 text_tarray::const_iterator parentcontents_end = parentcontents.end();
311 text_t shrunk_OID = OID;
312 shrink_parent (shrunk_OID);
313 while (parentcontents_here != parentcontents_end) {
314 if (*parentcontents_here == shrunk_OID) {
315 if (parentcontents_here == parentcontents.begin()) hasprevious = false;
316 else hasprevious = true;
317
318 parentcontents_here++;
319
320 if (parentcontents_here == parentcontents.end()) hasnext = false;
321 else hasnext = true;
322
323 break;
324 }
325
326 parentcontents_here ++;
327 }
328
329 // fill in metadata
330 if ((*fields_here == "hasnext" && hasnext) ||
331 (*fields_here == "hasprevious" && hasprevious))
332 tmetaptr->values.push_back("1");
333 else
334 tmetaptr->values.push_back("0");
335 } else
336 tmetaptr->values.push_back("0");
337 }
338 }
339 else if (pos_metadata != NULL && *fields_here != "contains") {
340 tmetaptr->values = *pos_metadata;
341 }
342 else
343 tmetaptr->values.push_back("");
344
345 this_info ++;
346 if (this_info != end_info) {
347 tmetaptr->parent = new MetadataInfo_t();
348 tmetaptr = tmetaptr->parent;
349 }
350 }
351 metadata[*fields_here] = this_metadata;
352 fields_here++;
353 }
354 return true;
355}
356
357
358bool mggdbmsourceclass::get_document (const text_t &OID, text_t &doc,
359 comerror_t &err, ostream &logout) {
360
361 outconvertclass text_t2ascii;
362
363 err = noError;
364 if (gdbmptr == NULL) {
365 // most likely a configuration problem
366 logout << text_t2ascii
367 << "configuration error: mggdbmsource contains a null gdbmclass\n\n";
368 err = configurationError;
369 return true;
370 }
371
372 // open the database
373 gdbmptr->setlogout(&logout);
374 if (!gdbmptr->opendatabase (gdbm_filename, GDBM_READER, 100, false)) {
375 // most likely a system problem (we have already checked that the
376 // gdbm database exists)
377 logout << text_t2ascii
378 << "system problem: open on gdbm database \""
379 << gdbm_filename << "\" failed\n\n";
380 err = systemProblem;
381 return true;
382 }
383
384 text_t tOID = OID;
385 if (needs_translating (OID))
386 translate_OID (OID, tOID, err, logout);
387 infodbclass info;
388 if (!gdbmptr->getinfo(tOID, info)) return false;
389
390 if (info["hastxt"].getint() == 1) {
391 int docnum = info["docnum"].getint();
392
393 // set the collection directory
394 mgsearchptr->setcollectdir (collectdir);
395
396 // get the text
397 mgsearchptr->docTargetDocument(defaultindex, defaultsubcollection,
398 defaultlanguage, collection, docnum, doc);
399 }
400 return true;
401}
Note: See TracBrowser for help on using the repository browser.