X-Git-Url: http://sru.miketaylor.org.uk/?a=blobdiff_plain;f=src%2Ffilter_zoom.cpp;h=de0727230d7adcf01dba2b1d1b37fed439e3bfa2;hb=85c1dafe0ef729111322b69aa7160c59838d16b4;hp=b3040740b91430548a0799f90821288b1464322d;hpb=0d850a64032dd0be5c7fc2dc9f1068e91217898f;p=metaproxy-moved-to-github.git diff --git a/src/filter_zoom.cpp b/src/filter_zoom.cpp index b304074..de07272 100644 --- a/src/filter_zoom.cpp +++ b/src/filter_zoom.cpp @@ -28,6 +28,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include +#include +#include #include #include #include @@ -39,7 +41,7 @@ namespace yf = mp::filter; namespace metaproxy_1 { namespace filter { - struct Zoom::Searchable { + struct Zoom::Searchable : boost::noncopyable { std::string database; std::string target; std::string query_encoding; @@ -50,10 +52,11 @@ namespace metaproxy_1 { std::string transform_xsl_fname; bool use_turbomarc; bool piggyback; + CCL_bibset ccl_bibset; Searchable(); ~Searchable(); }; - class Zoom::Backend { + class Zoom::Backend : boost::noncopyable { friend class Impl; friend class Frontend; std::string zurl; @@ -73,7 +76,7 @@ namespace metaproxy_1 { void set_option(const char *name, const char *value); int get_error(const char **addinfo); }; - class Zoom::Frontend { + class Zoom::Frontend : boost::noncopyable { friend class Impl; Impl *m_p; bool m_is_virtual; @@ -147,6 +150,7 @@ yf::Zoom::Backend::Backend(SearchablePtr ptr) : sptr(ptr) { m_connection = ZOOM_connection_create(0); m_resultset = 0; + xsp = 0; } yf::Zoom::Backend::~Backend() @@ -199,10 +203,12 @@ yf::Zoom::Searchable::Searchable() { piggyback = true; use_turbomarc = false; + ccl_bibset = ccl_qual_mk(); } yf::Zoom::Searchable::~Searchable() { + ccl_qual_rm(&ccl_bibset); } yf::Zoom::Frontend::Frontend(Impl *impl) : @@ -336,11 +342,14 @@ void yf::Zoom::Impl::parse_torus(const xmlNode *ptr1) else if (!strcmp((const char *) ptr3->name, "useTurboMarc")) { - yaz_log(YLOG_LOG, "seeing useTurboMarc"); s->use_turbomarc = mp::xml::get_bool(ptr3, false); - yaz_log(YLOG_LOG, "value=%s", - s->use_turbomarc ? "1" : "0"); - + } + else if (!strncmp((const char *) ptr3->name, + "cclmap_", 7)) + { + std::string value = mp::xml::get_text(ptr3); + ccl_qual_fitem(s->ccl_bibset, value.c_str(), + (const char *) ptr3->name + 7); } } if (s->database.length() && s->target.length()) @@ -356,7 +365,6 @@ void yf::Zoom::Impl::parse_torus(const xmlNode *ptr1) } } - void yf::Zoom::Impl::configure(const xmlNode *ptr, bool test_only) { for (ptr = ptr->children; ptr; ptr = ptr->next) @@ -519,9 +527,6 @@ Z_Records *yf::Zoom::Frontend::get_records(Odr_int start, } } - yaz_log(YLOG_LOG, "enable_pz2_transform %s", enable_pz2_transform ? - "enabled" : "disabled"); - b->set_option("preferredRecordSyntax", syntax_name); if (enable_pz2_transform) @@ -674,13 +679,59 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package) Odr_int hits = 0; Z_Query *query = sr->query; + WRBUF ccl_wrbuf = 0; + WRBUF pqf_wrbuf = 0; + if (query->which == Z_Query_type_1 || query->which == Z_Query_type_101) { - WRBUF w = wrbuf_alloc(); - yaz_rpnquery_to_wrbuf(w, query->u.type_1); + // RPN + pqf_wrbuf = wrbuf_alloc(); + yaz_rpnquery_to_wrbuf(pqf_wrbuf, query->u.type_1); + } + else if (query->which == Z_Query_type_2) + { + // CCL + ccl_wrbuf = wrbuf_alloc(); + wrbuf_write(ccl_wrbuf, (const char *) query->u.type_2->buf, + query->u.type_2->len); + } + else if (query->which == Z_Query_type_104 && + query->u.type_104->which == Z_External_CQL) + { + // CQL + const char *cql = query->u.type_104->u.cql; + CQL_parser cp = cql_parser_create(); + int r = cql_parser_string(cp, cql); + if (r) + { + cql_parser_destroy(cp); + apdu_res = + odr.create_searchResponse(apdu_req, + YAZ_BIB1_MALFORMED_QUERY, + "CQL syntax error"); + package.response() = apdu_res; + return; + } + struct cql_node *cn = cql_parser_result(cp); + char ccl_buf[1024]; - b->search_pqf(wrbuf_cstr(w), &hits, &error, &addinfo); - wrbuf_destroy(w); + r = cql_to_ccl_buf(cn, ccl_buf, sizeof(ccl_buf)); + yaz_log(YLOG_LOG, "cql_to_ccl_buf returned %d", r); + if (r == 0) + { + ccl_wrbuf = wrbuf_alloc(); + wrbuf_puts(ccl_wrbuf, ccl_buf); + } + cql_parser_destroy(cp); + if (r) + { + apdu_res = + odr.create_searchResponse(apdu_req, + YAZ_BIB1_MALFORMED_QUERY, + "CQL to CCL conversion error"); + package.response() = apdu_res; + return; + } } else { @@ -689,6 +740,36 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package) package.response() = apdu_res; return; } + + if (ccl_wrbuf) + { + // CCL to PQF + assert(pqf_wrbuf == 0); + int cerror, cpos; + struct ccl_rpn_node *cn; + cn = ccl_find_str(b->sptr->ccl_bibset, wrbuf_cstr(ccl_wrbuf), + &cerror, &cpos); + wrbuf_destroy(ccl_wrbuf); + if (!cn) + { + char *addinfo = odr_strdup(odr, ccl_err_msg(cerror)); + + apdu_res = + odr.create_searchResponse(apdu_req, + YAZ_BIB1_MALFORMED_QUERY, + addinfo); + package.response() = apdu_res; + return; + } + pqf_wrbuf = wrbuf_alloc(); + ccl_pquery(pqf_wrbuf, cn); + ccl_rpn_delete(cn); + } + + assert(pqf_wrbuf); + b->search_pqf(wrbuf_cstr(pqf_wrbuf), &hits, &error, &addinfo); + + wrbuf_destroy(pqf_wrbuf); const char *element_set_name = 0; Odr_int number_to_present = 0;