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

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

Did some tidying up of destructor functions as a result of a few hours
spent playing with ccmalloc

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