source: gsdl/trunk/src/colservr/collectset.cpp@ 15580

Last change on this file since 15580 was 15558, checked in by mdewsnip, 16 years ago

(Adding new DB support) Changed lots of "gdbm"s to "db"s, in preparation for adding new DB types.

  • Property svn:keywords set to Author Date Id Revision
File size: 12.5 KB
Line 
1/**********************************************************************
2 *
3 * collectset.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
27#include "collectset.h"
28#include "collectserver.h"
29#include "colservrconfig.h"
30#include "gsdlsitecfg.h"
31#include "filter.h"
32#include "browsefilter.h"
33#include "queryfilter.h"
34#include "mgqueryfilter.h"
35#include "mgppqueryfilter.h"
36#include "mggdbmsource.h"
37#include "lucenequeryfilter.h"
38#include "lucenegdbmsource.h"
39
40#include "fileutil.h"
41#include <assert.h>
42
43
44collectset::collectset (text_t &gsdlhome) {
45
46 text_tarray collections;
47 text_t collectdir;
48
49 // get gsdlhome (if we fail the error will be picked up later -- in
50 // cgiwrapper)
51
52 if (site_cfg_read (gsdlhome, httpdomain, httpprefix)) {
53 if (!gsdlhome.empty() && directory_exists(gsdlhome)) {
54 collectdir = filename_cat (gsdlhome, "collect");
55 if (read_dir (collectdir, collections)) {
56
57 text_tarray::const_iterator thiscol = collections.begin();
58 text_tarray::const_iterator endcol = collections.end();
59
60 while (thiscol != endcol) {
61 // ignore the modelcol
62 if (*thiscol == "modelcol") {
63 ++thiscol;
64 continue;
65 }
66
67 this->add_collection (*thiscol, gsdlhome);
68
69 ++thiscol;
70 }
71
72 this->add_all_collection_groups(gsdlhome);
73 }
74 }
75 }
76}
77
78collectset::~collectset () {
79 collectservermapclass::iterator here = cservers.begin();
80 collectservermapclass::iterator end = cservers.end();
81
82 while (here != end) {
83 if ((*here).second.c != NULL) {
84 delete (*here).second.c;
85 }
86 ++here;
87 }
88 cservers.clear();
89}
90
91bool collectset::init (ostream &logout) {
92 collectservermapclass::iterator here = cservers.begin();
93 collectservermapclass::iterator end = cservers.end();
94
95 while (here != end) {
96 assert ((*here).second.c != NULL);
97 if ((*here).second.c != NULL) {
98 const colservrconf &configinfo = (*here).second.c->get_configinfo ();
99
100 // configure this collection server
101
102 // note that we read build.cfg before collect.cfg so that the indexmaps
103 // are available to decode defaultindex, defaultsubcollection, and
104 // defaultlanguage
105
106 bool failed_build_cfg = false;
107 if (!build_cfg_read (*((*here).second.c), configinfo.gsdlhome,
108 configinfo.collection)) {
109 failed_build_cfg = true;
110
111 outconvertclass text_t2ascii;
112 logout << text_t2ascii
113 << "Warning: couldn't read build.cfg file for collection \"" //****
114 << configinfo.collection << "\", gsdlhome=\""
115 << configinfo.gsdlhome << "\"\n";
116 }
117
118 bool failed_collect_cfg = false;
119 if (!collect_cfg_read (*((*here).second.c), configinfo.gsdlhome,
120 configinfo.collection)) {
121 failed_collect_cfg = true;
122 outconvertclass text_t2ascii;
123 logout << text_t2ascii
124 << "Warning: couldn't read collect.cfg file for collection \""
125 << configinfo.collection << "\", gsdlhome=\""
126 << configinfo.gsdlhome << "\"\n";
127 }
128
129
130 bool is_colgroup = (*here).second.c->is_collection_group();
131
132 if (failed_collect_cfg) {
133 ++here;
134 continue;
135 }
136
137 if (failed_build_cfg && (!is_colgroup)) {
138 ++here;
139 continue;
140 }
141 // let a failed build.cfg through if its 'collect.cfg' marks it as 'collectgroup true'
142
143 if (!(*here).second.c->init (logout)) return false;
144
145 (*here).second.c->configure("httpdomain",httpdomain);
146 (*here).second.c->configure("httpprefix",httpprefix);
147 }
148 ++here;
149 }
150
151 return true;
152}
153
154collectservermapclass collectset::servers()
155{ return cservers;
156}
157
158
159void collectset::add_all_collections(const text_t &gsdlhome) {
160
161 text_tarray collections;
162 text_t collectdir = filename_cat(gsdlhome, "collect");
163 if (read_dir(collectdir, collections)) {
164
165 text_tarray::const_iterator thiscol = collections.begin();
166 text_tarray::const_iterator endcol = collections.end();
167
168 while (thiscol != endcol) {
169
170 // ignore the modelcol
171 if (*thiscol == "modelcol") {
172 ++thiscol;
173 continue;
174 }
175
176 // create collection server for this collection
177 this->add_collection (*thiscol, gsdlhome);
178
179 ++thiscol;
180 }
181
182 this->add_all_collection_groups(gsdlhome);
183 }
184}
185
186// add_collection sets up the collectionserver and calls
187// add_collectserver
188void collectset::add_collection (const text_t &collection,
189 const text_t &gsdlhome) {
190
191 this->remove_collection(collection);
192
193 // read config file to see if built with mg, mgpp, or lucene
194 text_t buildtype = "mg"; // mg is default
195
196 text_tarray cfgline;
197 text_t key;
198 text_t build_cfg = filename_cat(gsdlhome, "collect", collection, "index", "build.cfg");
199 char *build_cfgc = build_cfg.getcstr();
200 ifstream confin(build_cfgc);
201
202 if (confin) {
203 while (read_cfg_line(confin, cfgline) >= 0) {
204 if (cfgline.size() == 2) {
205 key = cfgline[0];
206 cfgline.erase(cfgline.begin());
207 if (key == "buildtype") {
208 buildtype = cfgline[0];
209 break;
210 }
211 }
212 }
213 confin.close();
214 }
215 delete []build_cfgc;
216
217 collectserver *cserver = new collectserver();
218 gdbmclass *gdbmhandler = new gdbmclass();
219
220 // add a null filter
221 filterclass *filter = new filterclass ();
222 cserver->add_filter (filter);
223
224 // add a browse filter
225 browsefilterclass *browsefilter = new browsefilterclass();
226 browsefilter->set_db_ptr(gdbmhandler);
227
228 cserver->add_filter (browsefilter);
229
230 if (buildtype == "mg") {
231 mgsearch = new mgsearchclass();
232
233 // add a query filter
234 mgqueryfilterclass *queryfilter = new mgqueryfilterclass();
235 queryfilter->set_db_ptr(gdbmhandler);
236 queryfilter->set_textsearchptr (mgsearch);
237 cserver->add_filter (queryfilter);
238
239 // add a mg and gdbm source
240 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass ();
241 mggdbmsource->set_gdbmptr (gdbmhandler);
242 mggdbmsource->set_textsearchptr (mgsearch);
243 cserver->add_source (mggdbmsource);
244 }
245 else if (buildtype == "mgpp") {
246 mgppsearch = new mgppsearchclass();
247
248 // add a query filter
249 mgppqueryfilterclass *queryfilter = new mgppqueryfilterclass();
250 queryfilter->set_db_ptr(gdbmhandler);
251 queryfilter->set_textsearchptr (mgppsearch);
252 cserver->add_filter (queryfilter);
253
254 // add a mg and gdbm source
255 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass ();
256 mggdbmsource->set_gdbmptr (gdbmhandler);
257 mggdbmsource->set_textsearchptr (mgppsearch);
258 cserver->add_source (mggdbmsource);
259 }
260 else if (buildtype == "lucene") {
261 lucenesearch = new lucenesearchclass();
262 lucenesearch->set_gsdlhome(gsdlhome);
263
264 // add a query filter
265 lucenequeryfilterclass *queryfilter = new lucenequeryfilterclass();
266 queryfilter->set_db_ptr(gdbmhandler);
267 queryfilter->set_textsearchptr (lucenesearch);
268 cserver->add_filter (queryfilter);
269
270 // add a lucene and gdbm source
271 lucenegdbmsourceclass *lucenegdbmsource = new lucenegdbmsourceclass ();
272 lucenegdbmsource->set_gdbmptr (gdbmhandler);
273 lucenegdbmsource->set_textsearchptr (lucenesearch);
274 cserver->add_source (lucenegdbmsource);
275 }
276
277 // inform collection server and everything it contains about its
278 // collection name
279 cserver->configure ("collection", collection);
280 cserver->configure ("gsdlhome", gsdlhome);
281
282 cservers.addcollectserver (cserver);
283}
284
285void collectset::remove_all_collections () {
286
287 // first unload any cached mg databases
288 if (mgsearch != NULL) {
289 mgsearch->unload_database();
290 }
291
292 // now delete the collection server objects
293 collectservermapclass::iterator here = cservers.begin();
294 collectservermapclass::iterator end = cservers.end();
295
296 while (here != end) {
297 if ((*here).second.c != NULL) {
298 delete (*here).second.c;
299 }
300 ++here;
301 }
302 cservers.clear();
303}
304
305void collectset::add_collection_group(const text_t& collection,
306 const text_t& gsdlhome)
307{
308 text_tarray group;
309 text_t collect_group_dir = filename_cat (gsdlhome, "collect", collection);
310
311 // need to read collect.cfg for 'collectgroup' as class hasn't been initialised through 'init' yet
312 text_t is_collect_group;
313 text_tarray cfgline;
314 text_t key;
315 text_t build_cfg = filename_cat(gsdlhome, "collect", collection, "etc", "collect.cfg");
316 char *collect_cfgc = build_cfg.getcstr();
317 ifstream confin(collect_cfgc);
318
319 if (confin) {
320 while (read_cfg_line(confin, cfgline) >= 0) {
321 if (cfgline.size() == 2) {
322 key = cfgline[0];
323 cfgline.erase(cfgline.begin());
324 if (key == "collectgroup") {
325 is_collect_group = cfgline[0];
326 break;
327 }
328 }
329 }
330 confin.close();
331 }
332 delete []collect_cfgc;
333
334 if (is_collect_group == "true") {
335
336 if (read_dir (collect_group_dir, group)) {
337
338 text_tarray::const_iterator thiscol = group.begin();
339 text_tarray::const_iterator endcol = group.end();
340
341 while (thiscol != endcol) {
342 // ignore the modelcol
343 if (*thiscol == "etc") {
344 ++thiscol;
345 continue;
346 }
347
348 this->add_collection (collection + "/" + *thiscol, gsdlhome);
349
350 ++thiscol;
351 }
352 }
353 }
354}
355
356void collectset::add_all_collection_groups (const text_t& gsdlhome)
357
358{
359 collectservermapclass::iterator here = cservers.begin();
360 collectservermapclass::iterator end = cservers.end();
361
362 while (here != end) {
363 text_t collection = (*here).second.c->get_collection_name();
364 this->add_collection_group(collection,gsdlhome);
365
366 ++here;
367 }
368}
369
370
371// remove_collection deletes the collection server of collection.
372// This only needs to be called if a collectionserver is to be
373// removed while the library is running. The destructor function
374// cleans up all collectservers when the program exits.
375void collectset::remove_collection (const text_t &collection) {
376
377 // do nothing if no collection server exists for this collection
378 if (cservers.getcollectserver(collection) == NULL) return;
379
380 // first unload any cached mg databases - we may need to do something
381 // similar to this for mgpp and lucene too
382 if (mgsearch != NULL) {
383 mgsearch->unload_database();
384 }
385
386 // now delete the collection server object
387 collectservermapclass::iterator here = cservers.begin();
388 collectservermapclass::iterator end = cservers.end();
389
390 while (here != end) {
391 if ((*here).second.c != NULL && (*here).first == collection) {
392 delete (*here).second.c;
393 cservers.erase (here);
394 return;
395 }
396 ++here;
397 }
398}
399
400
401// remove_collection deletes the collection server of collection.
402// This only needs to be called if a collectionserver is to be
403// removed while the library is running. The destructor function
404// cleans up all collectservers when the program exits.
405void collectset::remove_collection (const text_t &collection, ostream &logout) {
406
407 remove_collection(collection);
408
409 outconvertclass text_t2ascii;
410 logout << text_t2ascii << "collectset::remove_collection: failed to remove collectserver for "
411 << collection << "\n";
412}
413
414void collectset::configure(const text_t &key, const text_tarray &cfgline)
415{
416 if (key == "collection" || key == "collectdir") return;
417
418 collectservermapclass::iterator here = cservers.begin();
419 collectservermapclass::iterator end = cservers.end();
420
421 while (here != end) {
422 assert ((*here).second.c != NULL);
423 if ((*here).second.c != NULL) {
424 if (key == "collectinfo") {
425 if ((*here).first == cfgline[0]) {
426 (*here).second.c->configure ("gsdlhome", cfgline[1]);
427 (*here).second.c->configure ("gdbmhome", cfgline[2]);
428 }
429 } else {
430 (*here).second.c->configure (key, cfgline);
431 }
432 }
433
434 ++here;
435 }
436}
437
438void collectset::getCollectionList (text_tarray &collist)
439{
440 collist.erase(collist.begin(),collist.end());
441
442 collectservermapclass::iterator here = cservers.begin();
443 collectservermapclass::iterator end = cservers.end();
444 while (here != end) {
445 assert ((*here).second.c != NULL);
446 if ((*here).second.c != NULL) {
447 collist.push_back ((*here).second.c->get_collection_name());
448 }
449 ++here;
450 }
451}
Note: See TracBrowser for help on using the repository browser.