[15425] | 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 | cerr << "Supressing square brackets for the moment!\n";
|
---|
| 248 |
|
---|
| 249 | Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
|
---|
| 250 | GSQuery += "]";
|
---|
| 251 | GSQuery += ":";
|
---|
| 252 | GSQuery += Short;
|
---|
| 253 | }
|
---|
| 254 | // if it doesn't, add it as an unfielded search term
|
---|
| 255 | else {
|
---|
| 256 | cerr << "[" << rr->basenames[0] << "]: failed to find index" << endl;
|
---|
| 257 | Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
|
---|
| 258 | }
|
---|
| 259 | }
|
---|
| 260 | }
|
---|
| 261 | else {
|
---|
| 262 | Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
|
---|
| 263 | }
|
---|
| 264 | break;
|
---|
| 265 | }
|
---|
| 266 | case Z_Operand_resultSetId: {
|
---|
| 267 | GSQuery += "(";
|
---|
| 268 | GSQuery += Resultsets[Z->u.resultSetId];
|
---|
| 269 | GSQuery += ")";
|
---|
| 270 | break;
|
---|
| 271 | }
|
---|
| 272 | case Z_Operand_resultAttr:
|
---|
| 273 | GSQuery += " "; // ignore this for now
|
---|
| 274 | break;
|
---|
| 275 | default:
|
---|
| 276 | cerr << "Error in Z_Operand_parse" << endl;
|
---|
| 277 | exit(1);
|
---|
| 278 | }
|
---|
| 279 | }
|
---|
| 280 |
|
---|
| 281 | void Z_RPNStructure_parse(bend_search_rr *rr, Z_RPNStructure *Z, text_t &GSQuery)
|
---|
| 282 | {
|
---|
| 283 | /*
|
---|
| 284 | struct Z_RPNStructure {
|
---|
| 285 | int which;
|
---|
| 286 | union {
|
---|
| 287 | Z_Operand *simple;
|
---|
| 288 | Z_Complex *complex;
|
---|
| 289 | #define Z_RPNStructure_simple 1
|
---|
| 290 | #define Z_RPNStructure_complex 2
|
---|
| 291 | } u;
|
---|
| 292 | };
|
---|
| 293 | */
|
---|
| 294 |
|
---|
| 295 | switch(Z->which){
|
---|
| 296 | case Z_RPNStructure_simple:
|
---|
| 297 | Z_Operand_parse(rr, Z->u.simple, GSQuery);
|
---|
| 298 | break;
|
---|
| 299 | case Z_RPNStructure_complex:
|
---|
| 300 | GSQuery += "(";
|
---|
| 301 | Z_RPNStructure_parse(rr, Z->u.complex->s1, GSQuery);
|
---|
| 302 | Z_Operator_parse(rr, Z->u.complex->roperator, GSQuery);
|
---|
| 303 | Z_RPNStructure_parse(rr, Z->u.complex->s2, GSQuery);
|
---|
| 304 | GSQuery += ")";
|
---|
| 305 | break;
|
---|
| 306 | default:
|
---|
| 307 | cerr << "Error in Z_RPNStructure_parse" << endl;
|
---|
| 308 | exit(1);
|
---|
| 309 | }
|
---|
| 310 | }
|
---|
| 311 |
|
---|
| 312 | text_t ZQueryToGSQuery(bend_search_rr *rr)
|
---|
| 313 | {
|
---|
| 314 | text_t GSQuery;
|
---|
| 315 |
|
---|
| 316 | switch(rr->query->which){
|
---|
| 317 | case Z_Query_type_0:
|
---|
| 318 | cerr << "querytype = 0" << endl;
|
---|
| 319 | // this is a void*, pretend it's a Greenstone-type query
|
---|
| 320 | GSQuery += (char*)(rr->query->u.type_0);
|
---|
| 321 | break;
|
---|
| 322 | case Z_Query_type_1: {
|
---|
| 323 | cerr << "querytype = 1" << endl;
|
---|
| 324 | /*
|
---|
| 325 | struct Z_RPNQuery {
|
---|
| 326 | Z_AttributeSetId *attributeSetId;
|
---|
| 327 | Z_RPNStructure *RPNStructure;
|
---|
| 328 | };
|
---|
| 329 | */
|
---|
| 330 | // parse attributeSetId
|
---|
| 331 | cerr << "attributeSetId = ";
|
---|
| 332 | int c, d = 0;
|
---|
| 333 | do {
|
---|
| 334 | c = rr->query->u.type_1->attributeSetId[d];
|
---|
| 335 | cerr << c;
|
---|
| 336 | d++;
|
---|
| 337 | } while (c >= 0);
|
---|
| 338 | cerr << endl;
|
---|
| 339 |
|
---|
| 340 | Z_RPNStructure_parse(rr, rr->query->u.type_1->RPNStructure, GSQuery);
|
---|
| 341 | break; }
|
---|
| 342 | case Z_Query_type_2: {
|
---|
| 343 | cerr << "querytype = 2" << endl;
|
---|
| 344 | // this is just a buf (unsigned char*), pretend it's a Greenstone-type query
|
---|
| 345 | GSQuery += (char*)(rr->query->u.type_2->buf);
|
---|
| 346 | break; }
|
---|
| 347 | case Z_Query_type_100: {
|
---|
| 348 | cerr << "querytype = 100" << endl;
|
---|
| 349 | // this is just a buf (unsigned char*), pretend it's a Greenstone-type query
|
---|
| 350 | GSQuery += (char*)(rr->query->u.type_100->buf);
|
---|
| 351 | break; }
|
---|
| 352 | case Z_Query_type_101: {
|
---|
| 353 | cerr << "querytype = 101" << endl;
|
---|
| 354 | // check: is this really the same as a type 1 query?
|
---|
| 355 | Z_RPNStructure_parse(rr, rr->query->u.type_101->RPNStructure, GSQuery);
|
---|
| 356 | break; }
|
---|
| 357 | case Z_Query_type_102: {
|
---|
| 358 | cerr << "querytype = 102" << endl;
|
---|
| 359 | // this is just a buf (unsigned char*), pretend it's a Greenstone-type query
|
---|
| 360 | GSQuery += (char*)(rr->query->u.type_102->buf);
|
---|
| 361 | break; }
|
---|
| 362 | default: {
|
---|
| 363 | cerr << "Error in ZQueryToGSQuery" << endl;
|
---|
| 364 | exit(1); }
|
---|
| 365 | }
|
---|
| 366 |
|
---|
| 367 | // override GSQuery (test code)
|
---|
| 368 | //GSQuery = "[the]:TX";
|
---|
| 369 |
|
---|
| 370 | cerr << "GSQuery = `" << GSQuery << "'" << endl;
|
---|
| 371 | return GSQuery;
|
---|
| 372 | }
|
---|
| 373 |
|
---|