root/gsdl/trunk/src/colservr/sqlbrowsefilter.cpp @ 16310

Revision 16310, 6.8 KB (checked in by davidb, 12 years ago)

Introduction of 'collecthome' which parallels 'gsdlhome' to allow the toplevel collect folder to be outside of the gsdlhome area

Line 
1/**********************************************************************
2 *
3 * sqlbrowsefilter.cpp --
4 * Copyright (C) 2008  DL Consulting Ltd
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 "sqlbrowsefilter.h"
27#include "fileutil.h"
28
29
30sqlbrowsefilterclass::sqlbrowsefilterclass ()
31{
32  sql_db_ptr = NULL;
33}
34
35
36sqlbrowsefilterclass::~sqlbrowsefilterclass ()
37{
38}
39
40
41void sqlbrowsefilterclass::configure (const text_t &key, const text_tarray &cfgline)
42{
43  filterclass::configure (key, cfgline);
44
45  if (key == "indexstem")
46  {
47    indexstem = cfgline[0];
48  }
49}
50
51
52bool sqlbrowsefilterclass::init (ostream &logout)
53{
54  outconvertclass text_t2ascii;
55
56  if (!filterclass::init(logout)) return false;
57
58  if (sql_db_ptr == NULL)
59  {
60    // most likely a configuration problem
61    logout << text_t2ascii << "configuration error: sqlbrowsefilter contains a null sqldbclass\n\n";
62    return false;
63  }
64
65  if (indexstem.empty())
66  {
67    indexstem = collection;
68  }
69
70  // get the filename for the database and make sure it exists
71  sql_db_filename = resolve_db_filename(indexstem,sql_db_ptr->getfileextension());
72  if (!file_exists(sql_db_filename))
73  {
74    logout << text_t2ascii << "warning: database \"" << sql_db_filename << "\" does not exist\n\n";
75    return false;
76  }
77
78  return true;
79}
80
81
82void sqlbrowsefilterclass::filter (const FilterRequest_t &request,
83                   FilterResponse_t &response,
84                   comerror_t &err, ostream &logout)
85{
86  outconvertclass text_t2ascii;
87
88  response.clear();
89  err = noError;
90
91  if (sql_db_ptr == NULL) {
92    // most likely a configuration problem
93    logout << text_t2ascii << "configuration error: sqlbrowsefilter contains a null sqldbclass\n\n";
94    err = configurationError;
95    return;
96  }
97
98  // open the database
99  sql_db_ptr->setlogout (&logout);
100  if (!sql_db_ptr->opendatabase (sql_db_filename, DB_READER, 100, false)) {
101    // most likely a system problem (we have already checked that the database exists)
102    logout << text_t2ascii << "system problem: open on database \"" << sql_db_filename << "\" failed\n\n";
103    err = systemProblem;
104    return;
105  }
106
107  // Request for the metadata values assigned to an element
108  if (request.requestParams == "GetMetadataValues")
109  {
110    text_tarray metadata_element_names;
111    text_t metadata_value_filter = "";
112    text_t metadata_value_grouping_expression = "";
113    OptionValue_tarray::const_iterator options_iterator = request.filterOptions.begin();
114    while (options_iterator != request.filterOptions.end())
115    {
116      if ((*options_iterator).name == "MetadataElements")
117      {
118    splitchar ((*options_iterator).value.begin(), (*options_iterator).value.end(), ',', metadata_element_names);
119      }
120      if ((*options_iterator).name == "MetadataValueFilter")
121      {
122    metadata_value_filter = (*options_iterator).value;
123      }
124      if ((*options_iterator).name == "MetadataValueGroupingExpression")
125      {
126    metadata_value_grouping_expression = (*options_iterator).value;
127      }
128      options_iterator++;
129    }
130
131    text_tarray metadata_values = sql_db_ptr->get_metadata_values (metadata_element_names, metadata_value_filter, metadata_value_grouping_expression);
132
133    // Create a map from metadata value to ResultDocInfo_t, to remove duplicate values and obtain occurrence counts
134    map<text_t, ResultDocInfo_t> unique_metadata_values_map;
135    text_tarray::iterator metadata_value_iterator = metadata_values.begin();
136    while (metadata_value_iterator != metadata_values.end())
137    {
138      text_t metadata_value = *metadata_value_iterator;
139
140      // If no ResultDocInfo_t has already been created for this metadata value, create one now
141      if (unique_metadata_values_map.find(metadata_value) == unique_metadata_values_map.end())
142      {
143    ResultDocInfo_t metadata_value_result_doc;
144    metadata_value_result_doc.OID = metadata_value;
145    metadata_value_result_doc.result_num = 1;
146    unique_metadata_values_map[metadata_value] = metadata_value_result_doc;
147      }
148      // Otherwise we've seen this value before, so just update the occurrence count
149      else
150      {
151    unique_metadata_values_map[metadata_value].result_num++;
152      }
153
154      metadata_value_iterator++;
155    }
156
157    // Fill in response.docInfo with the ResultDocInfo_t objects we've created above
158    map<text_t, ResultDocInfo_t>::iterator unique_metadata_values_iterator = unique_metadata_values_map.begin();
159    while (unique_metadata_values_iterator != unique_metadata_values_map.end())
160    {
161      response.docInfo.push_back ((*unique_metadata_values_iterator).second);
162      unique_metadata_values_iterator++;
163    }
164  }
165
166  // Request for the documents with a certain metadata value assigned
167  else if (request.requestParams == "GetDocumentsWithMetadataValue")
168  {
169    text_tarray metadata_element_names;
170    text_t metadata_value = "";
171    text_t sort_by_metadata_element_name = "";
172    OptionValue_tarray::const_iterator options_iterator = request.filterOptions.begin();
173    while (options_iterator != request.filterOptions.end())
174    {
175      if ((*options_iterator).name == "MetadataElements")
176      {
177    splitchar ((*options_iterator).value.begin(), (*options_iterator).value.end(), ',', metadata_element_names);
178      }
179      if ((*options_iterator).name == "MetadataValue")
180      {
181    metadata_value = (*options_iterator).value;
182      }
183      if ((*options_iterator).name == "SortByMetadataElement")
184      {
185    sort_by_metadata_element_name = (*options_iterator).value;
186      }
187      options_iterator++;
188    }
189
190    text_tarray document_OIDs = sql_db_ptr->get_documents_with_metadata_value (metadata_element_names, metadata_value, sort_by_metadata_element_name);
191
192    // Fill in response.docInfo with the document OIDs
193    text_tarray::iterator document_OID_iterator = document_OIDs.begin();
194    while (document_OID_iterator != document_OIDs.end())
195    {
196      ResultDocInfo_t document_result_doc;
197      document_result_doc.OID = *document_OID_iterator;
198      response.docInfo.push_back (document_result_doc);
199      document_OID_iterator++;
200    }
201  }
202
203  sql_db_ptr->closedatabase();  // Important that local library doesn't leave any files open
204}
Note: See TracBrowser for help on using the browser.