session_shared: Hit count is type Odr_int
[metaproxy-moved-to-github.git] / src / filter_zoom.cpp
index a75c4d4..ae84b7b 100644 (file)
@@ -76,6 +76,7 @@ namespace metaproxy_1 {
             std::string urlRecipe;
             std::string contentConnector;
             std::string sortStrategy;
+            std::string rpn2cql_fname;
             bool use_turbomarc;
             bool piggyback;
             CCL_bibset ccl_bibset;
@@ -98,6 +99,7 @@ namespace metaproxy_1 {
             bool enable_explain;
             xmlDoc *explain_doc;
             std::string m_proxy;
+            cql_transform_t cqlt;
         public:
             Backend();
             ~Backend();
@@ -127,6 +129,7 @@ namespace metaproxy_1 {
                                       int *error,
                                       char **addinfo,
                                       mp::odr &odr,
+                                      std::string torus_url,
                                       std::string &torus_db,
                                       std::string &realm);
             void handle_present(mp::Package &package);
@@ -292,6 +295,7 @@ yf::Zoom::Backend::~Backend()
         xsltFreeStylesheet(xsp);
     if (explain_doc)
         xmlFreeDoc(explain_doc);
+    cql_transform_close(cqlt);
     ZOOM_connection_destroy(m_connection);
     ZOOM_resultset_destroy(m_resultset);
 }
@@ -593,6 +597,8 @@ yf::Zoom::SearchablePtr yf::Zoom::Impl::parse_torus_record(const xmlNode *ptr)
         {
             s->sortStrategy = mp::xml::get_text(ptr);
         }
+        else if (!strcmp((const char *) ptr->name, "rpn2cql"))
+            s->rpn2cql_fname = mp::xml::get_text(ptr);
     }
     return s;
 }
@@ -1094,6 +1100,8 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
         }
         else if (!strcmp(name, "realm"))
             realm = value;
+        else if (!strcmp(name, "torus_url"))
+            torus_url = value;
         else if (name[0] == 'x' && name[1] == '-')
         {
             out_names[no_out_args] = name;
@@ -1132,8 +1140,8 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
     }
 
     if (torus_db.compare("IR-Explain---1") == 0)
-        return explain_search(package, database, error, addinfo, odr, torus_db,
-            realm);
+        return explain_search(package, database, error, addinfo, odr, torus_url,
+                              torus_db, realm);
     
     SearchablePtr sptr;
 
@@ -1156,27 +1164,44 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
             return b;
         }
         const xmlNode *ptr = xmlDocGetRootElement(doc);
-        if (ptr)
-        {   // presumably ptr is a records element node
-            // parse first record in document
-            for (ptr = ptr->children; ptr; ptr = ptr->next)
+        if (ptr && ptr->type == XML_ELEMENT_NODE)
+        {
+            if (!strcmp((const char *) ptr->name, "record"))
+            {
+                sptr = m_p->parse_torus_record(ptr);
+            }
+            else if (!strcmp((const char *) ptr->name, "records"))
             {
-                if (ptr->type == XML_ELEMENT_NODE
-                    && !strcmp((const char *) ptr->name, "record"))
+                for (ptr = ptr->children; ptr; ptr = ptr->next)
                 {
-                    if (sptr)
+                    if (ptr->type == XML_ELEMENT_NODE
+                        && !strcmp((const char *) ptr->name, "record"))
                     {
-                        *error = YAZ_BIB1_UNSPECIFIED_ERROR;
-                        *addinfo = (char*) odr_malloc(odr, 40 + database.length()),
-                        sprintf(*addinfo, "multiple records for udb=%s",
-                                 database.c_str());
-                        xmlFreeDoc(doc);
-                        BackendPtr b;
-                        return b;
+                        if (sptr)
+                        {
+                            *error = YAZ_BIB1_UNSPECIFIED_ERROR;
+                            *addinfo = (char*)
+                                odr_malloc(odr, 40 + torus_db.length());
+                            sprintf(*addinfo, "multiple records for udb=%s",
+                                    database.c_str());
+                            xmlFreeDoc(doc);
+                            BackendPtr b;
+                            return b;
+                        }
+                        sptr = m_p->parse_torus_record(ptr);
                     }
-                    sptr = m_p->parse_torus_record(ptr);
                 }
             }
+            else
+            {
+                *error = YAZ_BIB1_UNSPECIFIED_ERROR;
+                *addinfo = (char*) odr_malloc(
+                    odr, 40 + strlen((const char *) ptr->name));
+                sprintf(*addinfo, "bad root element for torus: %s", ptr->name);
+                xmlFreeDoc(doc);
+                BackendPtr b;
+                return b;
+            }
         }
         xmlFreeDoc(doc);
     }
@@ -1257,10 +1282,32 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
         }
     }
 
+    cql_transform_t cqlt = 0;
+    if (sptr->rpn2cql_fname.length())
+    {
+        char fullpath[1024];
+        char *cp = yaz_filepath_resolve(sptr->rpn2cql_fname.c_str(),
+                                        m_p->file_path.c_str(), 0, fullpath);
+        if (cp)
+            cqlt = cql_transform_open_fname(fullpath);
+    }
+    else
+        cqlt = cql_transform_create();
+
+    if (!cqlt)
+    {
+        *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
+        *addinfo = odr_strdup(odr, "Missing/invalid cql2rpn file");
+        BackendPtr b;
+        xsltFreeStylesheet(xsp);
+        return b;
+    }
+
     m_backend.reset();
 
     BackendPtr b(new Backend);
 
+    b->cqlt = cqlt;
     b->sptr = sptr;
     b->xsp = xsp;
     b->m_frontend_database = database;
@@ -1803,6 +1850,7 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::explain_search(mp::Package &package,
                                                         int *error,
                                                         char **addinfo,
                                                         mp::odr &odr,
+                                                        std::string torus_url,
                                                         std::string &torus_db,
                                                         std::string &realm)
 {
@@ -1829,7 +1877,6 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::explain_search(mp::Package &package,
     else if (query->which == Z_Query_type_104 &&
         query->u.type_104->which == Z_External_CQL)
     {
-        std::string torus_url = m_p->torus_searchable_url;
         std::string torus_query(query->u.type_104->u.cql);
         xmlDoc *doc = mp::get_searchable(package, torus_url, "",
                                          torus_query,
@@ -2068,8 +2115,7 @@ next_proxy:
             cql_parser_destroy(cp);
             return;
         }
-        char ccl_buf[1024];
-        r = cql_to_ccl_buf(cn, ccl_buf, sizeof(ccl_buf));
+        r = cql_to_ccl(cn, wrbuf_vp_puts,  ccl_wrbuf);
         if (r)
         {
             error = YAZ_BIB1_MALFORMED_QUERY;
@@ -2097,8 +2143,6 @@ next_proxy:
         mp::wrbuf sort_spec_wrbuf;
         yaz_srw_sortkeys_to_sort_spec(wrbuf_cstr(sru_sortkeys_wrbuf),
                                       sort_spec_wrbuf);
-        wrbuf_puts(ccl_wrbuf, ccl_buf);
-        
         yaz_tok_cfg_t tc = yaz_tok_cfg_create();
         yaz_tok_parse_t tp =
             yaz_tok_parse_buf(tc, wrbuf_cstr(sort_spec_wrbuf));
@@ -2204,11 +2248,7 @@ next_proxy:
         }
         else
         {
-            cql_transform_t cqlt = cql_transform_create();
-            
-            status = cql_transform_rpn2cql_wrbuf(cqlt, wrb, zquery);
-            
-            cql_transform_close(cqlt);
+            status = cql_transform_rpn2cql_wrbuf(b->cqlt, wrb, zquery);
         }
         if (status == 0)
         {