Implement SOLR xml int reader (for term + freq)
[yaz-moved-to-github.git] / src / solr.c
index 4e0a74a..84af29d 100644 (file)
@@ -14,6 +14,7 @@
 #include <yaz/yaz-iconv.h>
 #include <yaz/log.h>
 #include <yaz/facet.h>
+#include <yaz/wrbuf.h>
 
 #include "sru-p.h"
 
@@ -21,6 +22,7 @@
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 
+#define SOLR_MAX_PARAMETERS  100
 
 const char *xml_node_attribute_value_get(xmlNodePtr ptr, const char *node_name, const char *attribute_name) {
 
@@ -92,7 +94,7 @@ static void yaz_solr_decode_result_docs(ODR o, xmlNodePtr ptr, Odr_int start, Z_
     }
 }
 
-static void yaz_solr_decode_result(ODR o, xmlNodePtr ptr, Z_SRW_searchRetrieveResponse *sr) {
+static int  yaz_solr_decode_result(ODR o, xmlNodePtr ptr, Z_SRW_searchRetrieveResponse *sr) {
     Odr_int start = 0;
     struct _xmlAttr *attr;
     for (attr = ptr->properties; attr; attr = attr->next)
@@ -100,11 +102,16 @@ static void yaz_solr_decode_result(ODR o, xmlNodePtr ptr, Z_SRW_searchRetrieveRe
             if (!strcmp((const char *) attr->name, "numFound")) {
                 sr->numberOfRecords = odr_intdup(o, odr_atoi(
                         (const char *) attr->children->content));
-            } else if (!strcmp((const char *) attr->name, "start")) {
+            } 
+            else if (!strcmp((const char *) attr->name, "start")) {
                 start = odr_atoi((const char *) attr->children->content);
             }
         }
-    yaz_solr_decode_result_docs(o, ptr, start, sr);
+    if (sr->numberOfRecords && *sr->numberOfRecords > 0)
+        yaz_solr_decode_result_docs(o, ptr, start, sr);
+    if (sr->numberOfRecords)
+        return 0;
+    return -1;
 }
 
 static Z_AttributeList *yaz_solr_use_atttribute_create(ODR o, const char *name) {
@@ -114,8 +121,20 @@ static Z_AttributeList *yaz_solr_use_atttribute_create(ODR o, const char *name)
 
 
 static const char *get_facet_term_count(xmlNodePtr node, int *freq) {
-    // TODO implement
-    return 0;
+
+    const char *term = xml_node_attribute_value_get(node, "int", "name");
+    xmlNodePtr child;
+    WRBUF wrbuf = wrbuf_alloc();
+    if (!term)
+        return term;
+
+    for (child = node->children; child ; child = child->next) {
+        if (child->type == XML_TEXT_NODE)
+        wrbuf_puts(wrbuf, (const char *) child->content);
+    }
+    *freq = atoi(wrbuf_cstr(wrbuf));
+    wrbuf_destroy(wrbuf);
+    return term;
 }
 
 Z_FacetField *yaz_solr_decode_facet_field(ODR o, xmlNodePtr ptr, Z_SRW_searchRetrieveResponse *sr)
@@ -141,7 +160,7 @@ Z_FacetField *yaz_solr_decode_facet_field(ODR o, xmlNodePtr ptr, Z_SRW_searchRet
     return facet_field;
 }
 
-static void yaz_solr_decode_facet_counts(ODR o, xmlNodePtr root, Z_SRW_searchRetrieveResponse *sr) {
+static int yaz_solr_decode_facet_counts(ODR o, xmlNodePtr root, Z_SRW_searchRetrieveResponse *sr) {
     xmlNodePtr ptr;
     for (ptr = root->children; ptr; ptr = ptr->next)
     {
@@ -161,10 +180,11 @@ static void yaz_solr_decode_facet_counts(ODR o, xmlNodePtr root, Z_SRW_searchRet
                 facet_list_field_set(o, facet_list, yaz_solr_decode_facet_field(o, node, sr), num_facets);
                 num_facets++;
             }
-            sr->facet_list = facet_list;
+            sr->facetList = facet_list;
             break;
         }
     }
+    return 0;
 }
 
 static void yaz_solr_decode_facets(ODR o, xmlNodePtr ptr, Z_SRW_searchRetrieveResponse *sr) {
@@ -201,19 +221,18 @@ int yaz_solr_decode_response(ODR o, Z_HTTP_Response *hres, Z_SRW_PDU **pdup)
         }
         else
         {
-            /** look for result node */
+            /** look for result (required) and facets node (optional) */
+            int rc_result = -1;
+            int rc_facets = 0;
             for (ptr = root->children; ptr; ptr = ptr->next)
             {
                 if (ptr->type == XML_ELEMENT_NODE &&
                     !strcmp((const char *) ptr->name, "result"))
-                        yaz_solr_decode_result(o, ptr, sr);
+                        rc_result = yaz_solr_decode_result(o, ptr, sr);
                 if (match_xml_node_attribute(ptr, "lst", "name", "facet_counts"))
-                        yaz_solr_decode_facet_counts(o, ptr, sr);
-            }
-            if (!ptr)
-            {
-                ret = -1;
+                    rc_facets =  yaz_solr_decode_facet_counts(o, ptr, sr);
             }
+            ret = rc_result + rc_facets;
         }
     }
     if (doc)
@@ -226,17 +245,37 @@ int yaz_solr_decode_response(ODR o, Z_HTTP_Response *hres, Z_SRW_PDU **pdup)
 #endif
 }
 
-void solr_encode_facet_field(ODR encode, Z_FacetField *facet_field) {
+static void yaz_solr_encode_facet_field(ODR encode, char **name, char **value, int *i, Z_FacetField *facet_field, int *limit) {
+      Z_AttributeList *attribute_list = facet_field->attributes;
+      struct yaz_facet_attr attr_values;
+      yaz_facet_attr_init(&attr_values);
+      yaz_facet_attr_get_z_attributes(attribute_list, &attr_values);
+      // TODO do we want to support server decided
+      if (!attr_values.errcode && attr_values.useattr) {
+          yaz_add_name_value_str(encode, name, value, i, "facet.field", (char *) attr_values.useattr);
+          // TODO max(attr_values, *limit);
+          if (attr_values.limit > 0 && attr_values.limit > *limit) {
+              *limit = attr_values.limit;
+          }
+      }
+}
+
+static void yaz_solr_encode_facet_list(ODR encode, char **name, char **value, int *i, Z_FacetList *facet_list, int *limit) {
+
+    int index;
+    for (index = 0; index < facet_list->num; index++)  {
+        yaz_solr_encode_facet_field(encode, name, value, i, facet_list->elements[index], limit);
 
+    }
 }
 
+
 int yaz_solr_encode_request(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
                             ODR encode, const char *charset)
 {
     const char *solr_op = 0;
     //TODO Change. not a nice hard coded, unchecked limit.
-    int max = 100;
-    char *name[100], *value[100];
+    char *name[SOLR_MAX_PARAMETERS], *value[SOLR_MAX_PARAMETERS];
     char *uri_args;
     char *path;
     int i = 0;
@@ -273,14 +312,15 @@ int yaz_solr_encode_request(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
         yaz_add_name_value_str(encode, name, value, &i,
                                "fl", request->recordSchema);
 
-        if (request->facet_list) {
-            int index;
-            Z_FacetList *facet_list = request->facet_list;
+        if (request->facetList) {
+            Z_FacetList *facet_list = request->facetList;
+            int limit;
+            Odr_int olimit;
             yaz_add_name_value_str(encode, name, value, &i, "facet", "true");
-            for (index = 0; index < facet_list->num; index++) {
-                //TODO impl
-                //solr_encode_facet_field(encode, name, value, &i, facet_list->elements[index]);
-            }
+            yaz_solr_encode_facet_list(encode, name, value, &i, facet_list, &limit);
+            olimit = limit;
+            yaz_add_name_value_int(encode, name, value, &i, "facet.limit", &olimit);
+
         }
         break;
     }