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

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

(Adding dynamic classifiers) Now creates a sqlbrowsefilter if sqlite is being used.

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