source: main/trunk/greenstone2/runtime-src/src/protocol/recptprototools.cpp@ 31903

Last change on this file since 31903 was 31903, checked in by ak19, 7 years ago

I hope these are all the changes necessary on the runtime side of GS2 to get the OAI server validation working for GS2: instead of working out the earliest datetime stamp of the OAI repository by comparing the builddate in index/build.cfg of each OAI collection and selecting the earliest, the oai-inf.db is now storing the special earliesttimestamp record. The timestamp of this record represents its collection's earliest timestamp. And the earliest of these among all OAI collections is now the earliest datetime of the OAI repository.

  • Property svn:executable set to *
File size: 10.6 KB
Line 
1/**********************************************************************
2 *
3 * recptprototools.cpp --
4 * Copyright (C) 1999-2008 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 "recptprototools.h"
27#include <assert.h>
28
29
30// get_info does a protocol call and returns (in response) the metadata
31// associated with OID. Metadata should be loaded with whatever
32// metadata fields are to be requested.
33
34// THIS FILE IS A CANDIDATE FOR REFACTORING: merge get_info methods
35
36// overloaded, to allow "custom" filter options.
37bool get_info (const text_t &OID, const text_t &collection, const text_t &lang,
38 const text_tset &metadata, bool getParents,
39 recptproto *collectproto, FilterResponse_t &response,
40 ostream &logout, int filterResultOptions)
41{
42 response.clear();
43
44 comerror_t err = noError;
45 FilterRequest_t request;
46 request.clear();
47
48 request.filterName = "NullFilter";
49 request.filterLang = lang;
50 request.filterResultOptions = filterResultOptions | FRmetadata;
51 request.getParents = getParents;
52 request.fields = metadata;
53 request.docSet.push_back (OID);
54 assert (collectproto != NULL);
55
56 collectproto->filter (collection, request, response, err, logout);
57 if (err != noError)
58 {
59 outconvertclass text_t2ascii;
60 logout << text_t2ascii
61 << "Error: call to filter failed for " << OID
62 << " in recptprototools::get_info ("
63 << get_comerror_string (err) << ")\n";
64 return false;
65 }
66
67 return true;
68}
69
70bool get_oai_info (const text_t &OID, const text_t &collection, const text_t &lang,
71 const text_tset &metadata, bool getParents,
72 recptproto *collectproto, FilterResponse_t &response,
73 ostream &logout)
74{
75 // set filteroption to FROAI
76 return get_info(OID, collection, lang, metadata, getParents, collectproto, response, logout, FROAI);
77}
78
79bool get_info (const text_t &OID, const text_t &collection, const text_t &lang,
80 const text_tset &metadata, const OptionValue_tarray &options,
81 bool getParents,
82 recptproto *collectproto, FilterResponse_t &response,
83 ostream &logout)
84{
85 response.clear();
86
87 comerror_t err = noError;
88 FilterRequest_t request;
89
90 request.filterName = "NullFilter";
91 request.filterLang = lang;
92 request.filterResultOptions = FRmetadata;
93 request.getParents = getParents;
94 request.filterOptions = options;
95 request.fields = metadata;
96 request.docSet.push_back (OID);
97
98 assert (collectproto != NULL);
99 collectproto->filter (collection, request, response, err, logout);
100 if (err != noError)
101 {
102 outconvertclass text_t2ascii;
103 logout << text_t2ascii
104 << "Error: call to filter failed for " << OID
105 << " in recptprototools::get_info ("
106 << get_comerror_string (err) << ")\n";
107 return false;
108 }
109
110 return true;
111}
112
113
114bool get_info (const text_tarray &OIDs, const text_t &collection, const text_t &lang,
115 const text_tset &metadata, bool getParents,
116 recptproto *collectproto, FilterResponse_t &response,
117 ostream &logout)
118{
119 response.clear();
120 if (OIDs.empty()) return true;
121
122 comerror_t err = noError;
123 FilterRequest_t request;
124
125 request.filterName = "NullFilter";
126 request.filterLang = lang;
127 request.filterResultOptions = FRmetadata;
128 request.getParents = getParents;
129 request.fields = metadata;
130
131 request.docSet = OIDs;
132
133 collectproto->filter (collection, request, response, err, logout);
134 if (err != noError)
135 {
136 outconvertclass text_t2ascii;
137 logout << text_t2ascii
138 << "Error: call to filter failed in recptprototools::get_info ("
139 << get_comerror_string (err) << ")\n";
140 return false;
141 }
142
143 return true;
144}
145
146
147// has_children returns true if OID has children
148bool has_children (const text_t &OID, const text_t &collection, const text_t &lang,
149 recptproto *collectproto, ostream &logout) {
150
151 FilterResponse_t response;
152 text_tset metadata;
153 metadata.insert ("haschildren");
154
155 if (get_info (OID, collection, lang, metadata, true, collectproto, response, logout))
156 {
157 if (response.docInfo[0].metadata["haschildren"].values[0] == "1")
158 {
159 return true;
160 }
161 }
162
163 return false;
164}
165
166
167// get_children does a protocol call and returns (in response) the OIDs and
168// metadata of all the children of OID. The metadata set should be loaded
169// with whatever metadata fields are to be requested.
170
171bool get_children (const text_t &OID, const text_t &collection, const text_t &lang,
172 const text_tset &metadata, bool getParents,
173 recptproto *collectproto, FilterResponse_t &response,
174 ostream &logout, int filterResultOptions)
175{
176 response.clear();
177
178 comerror_t err = noError;
179 FilterRequest_t request;
180 OptionValue_t option;
181
182 option.name = "ParentNode";
183 option.value = OID;
184 request.filterOptions.push_back (option);
185 request.filterName = "BrowseFilter";
186 request.filterLang = lang;
187 request.filterResultOptions = filterResultOptions | FROID;
188
189 // Efficiency improvement: only get the filter to retrieve metadata if some has been requested
190 // Otherwise, the filter makes an unnecessary request to the database for each child node
191 // By Michael Dewsnip, DL Consulting Ltd
192 if (metadata.size() > 0)
193 {
194 request.filterResultOptions |= FRmetadata;
195 }
196
197 request.fields = metadata;
198 request.getParents = getParents;
199
200 collectproto->filter (collection, request, response, err, logout);
201
202 if (err != noError)
203 {
204 outconvertclass text_t2ascii;
205 logout << text_t2ascii
206 << "Error: call to filter failed for " << OID
207 << " in recptprototools::get_children ("
208 << get_comerror_string (err) << ")\n";
209 return false;
210 }
211
212 return true;
213}
214
215
216static void recurse_contents (ResultDocInfo_t section, const bool &is_classify,
217 const text_t &collection, const text_t &lang,
218 const text_tset &metadata,
219 recptproto *collectproto, FilterResponse_t &response,
220 ostream &logout)
221{
222 int haschildren = section.metadata["haschildren"].values[0].getint();
223 const text_t &doctype = section.metadata["doctype"].values[0];
224
225 if ((haschildren == 1) && ((!is_classify) || (doctype == "classify")))
226 {
227 FilterResponse_t tmp;
228 bool getParents = true;
229 get_children (section.OID, collection, lang, metadata, getParents, collectproto, tmp, logout);
230 ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
231 ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
232 while (thisdoc != lastdoc)
233 {
234 response.docInfo.push_back (*thisdoc);
235 recurse_contents (*thisdoc, is_classify, collection, lang, metadata, collectproto, response, logout);
236 ++thisdoc;
237 }
238 }
239}
240
241
242// get_contents returns OIDs and metadata of all contents
243// below (and including) OID.
244void get_contents (const text_t &topOID, const bool &is_classify,
245 text_tset &metadata, const text_t &collection, const text_t &lang,
246 recptproto *collectproto, FilterResponse_t &response,
247 ostream &logout)
248{
249 if (topOID.empty()) return;
250 response.clear();
251
252 metadata.insert ("haschildren");
253 metadata.insert ("doctype");
254
255 // get topOIDs info
256 if (get_info (topOID, collection, lang, metadata, true, collectproto, response, logout))
257 {
258 recurse_contents (response.docInfo[0], is_classify, collection, lang, metadata, collectproto, response, logout);
259 }
260}
261
262
263bool get_metadata_values (const text_t metadata_elements, const text_t metadata_value_filter,
264 const text_t metadata_value_grouping_expression, const text_t &collection,
265 recptproto *collectproto, FilterResponse_t &response, ostream &logout)
266{
267 response.clear();
268
269 comerror_t err = noError;
270 FilterRequest_t request;
271 request.clear();
272
273 request.filterName = "SQLBrowseFilter";
274 request.requestParams = "GetMetadataValues";
275
276 OptionValue_t request_option;
277 request_option.name = "MetadataElements";
278 request_option.value = metadata_elements;
279 request.filterOptions.push_back (request_option);
280 request_option.name = "MetadataValueFilter";
281 request_option.value = metadata_value_filter;
282 request.filterOptions.push_back (request_option);
283 request_option.name = "MetadataValueGroupingExpression";
284 request_option.value = metadata_value_grouping_expression;
285 request.filterOptions.push_back (request_option);
286
287 assert (collectproto != NULL);
288 collectproto->filter (collection, request, response, err, logout);
289 if (err != noError)
290 {
291 outconvertclass text_t2ascii;
292 logout << text_t2ascii
293 << "Error: call to filter failed for " << metadata_elements
294 << " in recptprototools::get_metadata_values ("
295 << get_comerror_string (err) << ")\n";
296 return false;
297 }
298
299 return true;
300}
301
302
303bool get_documents_with_metadata_value (const text_t metadata_elements, const text_t metadata_value,
304 const text_t sort_by_metadata_element_name, const text_t &collection,
305 recptproto *collectproto, FilterResponse_t &response, ostream &logout)
306{
307 response.clear();
308
309 comerror_t err = noError;
310 FilterRequest_t request;
311 request.clear();
312
313 request.filterName = "SQLBrowseFilter";
314 request.requestParams = "GetDocumentsWithMetadataValue";
315
316 OptionValue_t request_option;
317 request_option.name = "MetadataElements";
318 request_option.value = metadata_elements;
319 request.filterOptions.push_back (request_option);
320 request_option.name = "MetadataValue";
321 request_option.value = metadata_value;
322 request.filterOptions.push_back (request_option);
323 request_option.name = "SortByMetadataElement";
324 request_option.value = sort_by_metadata_element_name;
325 request.filterOptions.push_back (request_option);
326
327 assert (collectproto != NULL);
328 collectproto->filter (collection, request, response, err, logout);
329 if (err != noError)
330 {
331 outconvertclass text_t2ascii;
332 logout << text_t2ascii
333 << "Error: call to filter failed for " << metadata_elements << " = " << metadata_value
334 << " in recptprototools::get_documents_with_metadata_value ("
335 << get_comerror_string (err) << ")\n";
336 return false;
337 }
338
339 return true;
340}
Note: See TracBrowser for help on using the repository browser.