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