YAZ  5.25.0
solr.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
9 #if HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12 
13 #include <stdlib.h>
14 #include <assert.h>
15 #include <yaz/srw.h>
16 #include <yaz/matchstr.h>
17 #include <yaz/yaz-iconv.h>
18 #include <yaz/log.h>
19 #include <yaz/facet.h>
20 #include <yaz/wrbuf.h>
21 #include <yaz/proto.h>
22 #include <yaz/nmem_xml.h>
23 
24 #include "sru-p.h"
25 
26 #if YAZ_HAVE_XML2
27 #include <libxml/parser.h>
28 #include <libxml/tree.h>
29 
30 static void extract_text_node(xmlNodePtr node, WRBUF wrbuf)
31 {
32  xmlNodePtr child;
33  for (child = node->children; child ; child = child->next)
34  {
35  if (child->type == XML_TEXT_NODE)
36  wrbuf_puts(wrbuf, (const char *) child->content);
37  }
38 }
39 
41  xmlNodePtr ptr,
42  const char *node_name, const char *attribute_name, const char *value)
43 {
44  const char *attribute_value;
45  // check if the node name matches
46  if (strcmp((const char*) ptr->name, node_name))
47  return 0;
48  if (attribute_name)
49  {
50  attribute_value = yaz_element_attribute_value_get(ptr, node_name,
51  attribute_name);
52  if (attribute_value && !strcmp(attribute_value, value))
53  return 1;
54  }
55  else /* No attribute to check */
56  return 1;
57  return 0;
58 }
59 
60 static void yaz_solr_decode_result_docs(ODR o, xmlNodePtr ptr,
61  Odr_int start,
63 {
64  xmlNodePtr node;
65  int offset = 0;
66  int i = 0;
67 
68  sr->num_records = 0;
69  for (node = ptr->children; node; node = node->next)
70  if (node->type == XML_ELEMENT_NODE)
71  sr->num_records++;
72 
73  if (sr->num_records)
74  sr->records = odr_malloc(o, sizeof(*sr->records) * sr->num_records);
75 
76  for (node = ptr->children; node; node = node->next)
77  {
78  if (node->type == XML_ELEMENT_NODE)
79  {
80  Z_SRW_record *record = sr->records + i;
81  xmlBufferPtr buf = xmlBufferCreate();
82  xmlNode *tmp = xmlCopyNode(node, 1);
83 
84  xmlNodeDump(buf, tmp->doc, tmp, 0, 0);
85 
86  xmlFreeNode(tmp);
87 
88  record->recordSchema = 0;
90  record->recordData_len = buf->use;
91  record->recordData_buf =
92  odr_strdupn(o, (const char *) buf->content, buf->use);
93  record->recordPosition = odr_intdup(o, start + offset + 1);
94 
95  xmlBufferFree(buf);
96 
97  offset++;
98  i++;
99  }
100  }
101 }
102 
103 static int yaz_solr_decode_result(ODR o, xmlNodePtr ptr,
105 {
106  Odr_int start = 0;
107  struct _xmlAttr *attr;
108  for (attr = ptr->properties; attr; attr = attr->next)
109  if (attr->children && attr->children->type == XML_TEXT_NODE)
110  {
111  if (!strcmp((const char *) attr->name, "numFound"))
112  {
114  (const char *) attr->children->content));
115  }
116  else if (!strcmp((const char *) attr->name, "start"))
117  {
118  start = odr_atoi((const char *) attr->children->content);
119  }
120  }
121  if (sr->numberOfRecords && *sr->numberOfRecords > 0)
122  yaz_solr_decode_result_docs(o, ptr, start, sr);
123  if (sr->numberOfRecords)
124  return 0;
125  return -1;
126 }
127 
128 static const char *get_facet_term_count(xmlNodePtr node, Odr_int *freq)
129 {
130  const char *term = yaz_element_attribute_value_get(node, "int", "name");
131  xmlNodePtr child;
132  WRBUF wrbuf = wrbuf_alloc();
133  if (!term)
134  return term;
135 
136  for (child = node->children; child ; child = child->next)
137  {
138  if (child->type == XML_TEXT_NODE)
139  wrbuf_puts(wrbuf, (const char *) child->content);
140  }
141  *freq = odr_atoi(wrbuf_cstr(wrbuf));
142  wrbuf_destroy(wrbuf);
143  return term;
144 }
145 
148 
149 {
150  Z_AttributeList *list;
151  Z_FacetField *facet_field;
152  int num_terms = 0;
153  int index = 0;
154  xmlNodePtr node;
155  // USE attribute
156  const char* name = yaz_element_attribute_value_get(ptr, "lst", "name");
157  list = zget_AttributeList_use_string(o, name);
158  for (node = ptr->children; node; node = node->next)
159  num_terms++;
160  facet_field = facet_field_create(o, list, num_terms);
161  index = 0;
162  for (node = ptr->children; node; node = node->next)
163  {
164  Odr_int count = 0;
165  const char *term = get_facet_term_count(node, &count);
166  facet_field_term_set(o, facet_field,
167  facet_term_create_cstr(o, term, count), index);
168  index++;
169  }
170  return facet_field;
171 }
172 
173 static int yaz_solr_decode_facet_counts(ODR o, xmlNodePtr root,
175 {
176  xmlNodePtr ptr;
177  for (ptr = root->children; ptr; ptr = ptr->next)
178  {
179  if (match_xml_node_attribute(ptr, "lst", "name", "facet_fields"))
180  {
181  xmlNodePtr node;
182  Z_FacetList *facet_list;
183  int num_facets = 0;
184  for (node = ptr->children; node; node= node->next)
185  {
186  num_facets++;
187  }
188  facet_list = facet_list_create(o, num_facets);
189  num_facets = 0;
190  for (node = ptr->children; node; node= node->next)
191  {
192  facet_list_field_set(o, facet_list,
193  yaz_solr_decode_facet_field(o, node, sr),
194  num_facets);
195  num_facets++;
196  }
197  sr->facetList = facet_list;
198  break;
199  }
200  }
201  return 0;
202 }
203 
204 static void yaz_solr_decode_suggestion_values(xmlNodePtr listPptr, WRBUF wrbuf)
205 {
206  xmlNodePtr node;
207  for (node = listPptr; node; node= node->next)
208  if (!strcmp((char*) node->name, "lst"))
209  {
210  xmlNodePtr child;
211  for (child = node->children; child; child= child->next)
212  {
213  if (match_xml_node_attribute(child, "str", "name", "word"))
214  {
215  wrbuf_puts(wrbuf, "<suggestion>");
216  extract_text_node(child, wrbuf);
217  wrbuf_puts(wrbuf, "</suggestion>\n");
218  }
219  }
220  }
221 }
222 
223 static void yaz_solr_decode_suggestion_lst(xmlNodePtr lstPtr, WRBUF wrbuf)
224 {
225  xmlNodePtr node;
226  for (node = lstPtr; node; node= node->next)
227  if (match_xml_node_attribute(node, "arr", "name", "suggestion"))
228  yaz_solr_decode_suggestion_values(node->children, wrbuf);
229 }
230 
231 static void yaz_solr_decode_misspelled(xmlNodePtr lstPtr, WRBUF wrbuf)
232 {
233  xmlNodePtr node;
234  for (node = lstPtr; node; node= node->next)
235  {
236  if (!strcmp((const char*) node->name, "lst"))
237  {
238  const char *misspelled =
239  yaz_element_attribute_value_get(node, "lst", "name");
240  if (misspelled)
241  {
242  wrbuf_printf(wrbuf, "<misspelled term=\"%s\">\n", misspelled);
243  yaz_solr_decode_suggestion_lst(node->children, wrbuf);
244  wrbuf_puts(wrbuf, "</misspelled>\n");
245  }
246  }
247  }
248 }
249 
250 static int yaz_solr_decode_spellcheck(ODR o, xmlNodePtr spellcheckPtr, Z_SRW_searchRetrieveResponse *sr)
251 {
252  xmlNodePtr ptr;
253  WRBUF wrbuf = wrbuf_alloc();
254  wrbuf_puts(wrbuf, "");
255  for (ptr = spellcheckPtr->children; ptr; ptr = ptr->next)
256  {
257  if (match_xml_node_attribute(ptr, "lst", "name", "suggestions"))
258  {
259  yaz_solr_decode_misspelled(ptr->children, wrbuf);
260  }
261  }
262  sr->suggestions = odr_strdup(o, wrbuf_cstr(wrbuf));
263  return 0;
264 }
265 
266 static int yaz_solr_decode_scan_result(ODR o, xmlNodePtr ptr,
267  Z_SRW_scanResponse *scr)
268 {
269  xmlNodePtr node;
270  char *pos;
271  int i = 0;
272 
273  /* find the actual list */
274  for (node = ptr->children; node; node = node->next)
275  if (node->type == XML_ELEMENT_NODE)
276  {
277  ptr = node;
278  break;
279  }
280 
281  scr->num_terms = 0;
282  for (node = ptr->children; node; node = node->next)
283  if (node->type == XML_ELEMENT_NODE &&
284  !strcmp((const char *) node->name, "int"))
285  scr->num_terms++;
286 
287  if (scr->num_terms)
288  scr->terms = odr_malloc(o, sizeof(*scr->terms) * scr->num_terms);
289 
290  for (node = ptr->children; node; node = node->next)
291  {
292  if (node->type == XML_ELEMENT_NODE &&
293  !strcmp((const char *) node->name, "int"))
294  {
295  Z_SRW_scanTerm *term = scr->terms + i;
296 
297  Odr_int count = 0;
298  const char *val = get_facet_term_count(node, &count);
299 
300  term->numberOfRecords = odr_intdup(o, count);
301 
302  /* if val contains a ^ then it is probably term<^>display term so separate them. This is due to
303  * SOLR not being able to encode them into 2 separate attributes.
304  */
305  pos = strchr(val, '^');
306  if (pos != NULL)
307  {
308  term->displayTerm = odr_strdup(o, pos + 1);
309  *pos = '\0';
310  term->value = odr_strdup(o, val);
311  *pos = '^';
312  }
313  else
314  {
315  term->value = odr_strdup(o, val);
316  term->displayTerm = NULL;
317  }
318  term->whereInList = NULL;
319  i++;
320  }
321  }
322 
323  if (scr->num_terms)
324  return 0;
325  return -1;
326 }
327 
328 static int yaz_solr_decode_error(ODR o, xmlNode *ptr,
330 {
331  for (ptr = ptr->children; ptr; ptr = ptr->next)
332  if (ptr->type == XML_ELEMENT_NODE &&
333  match_xml_node_attribute(ptr, "str", "name", "msg"))
334  {
335  char *msg = nmem_text_node_cdata(ptr->children, odr_getmem(o));
338  }
339  return 0;
340 }
341 
342 #endif
343 
345 {
346  int ret = -1;
347  Z_SRW_PDU *pdu = 0;
348 #if YAZ_HAVE_XML2
349  const char *content_buf = hres->content_buf;
350  int content_len = hres->content_len;
351  xmlDocPtr doc = xmlParseMemory(content_buf, content_len);
352 
353  if (doc)
354  {
355  Z_SRW_searchRetrieveResponse *sr = NULL;
356  Z_SRW_scanResponse *scr = NULL;
357  xmlNodePtr ptr;
358  xmlNodePtr root = xmlDocGetRootElement(doc);
359  if (root && !strcmp((const char *) root->name, "response"))
360  {
361  for (ptr = root->children; ptr; ptr = ptr->next)
362  {
363  if (!pdu && ptr->type == XML_ELEMENT_NODE &&
364  match_xml_node_attribute(ptr, "lst", "name", "error"))
365  {
367  sr = pdu->u.response;
368  ret = yaz_solr_decode_error(o, ptr, sr);
369  }
370  if (ptr->type == XML_ELEMENT_NODE &&
371  !strcmp((const char *) ptr->name, "result"))
372  {
374  sr = pdu->u.response;
375  ret = yaz_solr_decode_result(o, ptr, sr);
376  }
377  if (ptr->type == XML_ELEMENT_NODE &&
378  match_xml_node_attribute(ptr, "lst", "name", "terms"))
379  {
381  scr = pdu->u.scan_response;
382  ret = yaz_solr_decode_scan_result(o, ptr, scr);
383  }
384  /* The check on hits is a work-around to avoid garbled
385  facets on zero results from the SOLR server.
386  The work-around works because the results is before
387  the facets in the xml.
388  */
389  if (sr && sr->numberOfRecords)
390  {
391  if (*sr->numberOfRecords > 0 &&
392  match_xml_node_attribute(ptr, "lst", "name",
393  "facet_counts"))
394  ret = yaz_solr_decode_facet_counts(o, ptr, sr);
395  if (*sr->numberOfRecords == 0 &&
396  match_xml_node_attribute(ptr, "lst", "name",
397  "spellcheck"))
398  ret = yaz_solr_decode_spellcheck(o, ptr, sr);
399  }
400  }
401  }
402  xmlFreeDoc(doc);
403  }
404 #endif
405  *pdup = pdu;
406  return ret;
407 }
408 
410  ODR encode, char **name, char **value, int *i,
411  Z_FacetField *facet_field)
412 {
413  Z_AttributeList *attribute_list = facet_field->attributes;
414  struct yaz_facet_attr attr_values;
415  yaz_facet_attr_init(&attr_values);
416  yaz_facet_attr_get_z_attributes(attribute_list, &attr_values);
417 
418  if (attr_values.errcode)
419  return -1;
420  if (attr_values.useattr)
421  {
422  WRBUF wrbuf = wrbuf_alloc();
423  yaz_add_name_value_str(encode, name, value, i,
424  "facet.field",
425  odr_strdup(encode, attr_values.useattr));
426 
427  if (attr_values.limit > 0)
428  {
429  Odr_int v = attr_values.limit;
430  wrbuf_rewind(wrbuf);
431  wrbuf_printf(wrbuf, "f.%s.facet.limit", attr_values.useattr);
432  yaz_add_name_value_int(encode, name, value, i,
433  odr_strdup(encode, wrbuf_cstr(wrbuf)),
434  &v);
435  }
436  if (attr_values.start > 1)
437  {
438  Odr_int v = attr_values.start - 1;
439  wrbuf_rewind(wrbuf);
440  wrbuf_printf(wrbuf, "f.%s.facet.offset", attr_values.useattr);
441  yaz_add_name_value_int(encode, name, value, i,
442  odr_strdup(encode, wrbuf_cstr(wrbuf)),
443  &v);
444  }
445  if (attr_values.sortorder == 1)
446  {
447  wrbuf_rewind(wrbuf);
448  wrbuf_printf(wrbuf, "f.%s.facet.sort", attr_values.useattr);
449  yaz_add_name_value_str(encode, name, value, i,
450  odr_strdup(encode, wrbuf_cstr(wrbuf)),
451  "index");
452  }
453  wrbuf_destroy(wrbuf);
454  }
455  else
456  {
457  if (attr_values.limit > 0)
458  {
459  Odr_int v = attr_values.limit;
460  yaz_add_name_value_int(encode, name, value, i, "facet.limit", &v);
461  }
462  if (attr_values.start > 1)
463  {
464  Odr_int v = attr_values.start - 1;
465  yaz_add_name_value_int(encode, name, value, i, "facet.offset", &v);
466  }
467  if (attr_values.sortorder == 1)
468  {
469  yaz_add_name_value_str(encode, name, value, i, "facet.sort",
470  "index");
471  }
472  }
473  return 0;
474 }
475 
477  ODR encode, char **name, char **value,
478  int *i, Z_FacetList *facet_list)
479 {
480  int index;
481  for (index = 0; index < facet_list->num; index++)
482  {
483  int r = yaz_solr_encode_facet_field(encode, name, value, i,
484  facet_list->elements[index]);
485  if (r)
486  return -1;
487 
488  }
489  return 0;
490 }
491 
493  ODR encode, const char *charset)
494 {
495  const char *solr_op = 0;
496  char **name, **value;
497  char *uri_args;
498  char *path;
499  char *q;
500  char *cp;
501  int i = 0;
502  int defType_set = 0;
503  int no_parms = 20; /* safe upper limit of args without extra_args */
504  Z_SRW_extra_arg *ea;
505 
506  if (srw_pdu->which == Z_SRW_searchRetrieve_request)
507  { /* to make room for facets in yaz_solr_encode_facet_list later */
509  if (request->facetList)
510  no_parms += request->facetList->num;
511  }
512  for (ea = srw_pdu->extra_args; ea; ea = ea->next)
513  no_parms++;
514  name = (char **) odr_malloc(encode, sizeof(*name) * no_parms);
515  value = (char **) odr_malloc(encode, sizeof(*value) * no_parms);
516 
517  for (ea = srw_pdu->extra_args; ea; ea = ea->next)
518  {
519  name[i] = ea->name;
520  if (!strcmp(ea->name, "defType"))
521  defType_set = 1;
522  value[i] = ea->value;
523  i++;
524  }
525 
526  z_HTTP_header_add_basic_auth(encode, &hreq->headers,
527  srw_pdu->username, srw_pdu->password);
528  if (srw_pdu->which == Z_SRW_searchRetrieve_request)
529  {
531  solr_op = "select";
532  if (!srw_pdu->u.request->query)
533  return -1;
534  if (!defType_set)
535  yaz_add_name_value_str(encode, name, value, &i, "defType",
536  "lucene");
537  yaz_add_name_value_str(encode, name, value, &i, "q", request->query);
538  if (srw_pdu->u.request->startRecord)
539  {
540  Odr_int start = *request->startRecord - 1;
541  yaz_add_name_value_int(encode, name, value, &i,
542  "start", &start);
543  }
544  yaz_add_name_value_int(encode, name, value, &i,
545  "rows", request->maximumRecords);
546  yaz_add_name_value_str(encode, name, value, &i,
547  "fl", request->recordSchema);
548 
549  switch(srw_pdu->u.request->sort_type)
550  {
552  break;
554  yaz_add_name_value_str(encode, name, value, &i, "sort",
555  srw_pdu->u.request->sort.sortKeys);
556  break;
557  }
558  if (request->facetList)
559  {
560  Z_FacetList *facet_list = request->facetList;
561  yaz_add_name_value_str(encode, name, value, &i, "facet", "true");
562  yaz_add_name_value_str(encode, name, value, &i, "facet.mincount", "1");
563  if (yaz_solr_encode_facet_list(encode, name, value, &i, facet_list))
564  return -1;
565  }
566  }
567  else if (srw_pdu->which == Z_SRW_scan_request)
568  {
570  solr_op = "terms";
571  if (!srw_pdu->u.scan_request->scanClause)
572  return -1;
573  if (!strcmp(srw_pdu->u.scan_request->queryType, "pqf"))
574  {
575  yaz_add_name_value_str(encode, name, value, &i,
576  "terms.fl", request->scanClause);
577  yaz_add_name_value_str(encode, name, value, &i,
578  "terms.lower", request->scanClause);
579  }
580  else if (!strcmp(srw_pdu->u.scan_request->queryType, "cql"))
581  {
582  q = request->scanClause;
583  cp = strchr(q, ':');
584  if (cp != NULL)
585  {
586  yaz_add_name_value_str(encode, name, value, &i,
587  "terms.lower", odr_strdup(encode, cp + 1));
588  *cp = '\0';
589  yaz_add_name_value_str(encode, name, value, &i,
590  "terms.fl", odr_strdup(encode, q));
591  *cp = ':';
592  }
593  else
594  yaz_add_name_value_str(encode, name, value, &i,
595  "terms.lower", odr_strdup(encode, q));
596  }
597  else
598  return -1;
599  yaz_add_name_value_str(encode, name, value, &i,
600  "terms.sort", "index");
601  yaz_add_name_value_int(encode, name, value, &i,
602  "terms.limit", request->maximumTerms);
603  }
604  else
605  return -1;
606 
607  name[i++] = 0;
608 
609  yaz_array_to_uri(&uri_args, encode, name, value);
610 
611  hreq->method = "GET";
612 
613  path = (char *)
614  odr_malloc(encode, strlen(hreq->path) +
615  strlen(uri_args) + strlen(solr_op) + 5);
616 
617  cp = strchr(hreq->path, '#');
618  if (cp)
619  *cp = '\0';
620  strcpy(path, hreq->path);
621  cp = strchr(path, '?');
622  if (cp && strcmp(solr_op, "terms"))
623  { /* complete path with requestHandler */
624  int last = path[strlen(path)-1];
625  if (last != '?' && last != '&')
626  strcat(path, "&");
627  }
628  else
629  {
630  /* add requestHandler ourselves */
631  cp = strrchr(path, '/');
632  if (cp)
633  {
634  if (!strcmp(cp, "/select") || !strcmp(cp, "/"))
635  *cp = '\0';
636  }
637  strcat(path, "/");
638  strcat(path, solr_op);
639  strcat(path, "?");
640  }
641  strcat(path, uri_args);
642  hreq->path = path;
643  return 0;
644 }
645 
646 
647 /*
648  * Local variables:
649  * c-basic-offset: 4
650  * c-file-style: "Stroustrup"
651  * indent-tabs-mode: nil
652  * End:
653  * vim: shiftwidth=4 tabstop=8 expandtab
654  */
655 
Z_SRW_scanRequest * scan_request
Definition: srw.h:207
static int yaz_solr_decode_error(ODR o, xmlNode *ptr, Z_SRW_searchRetrieveResponse *sr)
Definition: solr.c:328
Header for Nibble Memory functions + Libxml2 specific stuff.
#define Z_SRW_scan_request
Definition: srw.h:195
#define Z_SRW_scan_response
Definition: srw.h:196
Z_AttributeList * attributes
Definition: z-facet-1.h:36
Odr_int * startRecord
Definition: srw.h:83
void yaz_facet_attr_get_z_attributes(const Z_AttributeList *attributes, struct yaz_facet_attr *av)
Definition: facet.c:147
#define YAZ_SRW_UNSUPP_PARAMETER_VALUE
Definition: diagsrw.h:15
SRU private header.
Odr_int * numberOfRecords
Definition: srw.h:140
static int node(struct cql_node *cn, void(*pr)(const char *buf, void *client_data), void *client_data)
Definition: cql2ccl.c:86
char * recordData_buf
Definition: srw.h:58
char * odr_strdup(ODR o, const char *str)
Definition: odr_mem.c:36
Header for WRBUF (growing buffer)
int yaz_solr_encode_request(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, ODR encode, const char *charset)
encode SOLR request (HTTP)
Definition: solr.c:492
void z_HTTP_header_add_basic_auth(ODR o, Z_HTTP_Header **hp, const char *username, const char *password)
Definition: http.c:168
int errcode
Definition: facet.h:54
int start
Definition: facet.h:62
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
Definition: wrbuf.c:281
void yaz_add_name_value_int(ODR o, char **name, char **value, int *i, char *a_name, Odr_int *val)
Definition: srwutil.c:929
union Z_SRW_searchRetrieveRequest::@32 sort
Z_SRW_scanTerm * terms
Definition: srw.h:146
static const char * get_facet_term_count(xmlNodePtr node, Odr_int *freq)
Definition: solr.c:128
Header for SRW/SRU.
char * name
Definition: initopt.c:18
static void yaz_solr_decode_suggestion_lst(xmlNodePtr lstPtr, WRBUF wrbuf)
Definition: solr.c:223
#define Z_SRW_sort_type_sort
Definition: srw.h:75
void wrbuf_puts(WRBUF b, const char *buf)
appends C-string to WRBUF
Definition: wrbuf.c:89
char * password
Definition: srw.h:214
union Z_SRW_PDU::@33 u
char * scanClause
Definition: srw.h:131
Z_AttributeList * zget_AttributeList_use_string(ODR o, const char *name)
creates AttributeList with type=1(use) and string value
Definition: pquery.c:310
Z_SRW_searchRetrieveResponse * response
Definition: srw.h:204
Odr_int * numberOfRecords
Definition: srw.h:98
Z_FacetList * facetList
Definition: srw.h:94
nmem_int_t Odr_int
Definition: odr.h:47
void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d, int *num, int code, const char *addinfo)
Definition: srwutil.c:185
Z_SRW_scanResponse * scan_response
Definition: srw.h:208
string buffer
Definition: wrbuf.h:42
Z_FacetList * facet_list_create(ODR odr, int num_facets)
Definition: facet.c:215
static int yaz_solr_encode_facet_list(ODR encode, char **name, char **value, int *i, Z_FacetList *facet_list)
Definition: solr.c:476
void * odr_malloc(ODR o, size_t size)
Definition: odr_mem.c:31
void yaz_add_name_value_str(ODR o, char **name, char **value, int *i, char *a_name, char *val)
Definition: srwutil.c:941
Header for YAZ iconv interface.
Odr_int * maximumTerms
Definition: srw.h:133
char * queryType
Definition: srw.h:130
static int yaz_solr_decode_scan_result(ODR o, xmlNodePtr ptr, Z_SRW_scanResponse *scr)
Definition: solr.c:266
void facet_field_term_set(ODR odr, Z_FacetField *field, Z_FacetTerm *facet_term, int index)
Definition: facet.c:208
Odr_int * maximumRecords
Definition: srw.h:84
char * path
Definition: zgdu.h:51
void wrbuf_rewind(WRBUF b)
empty WRBUF content (length of buffer set to 0)
Definition: wrbuf.c:47
static void yaz_solr_decode_result_docs(ODR o, xmlNodePtr ptr, Odr_int start, Z_SRW_searchRetrieveResponse *sr)
Definition: solr.c:60
static void yaz_solr_decode_misspelled(xmlNodePtr lstPtr, WRBUF wrbuf)
Definition: solr.c:231
static int yaz_solr_decode_result(ODR o, xmlNodePtr ptr, Z_SRW_searchRetrieveResponse *sr)
Definition: solr.c:103
static void yaz_solr_decode_suggestion_values(xmlNodePtr listPptr, WRBUF wrbuf)
Definition: solr.c:204
Z_SRW_diagnostic * diagnostics
Definition: srw.h:106
static int yaz_solr_decode_facet_counts(ODR o, xmlNodePtr root, Z_SRW_searchRetrieveResponse *sr)
Definition: solr.c:173
void wrbuf_printf(WRBUF b, const char *fmt,...)
writes printf result to WRBUF
Definition: wrbuf.c:178
Z_FacetField * facet_field_create(ODR odr, Z_AttributeList *attributes, int num_terms)
Definition: facet.c:198
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
Definition: wrbuf.c:38
int recordPacking
Definition: srw.h:53
Z_SRW_PDU * yaz_srw_get(ODR o, int which)
Definition: srwutil.c:757
Header for Z39.50 Protocol.
const char * yaz_element_attribute_value_get(xmlNodePtr ptr, const char *node_name, const char *attribute_name)
Definition: srwutil.c:71
char * recordSchema
Definition: srw.h:51
Header for the facet utilities.
Z_SRW_extra_arg * extra_args
Definition: srw.h:219
static int yaz_solr_encode_facet_field(ODR encode, char **name, char **value, int *i, Z_FacetField *facet_field)
Definition: solr.c:409
Z_SRW_extra_arg * next
Definition: srw.h:175
char * username
Definition: srw.h:213
char * value
Definition: srw.h:139
char * whereInList
Definition: srw.h:142
int which
Definition: srw.h:201
Odr_int * odr_intdup(ODR o, Odr_int v)
Definition: odr_mem.c:51
char * content_buf
Definition: zgdu.h:61
Definition: odr.h:124
Odr_int * recordPosition
Definition: srw.h:60
int content_len
Definition: zgdu.h:62
const char * useattr
Definition: facet.h:56
void yaz_array_to_uri(char **path, ODR o, char **name, char **value)
Definition: uri.c:98
Z_SRW_record * records
Definition: srw.h:103
void yaz_facet_attr_init(struct yaz_facet_attr *attr_values)
Definition: facet.c:68
char * nmem_text_node_cdata(const xmlNode *ptr_cdata, NMEM nmem)
copies TEXT Libxml2 node data to NMEM
Definition: nmemsdup.c:145
Z_FacetList * facetList
Definition: srw.h:111
Z_FacetField * yaz_solr_decode_facet_field(ODR o, xmlNodePtr ptr, Z_SRW_searchRetrieveResponse *sr)
Definition: solr.c:146
Z_FacetField ** elements
Definition: z-facet-1.h:32
Header for YAZ iconv interface.
char * name
Definition: srw.h:173
#define odr_getmem(o)
Definition: odr.h:216
int yaz_solr_decode_response(ODR o, Z_HTTP_Response *hres, Z_SRW_PDU **pdup)
decode SOLR response (HTTP)
Definition: solr.c:344
#define Z_SRW_searchRetrieve_request
Definition: srw.h:191
static int match_xml_node_attribute(xmlNodePtr ptr, const char *node_name, const char *attribute_name, const char *value)
Definition: solr.c:40
char * method
Definition: zgdu.h:49
Z_FacetTerm * facet_term_create_cstr(ODR odr, const char *cstr, Odr_int freq)
Definition: facet.c:189
Odr_int odr_atoi(const char *s)
Definition: odr_mem.c:146
Z_HTTP_Header * headers
Definition: zgdu.h:52
int recordData_len
Definition: srw.h:59
Logging utility.
char * displayTerm
Definition: srw.h:141
int sortorder
Definition: facet.h:60
static void extract_text_node(xmlNodePtr node, WRBUF wrbuf)
Definition: solr.c:30
#define Z_SRW_searchRetrieve_response
Definition: srw.h:192
Z_SRW_searchRetrieveRequest * request
Definition: srw.h:203
char * odr_strdupn(ODR o, const char *str, size_t n)
Definition: odr_mem.c:46
int limit
Definition: facet.h:61
Definition: srw.h:200
#define Z_SRW_recordPacking_XML
Definition: srw.h:55
char * value
Definition: srw.h:174
WRBUF wrbuf_alloc(void)
construct WRBUF
Definition: wrbuf.c:25
void facet_list_field_set(ODR odr, Z_FacetList *list, Z_FacetField *field, int index)
Definition: facet.c:224
static int yaz_solr_decode_spellcheck(ODR o, xmlNodePtr spellcheckPtr, Z_SRW_searchRetrieveResponse *sr)
Definition: solr.c:250
#define Z_SRW_sort_type_none
Definition: srw.h:74