Do not require requestsyntax to be set for pp2 transforms
[metaproxy-moved-to-github.git] / src / filter_zoom.cpp
index 44986d6..f7de862 100644 (file)
@@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include "config.hpp"
 #include "filter_zoom.hpp"
 #include <yaz/zoom.h>
+#include <yaz/yaz-version.h>
 #include <yaz/srw.h>
 #include <metaproxy/package.hpp>
 #include <metaproxy/util.hpp>
@@ -29,8 +30,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #include <boost/thread/mutex.hpp>
 #include <boost/thread/condition.hpp>
+#include <yaz/ccl_xml.h>
 #include <yaz/ccl.h>
 #include <yaz/rpn2cql.h>
+#include <yaz/rpn2solr.h>
 #include <yaz/pquery.h>
 #include <yaz/cql.h>
 #include <yaz/oid_db.h>
@@ -60,7 +63,7 @@ namespace metaproxy_1 {
             bool use_turbomarc;
             bool piggyback;
             CCL_bibset ccl_bibset;
-            Searchable();
+            Searchable(CCL_bibset base);
             ~Searchable();
         };
         class Zoom::Backend : boost::noncopyable {
@@ -84,7 +87,7 @@ namespace metaproxy_1 {
                          int *error, const char **addinfo);
             void set_option(const char *name, const char *value);
             const char *get_option(const char *name);
-            int get_error(const char **addinfo);
+            void get_zoom_error(int *error, const char **addinfo);
         };
         class Zoom::Frontend : boost::noncopyable {
             friend class Impl;
@@ -129,6 +132,7 @@ namespace metaproxy_1 {
             std::string torus_url;
             std::map<std::string,std::string> fieldmap;
             std::string xsldir;
+            CCL_bibset bibset;
         };
     }
 }
@@ -171,18 +175,35 @@ yf::Zoom::Backend::~Backend()
     ZOOM_resultset_destroy(m_resultset);
 }
 
+
+void yf::Zoom::Backend::get_zoom_error(int *error, const char **addinfo)
+{
+    const char *msg = 0;
+    *error = ZOOM_connection_error(m_connection, &msg, addinfo);
+    if (*error)
+    {
+        if (*error >= ZOOM_ERROR_CONNECT)
+        {
+            // turn ZOOM diagnostic into a Bib-1 2: with addinfo=zoom err msg
+            *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
+            if (addinfo)
+                *addinfo = msg;
+        }
+    }
+}
+
 void yf::Zoom::Backend::connect(std::string zurl,
                                 int *error, const char **addinfo)
 {
     ZOOM_connection_connect(m_connection, zurl.c_str(), 0);
-    *error = ZOOM_connection_error(m_connection, 0, addinfo);
+    get_zoom_error(error, addinfo);
 }
 
 void yf::Zoom::Backend::search_pqf(const char *pqf, Odr_int *hits,
                                    int *error, const char **addinfo)
 {
     m_resultset = ZOOM_connection_search_pqf(m_connection, pqf);
-    *error = ZOOM_connection_error(m_connection, 0, addinfo);
+    get_zoom_error(error, addinfo);
     if (*error == 0)
         *hits = ZOOM_resultset_size(m_resultset);
     else
@@ -198,7 +219,7 @@ void yf::Zoom::Backend::search_cql(const char *cql, Odr_int *hits,
 
     m_resultset = ZOOM_connection_search(m_connection, q);
     ZOOM_query_destroy(q);
-    *error = ZOOM_connection_error(m_connection, 0, addinfo);
+    get_zoom_error(error, addinfo);
     if (*error == 0)
         *hits = ZOOM_resultset_size(m_resultset);
     else
@@ -210,7 +231,7 @@ void yf::Zoom::Backend::present(Odr_int start, Odr_int number,
                                 int *error, const char **addinfo)
 {
     ZOOM_resultset_records(m_resultset, recs, start, number);
-    *error = ZOOM_connection_error(m_connection, 0, addinfo);
+    get_zoom_error(error, addinfo);
 }
 
 void yf::Zoom::Backend::set_option(const char *name, const char *value)
@@ -225,16 +246,11 @@ const char *yf::Zoom::Backend::get_option(const char *name)
     return ZOOM_connection_option_get(m_connection, name);
 }
 
-int yf::Zoom::Backend::get_error(const char **addinfo)
-{
-    return ZOOM_connection_error(m_connection, 0, addinfo);
-}
-
-yf::Zoom::Searchable::Searchable()
+yf::Zoom::Searchable::Searchable(CCL_bibset base)
 {
     piggyback = true;
     use_turbomarc = true;
-    ccl_bibset = ccl_qual_mk();
+    ccl_bibset = ccl_qual_dup(base);
 }
 
 yf::Zoom::Searchable::~Searchable()
@@ -298,10 +314,12 @@ void yf::Zoom::Impl::release_frontend(mp::Package &package)
 
 yf::Zoom::Impl::Impl()
 {
+    bibset = ccl_qual_mk();
 }
 
 yf::Zoom::Impl::~Impl()
 { 
+    ccl_qual_rm(&bibset);
 }
 
 yf::Zoom::SearchablePtr yf::Zoom::Impl::parse_torus(const xmlNode *ptr1)
@@ -322,7 +340,7 @@ yf::Zoom::SearchablePtr yf::Zoom::Impl::parse_torus(const xmlNode *ptr1)
                     continue;
                 if (!strcmp((const char *) ptr2->name, "layer"))
                 {
-                    Zoom::SearchablePtr s(new Searchable);
+                    Zoom::SearchablePtr s(new Searchable(bibset));
 
                     const xmlNode *ptr3 = ptr2;
                     for (ptr3 = ptr3->children; ptr3; ptr3 = ptr3->next)
@@ -433,6 +451,11 @@ void yf::Zoom::Impl::configure(const xmlNode *ptr, bool test_only)
                                                        attr->name));
             }
         }
+        else if (!strcmp((const char *) ptr->name, "cclmap"))
+        {
+            const char *addinfo = 0;
+            ccl_xml_config(bibset, ptr, &addinfo);
+        }
         else if (!strcmp((const char *) ptr->name, "fieldmap"))
         {
             const struct _xmlAttr *attr;
@@ -452,10 +475,6 @@ void yf::Zoom::Impl::configure(const xmlNode *ptr, bool test_only)
             if (cql_field.length())
                 fieldmap[cql_field] = ccl_field;
         }
-        else if (!strcmp((const char *) ptr->name, "records"))
-        {
-            yaz_log(YLOG_WARN, "records ignored!");
-        }
         else
         {
             throw mp::filter::FilterException
@@ -538,6 +557,8 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
     b->xsp = xsp;
     b->m_frontend_database = database;
     std::string authentication = sptr->authentication;
+        
+    b->set_option("timeout", "40");
 
     if (sptr->query_encoding.length())
         b->set_option("rpnCharset", sptr->query_encoding.c_str());
@@ -629,10 +650,8 @@ Z_Records *yf::Zoom::Frontend::get_records(Odr_int start,
             !strcmp(element_set_name, "pz2"))
         {
             if (b->sptr->request_syntax.length())
-            {
                 syntax_name = b->sptr->request_syntax.c_str();
-                enable_pz2_transform = true;
-            }
+            enable_pz2_transform = true;
         }
         else
         {
@@ -940,29 +959,40 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package)
     assert(pqf_wrbuf);
     if (b->get_option("sru"))
     {
-        cql_transform_t cqlt = cql_transform_create();
+        int status = 0;
         Z_RPNQuery *zquery;
-        WRBUF wrb = wrbuf_alloc();
-        int status;
-        
         zquery = p_query_rpn(odr, wrbuf_cstr(pqf_wrbuf));
-        status = cql_transform_rpn2cql_wrbuf(cqlt, wrb, zquery);
-        
-        cql_transform_close(cqlt);
-
+        WRBUF wrb = wrbuf_alloc();
+            
+        if (!strcmp(b->get_option("sru"), "solr"))
+        {
+            solr_transform_t cqlt = solr_transform_create();
+            
+            status = solr_transform_rpn2solr_wrbuf(cqlt, wrb, zquery);
+            
+            solr_transform_close(cqlt);
+        }
+        else
+        {
+            cql_transform_t cqlt = cql_transform_create();
+            
+            status = cql_transform_rpn2cql_wrbuf(cqlt, wrb, zquery);
+            
+            cql_transform_close(cqlt);
+        }
         if (status == 0)
         {
             yaz_log(YLOG_LOG, "search CQL: %s", wrbuf_cstr(wrb));
             b->search_cql(wrbuf_cstr(wrb), &hits, &error, &addinfo);
         }
-
+        
         wrbuf_destroy(wrb);
         wrbuf_destroy(pqf_wrbuf);
         if (status)
         {
             apdu_res = 
                 odr.create_searchResponse(apdu_req, YAZ_BIB1_MALFORMED_QUERY,
-                                          "can not convert from RPN to CQL");
+                                          "can not convert from RPN to CQL/SOLR");
             package.response() = apdu_res;
             return;
         }