source: gsdl/trunk/runtime-src/src/colservr/collectset.cpp@ 18061

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

Adding a new collectset constructor that sets httpprefix only, for use by the Firefox Greenstone code.

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