source: trunk/gsdl/src/colservr/mggdbmsource.cpp@ 2212

Last change on this file since 2212 was 2212, checked in by sjboddie, 23 years ago

Fixed a bug that was causing the local library server to attempt to write
files to gsdlhome (i.e. the cd-rom drive if served from a cd) under certain
circumstances.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 9.7 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 *********************************************************************/
25
26#include "mggdbmsource.h"
27#include "fileutil.h"
28#include "OIDtools.h"
29#include "gsdltools.h"
30
31
32mggdbmsourceclass::mggdbmsourceclass () {
33 gdbmptr = NULL;
34 mgsearchptr = NULL;
35}
36
37mggdbmsourceclass::~mggdbmsourceclass () {
38 if (gdbmptr != NULL) delete gdbmptr;
39 if (mgsearchptr != NULL) delete mgsearchptr;
40}
41
42void mggdbmsourceclass::configure (const text_t &key, const text_tarray &cfgline) {
43 if (cfgline.size() >= 1) {
44 const text_t &value = cfgline[0];
45
46 if (key == "collection") collection = value;
47 else if (key == "collectdir") collectdir = value;
48 else if (key == "gsdlhome") gsdlhome = value;
49 else if (key == "gdbmhome") gdbmhome = value;
50 }
51
52 if (key == "indexmap") {
53 indexmap.importmap (cfgline);
54
55 } else if (key == "defaultindex") {
56 indexmap.from2to (cfgline[0], defaultindex);
57
58 } else if (key == "subcollectionmap") {
59 subcollectionmap.importmap (cfgline);
60
61 } else if (key == "defaultsubcollection") {
62 subcollectionmap.from2to (cfgline[0], defaultsubcollection);
63
64 } else if (key == "languagemap") {
65 languagemap.importmap (cfgline);
66
67 } else if (key == "defaultlanguage")
68 languagemap.from2to (cfgline[0], defaultlanguage);
69}
70
71bool mggdbmsourceclass::init (ostream &logout) {
72 outconvertclass text_t2ascii;
73
74 if (gdbmhome.empty()) gdbmhome = gsdlhome;
75
76 if (!sourceclass::init (logout)) return false;
77
78 // get the collection directory name
79 if (collectdir.empty()) {
80 collectdir = filename_cat (gsdlhome, "collect", collection);
81 }
82
83 // get the filename for the database and make sure it exists
84 gdbm_filename = filename_cat(gdbmhome, "collect", collection, "index", "text", collection);
85 if (littleEndian()) gdbm_filename += ".ldb";
86 else gdbm_filename += ".bdb";
87
88 if (!file_exists(gdbm_filename)) {
89 logout << text_t2ascii
90 << "warning: gdbm database \"" //****
91 << gdbm_filename << "\" does not exist\n\n";
92 // return false; //****
93 }
94
95 return true;
96}
97
98bool mggdbmsourceclass::translate_OID (const text_t &OIDin, text_t &OIDout,
99 comerror_t &err, ostream &logout) {
100
101 outconvertclass text_t2ascii;
102
103 err = noError;
104 if (gdbmptr == NULL) {
105 // most likely a configuration problem
106 logout << text_t2ascii
107 << "configuration error: mggdbmsource contains a null gdbmclass\n\n";
108 err = configurationError;
109 return true;
110 }
111
112 // open the database
113 gdbmptr->setlogout(&logout);
114 if (!gdbmptr->opendatabase (gdbm_filename, GDBM_READER, 100, false)) {
115 // most likely a system problem (we have already checked that the
116 // gdbm database exists)
117 logout << text_t2ascii
118 << "system problem: open on gdbm database \""
119 << gdbm_filename << "\" failed\n\n";
120 err = systemProblem;
121 return true;
122 }
123
124 infodbclass info;
125 OIDout = gdbmptr->translate_OID (OIDin, info);
126 return true;
127}
128
129bool mggdbmsourceclass::get_metadata (const text_t &/*requestParams*/, const text_t &/*refParams*/,
130 bool getParents, const text_tset &fields,
131 const text_t &OID, MetadataInfo_tmap &metadata,
132 comerror_t &err, ostream &logout) {
133 outconvertclass text_t2ascii;
134
135 metadata.erase(metadata.begin(), metadata.end());
136
137 err = noError;
138 if (gdbmptr == NULL) {
139 // most likely a configuration problem
140 logout << text_t2ascii
141 << "configuration error: mggdbmsource contains a null gdbmclass\n\n";
142 err = configurationError;
143 return true;
144 }
145
146 // open the database
147 gdbmptr->setlogout(&logout);
148 if (!gdbmptr->opendatabase (gdbm_filename, GDBM_READER, 100, false)) {
149 // most likely a system problem (we have already checked that the
150 // gdbm database exists)
151 logout << text_t2ascii
152 << "system problem: open on gdbm database \""
153 << gdbm_filename << "\" failed\n\n";
154 err = systemProblem;
155 return true;
156 }
157
158 // get the metadata - if getParents is set we need to get
159 // info for all parents of OID as well as OID
160 vector<infodbclass> info_array;
161 text_tarray OIDs;
162 if (getParents) get_parents_array (OID, OIDs);
163 OIDs.push_back (OID);
164
165 text_tarray::const_iterator this_OID = OIDs.begin();
166 text_tarray::const_iterator end_OID = OIDs.end();
167
168 while (this_OID != end_OID) {
169 infodbclass info;
170 if (!gdbmptr->getinfo(*this_OID, info)) return false;
171
172 // adjust the metadata
173 text_t &contains = info["contains"];
174 if (contains.empty()) info["haschildren"] = 0;
175 else info["haschildren"] = 1;
176 contains.clear();
177
178 info_array.push_back(info);
179 this_OID ++;
180 }
181
182 // if fields set is empty we want to get all available metadata
183 text_tset tfields = fields;
184 if (tfields.empty() && !info_array.empty()) {
185 infodbclass::iterator t_info = info_array[0].begin();
186 infodbclass::iterator e_info = info_array[0].end();
187 while (t_info != e_info) {
188 if ((*t_info).first != "contains")
189 tfields.insert ((*t_info).first);
190 t_info ++;
191 }
192 tfields.insert ("hasnext");
193 tfields.insert ("hasprevious");
194 }
195
196 // collect together the metadata
197 bool donenextprevtest = false;
198 bool hasnext=false, hasprevious=false;
199 MetadataInfo_t this_metadata;
200 text_tarray *pos_metadata;
201 text_tset::const_iterator fields_here = tfields.begin();
202 text_tset::const_iterator fields_end = tfields.end();
203
204 while (fields_here != fields_end) {
205 this_metadata.clear();
206 this_metadata.isRef = false;
207
208 vector<infodbclass>::reverse_iterator this_info = info_array.rbegin();
209 vector<infodbclass>::reverse_iterator end_info = info_array.rend();
210 MetadataInfo_t *tmetaptr = &this_metadata;
211 while (this_info != end_info) {
212
213 pos_metadata = (*this_info).getmultinfo(*fields_here);
214 if ((*fields_here == "hasnext" || *fields_here == "hasprevious")) {
215
216 // collect metadata
217 if (!donenextprevtest) {
218 donenextprevtest = true;
219
220 // cache parent contents array
221 text_t thisparent = get_parent (OID);
222 if (!thisparent.empty()) {
223 if (thisparent != parentOID) {
224 parentOID = thisparent;
225 parentcontents.erase(parentcontents.begin(), parentcontents.end());
226 if (gdbmptr->getinfo(parentOID, parentinfo)) {
227 text_t &parentinfocontains = parentinfo["contains"];
228 if (!parentinfocontains.empty())
229 splitchar (parentinfocontains.begin(), parentinfocontains.end(),
230 ';', parentcontents);
231 }
232 }
233
234 // do tests
235 text_tarray::const_iterator parentcontents_here = parentcontents.begin();
236 text_tarray::const_iterator parentcontents_end = parentcontents.end();
237 text_t shrunk_OID = OID;
238 shrink_parent (shrunk_OID);
239 while (parentcontents_here != parentcontents_end) {
240 if (*parentcontents_here == shrunk_OID) {
241 if (parentcontents_here == parentcontents.begin()) hasprevious = false;
242 else hasprevious = true;
243
244 parentcontents_here++;
245
246 if (parentcontents_here == parentcontents.end()) hasnext = false;
247 else hasnext = true;
248
249 break;
250 }
251
252 parentcontents_here ++;
253 }
254
255 // fill in metadata
256 if ((*fields_here == "hasnext" && hasnext) ||
257 (*fields_here == "hasprevious" && hasprevious))
258 tmetaptr->values.push_back("1");
259 else
260 tmetaptr->values.push_back("0");
261 } else
262 tmetaptr->values.push_back("0");
263 }
264 }
265 else if (pos_metadata != NULL && *fields_here != "contains") {
266 tmetaptr->values = *pos_metadata;
267 }
268 else
269 tmetaptr->values.push_back("");
270
271 this_info ++;
272 if (this_info != end_info) {
273 tmetaptr->parent = new MetadataInfo_t();
274 tmetaptr = tmetaptr->parent;
275 }
276 }
277 metadata[*fields_here] = this_metadata;
278 fields_here++;
279 }
280 return true;
281}
282
283
284bool mggdbmsourceclass::get_document (const text_t &OID, text_t &doc,
285 comerror_t &err, ostream &logout) {
286
287 outconvertclass text_t2ascii;
288
289 err = noError;
290 if (gdbmptr == NULL) {
291 // most likely a configuration problem
292 logout << text_t2ascii
293 << "configuration error: mggdbmsource contains a null gdbmclass\n\n";
294 err = configurationError;
295 return true;
296 }
297
298 // open the database
299 gdbmptr->setlogout(&logout);
300 if (!gdbmptr->opendatabase (gdbm_filename, GDBM_READER, 100, false)) {
301 // most likely a system problem (we have already checked that the
302 // gdbm database exists)
303 logout << text_t2ascii
304 << "system problem: open on gdbm database \""
305 << gdbm_filename << "\" failed\n\n";
306 err = systemProblem;
307 return true;
308 }
309
310 text_t tOID = OID;
311 if (needs_translating (OID))
312 translate_OID (OID, tOID, err, logout);
313 infodbclass info;
314 if (!gdbmptr->getinfo(tOID, info)) return false;
315
316 if (info["hastxt"].getint() == 1) {
317 int docnum = info["docnum"].getint();
318
319 // set the collection directory
320 mgsearchptr->setcollectdir (collectdir);
321
322 // get the text
323 mgsearchptr->docTargetDocument(defaultindex, defaultsubcollection,
324 defaultlanguage, collection, docnum, doc);
325 }
326 return true;
327}
Note: See TracBrowser for help on using the repository browser.