1 |
|
---|
2 | #include "z3950parser.h"
|
---|
3 |
|
---|
4 | void Z_AttributeList_parse(bend_search_rr *rr, Z_AttributeList *Z, text_t &GSQuery)
|
---|
5 | {
|
---|
6 | /*
|
---|
7 | struct Z_AttributeList {
|
---|
8 | int num_attributes;
|
---|
9 | Z_AttributeElement **attributes;
|
---|
10 | };
|
---|
11 | */
|
---|
12 |
|
---|
13 | /*
|
---|
14 | struct Z_AttributeElement {
|
---|
15 | Z_AttributeSetId *attributeSet; // OPT
|
---|
16 | int *attributeType;
|
---|
17 | int which;
|
---|
18 | union {
|
---|
19 | int *numeric;
|
---|
20 | Z_ComplexAttribute *complex;
|
---|
21 | #define Z_AttributeValue_numeric 1
|
---|
22 | #define Z_AttributeValue_complex 2
|
---|
23 | } value;
|
---|
24 | };
|
---|
25 | */
|
---|
26 |
|
---|
27 |
|
---|
28 |
|
---|
29 | }
|
---|
30 |
|
---|
31 | void Z_Term_parse(bend_search_rr *rr, Z_Term *Z, text_t &GSQuery)
|
---|
32 | {
|
---|
33 | /*
|
---|
34 | struct Z_Term {
|
---|
35 | int which;
|
---|
36 | union {
|
---|
37 | Odr_oct *general;
|
---|
38 | int *numeric;
|
---|
39 | Z_InternationalString *characterString;
|
---|
40 | Odr_oid *oid;
|
---|
41 | char *dateTime;
|
---|
42 | Z_External *external;
|
---|
43 | Z_IntUnit *integerAndUnit;
|
---|
44 | Odr_null *null;
|
---|
45 | #define Z_Term_general 1
|
---|
46 | #define Z_Term_numeric 2
|
---|
47 | #define Z_Term_characterString 3
|
---|
48 | #define Z_Term_oid 4
|
---|
49 | #define Z_Term_dateTime 5
|
---|
50 | #define Z_Term_external 6
|
---|
51 | #define Z_Term_integerAndUnit 7
|
---|
52 | #define Z_Term_null 8
|
---|
53 | } u;
|
---|
54 | };
|
---|
55 | */
|
---|
56 |
|
---|
57 | char *term;
|
---|
58 |
|
---|
59 | switch(Z->which){
|
---|
60 | case Z_Term_general: {
|
---|
61 | // must copy no more than len bytes from buf, or else previous query terms may be included
|
---|
62 | int buflen = Z->u.general->len;
|
---|
63 | term = new char[buflen+1];
|
---|
64 | memset(term, '\0', buflen+1);
|
---|
65 | strncpy(term, (const char*)(Z->u.general->buf), buflen);
|
---|
66 | GSQuery += term;
|
---|
67 | break; }
|
---|
68 | case Z_Term_numeric:
|
---|
69 | GSQuery += *(Z->u.numeric); // int*
|
---|
70 | break;
|
---|
71 | case Z_Term_characterString:
|
---|
72 | GSQuery += Z->u.characterString; // what is this type?
|
---|
73 | break;
|
---|
74 | case Z_Term_oid:
|
---|
75 | GSQuery += *(Z->u.oid); // int*
|
---|
76 | break;
|
---|
77 | case Z_Term_dateTime:
|
---|
78 | GSQuery += Z->u.dateTime; // char*
|
---|
79 | break;
|
---|
80 | case Z_Term_external:
|
---|
81 | GSQuery += " "; // ignore this for now
|
---|
82 | break;
|
---|
83 | case Z_Term_integerAndUnit:
|
---|
84 | GSQuery += " "; // ignore this for now
|
---|
85 | break;
|
---|
86 | case Z_Term_null:
|
---|
87 | GSQuery += " "; // void
|
---|
88 | break;
|
---|
89 | default:
|
---|
90 | cerr << "Error in Z_Term_parse" << endl;
|
---|
91 | exit(1);
|
---|
92 | }
|
---|
93 | }
|
---|
94 |
|
---|
95 | void Z_ProximityOperator_parse(bend_search_rr *rr, Z_ProximityOperator *Z, text_t &GSQuery)
|
---|
96 | {
|
---|
97 | /*
|
---|
98 | struct Z_ProximityOperator {
|
---|
99 | bool_t *exclusion; // OPT
|
---|
100 | int *distance;
|
---|
101 | bool_t *ordered;
|
---|
102 | #define Z_ProximityOperator_Prox_lessThan 1
|
---|
103 | #define Z_ProximityOperator_Prox_lessThanOrEqual 2
|
---|
104 | #define Z_ProximityOperator_Prox_equal 3
|
---|
105 | #define Z_ProximityOperator_Prox_greaterThanOrEqual 4
|
---|
106 | #define Z_ProximityOperator_Prox_greaterThan 5
|
---|
107 | #define Z_ProximityOperator_Prox_notEqual 6
|
---|
108 | int *relationType;
|
---|
109 | int which;
|
---|
110 | union {
|
---|
111 | Z_ProxUnit *known;
|
---|
112 | int *zprivate;
|
---|
113 | #define Z_ProximityOperator_known 1
|
---|
114 | #define Z_ProximityOperator_private 2
|
---|
115 | } u;
|
---|
116 | };
|
---|
117 |
|
---|
118 | #define Z_ProxUnit_character 1
|
---|
119 | #define Z_ProxUnit_word 2
|
---|
120 | #define Z_ProxUnit_sentence 3
|
---|
121 | #define Z_ProxUnit_paragraph 4
|
---|
122 | #define Z_ProxUnit_section 5
|
---|
123 | #define Z_ProxUnit_chapter 6
|
---|
124 | #define Z_ProxUnit_document 7
|
---|
125 | #define Z_ProxUnit_element 8
|
---|
126 | #define Z_ProxUnit_subelement 9
|
---|
127 | #define Z_ProxUnit_elementType 10
|
---|
128 | #define Z_ProxUnit_byte 11
|
---|
129 | */
|
---|
130 |
|
---|
131 | // Greenstone (actually mgpp) supports proximity, but only
|
---|
132 | // to n words either side.
|
---|
133 | // A more complete implementation of proximity can be added
|
---|
134 | // by parsing the other fields in Z_ProximityOperator.
|
---|
135 | // Note: this only works properly with MGPP collections
|
---|
136 |
|
---|
137 | GSQuery += " NEAR";
|
---|
138 | GSQuery += *(Z->distance);
|
---|
139 | GSQuery += " ";
|
---|
140 | }
|
---|
141 |
|
---|
142 | void Z_Operator_parse(bend_search_rr *rr, Z_Operator *Z, text_t &GSQuery)
|
---|
143 | {
|
---|
144 | /*
|
---|
145 | struct Z_Operator {
|
---|
146 | int which;
|
---|
147 | union {
|
---|
148 | Odr_null *and;
|
---|
149 | Odr_null *or;
|
---|
150 | Odr_null *and_not;
|
---|
151 | Z_ProximityOperator *prox;
|
---|
152 | #define Z_Operator_and 1
|
---|
153 | #define Z_Operator_or 2
|
---|
154 | #define Z_Operator_and_not 3
|
---|
155 | #define Z_Operator_prox 4
|
---|
156 | } u;
|
---|
157 | };
|
---|
158 | */
|
---|
159 |
|
---|
160 | switch(Z->which){
|
---|
161 | case Z_Operator_and:
|
---|
162 | GSQuery += " & ";
|
---|
163 | break;
|
---|
164 | case Z_Operator_or:
|
---|
165 | GSQuery += " | ";
|
---|
166 | break;
|
---|
167 | case Z_Operator_and_not:
|
---|
168 | GSQuery += " ! ";
|
---|
169 | break;
|
---|
170 | case Z_Operator_prox:
|
---|
171 | Z_ProximityOperator_parse(rr, Z->u.prox, GSQuery);
|
---|
172 | break;
|
---|
173 | default:
|
---|
174 | cerr << "Error in Z_Operator_parse" << endl;
|
---|
175 | exit(1);
|
---|
176 | }
|
---|
177 | }
|
---|
178 |
|
---|
179 | void Z_Operand_parse(bend_search_rr *rr, Z_Operand *Z, text_t &GSQuery)
|
---|
180 | {
|
---|
181 | /*
|
---|
182 | struct Z_Operand {
|
---|
183 | int which;
|
---|
184 | union {
|
---|
185 | Z_AttributesPlusTerm *attributesPlusTerm;
|
---|
186 | Z_ResultSetId *resultSetId;
|
---|
187 | Z_ResultSetPlusAttributes *resultAttr;
|
---|
188 | #define Z_Operand_APT 1
|
---|
189 | #define Z_Operand_resultSetId 2
|
---|
190 | #define Z_Operand_resultAttr 3
|
---|
191 | } u;
|
---|
192 | };
|
---|
193 | */
|
---|
194 |
|
---|
195 | switch(Z->which) {
|
---|
196 | case Z_Operand_APT: {
|
---|
197 | /*
|
---|
198 | struct Z_AttributesPlusTerm {
|
---|
199 | Z_AttributeList *attributes;
|
---|
200 | Z_Term *term;
|
---|
201 | };
|
---|
202 | */
|
---|
203 |
|
---|
204 | /*
|
---|
205 | struct Z_AttributeList {
|
---|
206 | int num_attributes;
|
---|
207 | Z_AttributeElement **attributes;
|
---|
208 | };
|
---|
209 | */
|
---|
210 |
|
---|
211 | /*
|
---|
212 | struct Z_AttributeElement {
|
---|
213 | Z_AttributeSetId *attributeSet; // OPT
|
---|
214 | int *attributeType;
|
---|
215 | int which;
|
---|
216 | union {
|
---|
217 | int *numeric;
|
---|
218 | Z_ComplexAttribute *complex;
|
---|
219 | #define Z_AttributeValue_numeric 1
|
---|
220 | #define Z_AttributeValue_complex 2
|
---|
221 | } value;
|
---|
222 | };
|
---|
223 | */
|
---|
224 |
|
---|
225 | char *term;
|
---|
226 |
|
---|
227 | if (Z->u.attributesPlusTerm->attributes->num_attributes > 0) {
|
---|
228 | int Bib1_relation = *(Z->u.attributesPlusTerm->attributes->attributes[0]->attributeType);
|
---|
229 | int Bib1_use = *(Z->u.attributesPlusTerm->attributes->attributes[0]->value.numeric);
|
---|
230 |
|
---|
231 | // if use value is 1010 ("Body of text"), is not a fielded search
|
---|
232 | if (Bib1_use == 1010) {
|
---|
233 | // if relation value is 6 ("not"), add a "not" to GSQuery
|
---|
234 | if (Bib1_relation == 6) {
|
---|
235 | GSQuery += "! ";
|
---|
236 | }
|
---|
237 | Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
|
---|
238 | }
|
---|
239 | // for other use values, is a fielded search
|
---|
240 | else {
|
---|
241 | text_t Short;
|
---|
242 | // only add [ ]: if the index exists in the collection,
|
---|
243 | // note: only the index names in the first collection of a
|
---|
244 | // multi-collection search are used at the moment
|
---|
245 | if ((Collection_map[rr->basenames[0]]).getFieldArg(Bib1_use, Short)) {
|
---|
246 | GSQuery += "[";
|
---|
247 | Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
|
---|
248 | GSQuery += "]";
|
---|
249 | GSQuery += ":";
|
---|
250 | GSQuery += Short;
|
---|
251 | }
|
---|
252 | // if it doesn't, add it as an unfielded search term
|
---|
253 | else {
|
---|
254 | cerr << "[" << rr->basenames[0] << "]: failed to find field index for " <<Bib1_use<<", adding term unfielded" << endl;
|
---|
255 | Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
|
---|
256 | }
|
---|
257 | }
|
---|
258 | }
|
---|
259 | else {
|
---|
260 | Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
|
---|
261 | }
|
---|
262 | break;
|
---|
263 | }
|
---|
264 | case Z_Operand_resultSetId: {
|
---|
265 | GSQuery += "(";
|
---|
266 | GSQuery += Resultsets[Z->u.resultSetId];
|
---|
267 | GSQuery += ")";
|
---|
268 | break;
|
---|
269 | }
|
---|
270 | case Z_Operand_resultAttr:
|
---|
271 | GSQuery += " "; // ignore this for now
|
---|
272 | break;
|
---|
273 | default:
|
---|
274 | cerr << "Error in Z_Operand_parse" << endl;
|
---|
275 | exit(1);
|
---|
276 | }
|
---|
277 | }
|
---|
278 |
|
---|
279 | void Z_RPNStructure_parse(bend_search_rr *rr, Z_RPNStructure *Z, text_t &GSQuery)
|
---|
280 | {
|
---|
281 | /*
|
---|
282 | struct Z_RPNStructure {
|
---|
283 | int which;
|
---|
284 | union {
|
---|
285 | Z_Operand *simple;
|
---|
286 | Z_Complex *complex;
|
---|
287 | #define Z_RPNStructure_simple 1
|
---|
288 | #define Z_RPNStructure_complex 2
|
---|
289 | } u;
|
---|
290 | };
|
---|
291 | */
|
---|
292 |
|
---|
293 | switch(Z->which){
|
---|
294 | case Z_RPNStructure_simple:
|
---|
295 | Z_Operand_parse(rr, Z->u.simple, GSQuery);
|
---|
296 | break;
|
---|
297 | case Z_RPNStructure_complex:
|
---|
298 | GSQuery += "(";
|
---|
299 | Z_RPNStructure_parse(rr, Z->u.complex->s1, GSQuery);
|
---|
300 | Z_Operator_parse(rr, Z->u.complex->roperator, GSQuery);
|
---|
301 | Z_RPNStructure_parse(rr, Z->u.complex->s2, GSQuery);
|
---|
302 | GSQuery += ")";
|
---|
303 | break;
|
---|
304 | default:
|
---|
305 | cerr << "Error in Z_RPNStructure_parse" << endl;
|
---|
306 | exit(1);
|
---|
307 | }
|
---|
308 | }
|
---|
309 |
|
---|
310 | text_t ZQueryToGSQuery(bend_search_rr *rr)
|
---|
311 | {
|
---|
312 | text_t GSQuery;
|
---|
313 |
|
---|
314 | switch(rr->query->which){
|
---|
315 | case Z_Query_type_0:
|
---|
316 | cerr << "querytype = 0" << endl;
|
---|
317 | // this is a void*, pretend it's a Greenstone-type query
|
---|
318 | GSQuery += (char*)(rr->query->u.type_0);
|
---|
319 | break;
|
---|
320 | case Z_Query_type_1: {
|
---|
321 | cerr << "querytype = 1" << endl;
|
---|
322 | /*
|
---|
323 | struct Z_RPNQuery {
|
---|
324 | Z_AttributeSetId *attributeSetId;
|
---|
325 | Z_RPNStructure *RPNStructure;
|
---|
326 | };
|
---|
327 | */
|
---|
328 | // parse attributeSetId
|
---|
329 | cerr << "attributeSetId = ";
|
---|
330 | int c, d = 0;
|
---|
331 | do {
|
---|
332 | c = rr->query->u.type_1->attributeSetId[d];
|
---|
333 | cerr << c;
|
---|
334 | d++;
|
---|
335 | } while (c >= 0);
|
---|
336 | cerr << endl;
|
---|
337 |
|
---|
338 | Z_RPNStructure_parse(rr, rr->query->u.type_1->RPNStructure, GSQuery);
|
---|
339 | break; }
|
---|
340 | case Z_Query_type_2: {
|
---|
341 | cerr << "querytype = 2" << endl;
|
---|
342 | // this is just a buf (unsigned char*), pretend it's a Greenstone-type query
|
---|
343 | GSQuery += (char*)(rr->query->u.type_2->buf);
|
---|
344 | break; }
|
---|
345 | case Z_Query_type_100: {
|
---|
346 | cerr << "querytype = 100" << endl;
|
---|
347 | // this is just a buf (unsigned char*), pretend it's a Greenstone-type query
|
---|
348 | GSQuery += (char*)(rr->query->u.type_100->buf);
|
---|
349 | break; }
|
---|
350 | case Z_Query_type_101: {
|
---|
351 | cerr << "querytype = 101" << endl;
|
---|
352 | // check: is this really the same as a type 1 query?
|
---|
353 | Z_RPNStructure_parse(rr, rr->query->u.type_101->RPNStructure, GSQuery);
|
---|
354 | break; }
|
---|
355 | case Z_Query_type_102: {
|
---|
356 | cerr << "querytype = 102" << endl;
|
---|
357 | // this is just a buf (unsigned char*), pretend it's a Greenstone-type query
|
---|
358 | GSQuery += (char*)(rr->query->u.type_102->buf);
|
---|
359 | break; }
|
---|
360 | default: {
|
---|
361 | cerr << "Error in ZQueryToGSQuery" << endl;
|
---|
362 | exit(1); }
|
---|
363 | }
|
---|
364 |
|
---|
365 | // override GSQuery (test code)
|
---|
366 | //GSQuery = "[the]:TX";
|
---|
367 |
|
---|
368 | cerr << "GSQuery = `" << GSQuery << "'" << endl;
|
---|
369 | return GSQuery;
|
---|
370 | }
|
---|
371 |
|
---|