X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Ffilter_zoom.cpp;h=1c2ff9a42cc945f5467c68b174fa10698d00ab4a;hb=bd2f40fe6690ff236d0a5e144ff8982a63052ac2;hp=b3ddf35ccf6abd446842e7272b292d265b89e21c;hpb=8555167adc8ae9af57bd96826c247c9d28e7edd9;p=metaproxy-moved-to-github.git diff --git a/src/filter_zoom.cpp b/src/filter_zoom.cpp index b3ddf35..1c2ff9a 100644 --- a/src/filter_zoom.cpp +++ b/src/filter_zoom.cpp @@ -17,6 +17,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.hpp" + +#include +#include +#include #include "filter_zoom.hpp" #include #include @@ -92,6 +96,7 @@ namespace metaproxy_1 { void present(Odr_int start, Odr_int number, ZOOM_record *recs, int *error, char **addinfo, ODR odr); void set_option(const char *name, const char *value); + void set_option(const char *name, std::string value); const char *get_option(const char *name); void get_zoom_error(int *error, char **addinfo, ODR odr); }; @@ -144,6 +149,7 @@ namespace metaproxy_1 { std::string file_path; std::string content_proxy_server; std::string content_tmp_file; + bool apdu_log; CCL_bibset bibset; std::string element_transform; std::string element_raw; @@ -197,7 +203,8 @@ void yf::Zoom::Backend::get_zoom_error(int *error, char **addinfo, { const char *msg = 0; const char *zoom_addinfo = 0; - *error = ZOOM_connection_error(m_connection, &msg, &zoom_addinfo); + const char *dset = 0; + *error = ZOOM_connection_error_x(m_connection, &msg, &zoom_addinfo, &dset); if (*error) { if (*error >= ZOOM_ERROR_CONNECT) @@ -217,6 +224,8 @@ void yf::Zoom::Backend::get_zoom_error(int *error, char **addinfo, } else { + if (dset && !strcmp(dset, "info:srw/diagnostic/1")) + *error = yaz_diag_srw_to_bib1(*error); *addinfo = (char *) odr_malloc( odr, 20 + (zoom_addinfo ? strlen(zoom_addinfo) : 0)); **addinfo = '\0'; @@ -280,6 +289,11 @@ void yf::Zoom::Backend::set_option(const char *name, const char *value) ZOOM_resultset_option_set(m_resultset, name, value); } +void yf::Zoom::Backend::set_option(const char *name, std::string value) +{ + set_option(name, value.c_str()); +} + const char *yf::Zoom::Backend::get_option(const char *name) { return ZOOM_connection_option_get(m_connection, name); @@ -351,9 +365,12 @@ void yf::Zoom::Impl::release_frontend(mp::Package &package) } } -yf::Zoom::Impl::Impl() : element_transform("pz2") , element_raw("raw") +yf::Zoom::Impl::Impl() : + apdu_log(false), element_transform("pz2") , element_raw("raw") { bibset = ccl_qual_mk(); + + srand(time(0)); } yf::Zoom::Impl::~Impl() @@ -510,7 +527,7 @@ void yf::Zoom::Impl::configure_local_records(const xmlNode *ptr, bool test_only) void yf::Zoom::Impl::configure(const xmlNode *ptr, bool test_only, const char *path) { - content_tmp_file = "/tmp/mp_content_proxy."; + content_tmp_file = "/tmp/cf.XXXXXX.p"; if (path && *path) { file_path = path; @@ -578,6 +595,19 @@ void yf::Zoom::Impl::configure(const xmlNode *ptr, bool test_only, attr->name)); } } + else if (!strcmp((const char *) ptr->name, "log")) + { + const struct _xmlAttr *attr; + for (attr = ptr->properties; attr; attr = attr->next) + { + if (!strcmp((const char *) attr->name, "apdu")) + apdu_log = mp::xml::get_bool(attr->children, false); + else + throw mp::filter::FilterException( + "Bad attribute " + std::string((const char *) + attr->name)); + } + } else { throw mp::filter::FilterException @@ -701,10 +731,12 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( b->m_frontend_database = database; if (sptr->query_encoding.length()) - b->set_option("rpnCharset", sptr->query_encoding.c_str()); + b->set_option("rpnCharset", sptr->query_encoding); b->set_option("timeout", "40"); - + + if (m_p->apdu_log) + b->set_option("apdulog", "1"); std::string authentication = sptr->authentication; std::string proxy = sptr->cfProxy; @@ -729,6 +761,8 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( param_password = value; else if (!strcmp(name, "proxy")) param_proxy = value; + else if (!strcmp(name, "cproxysession")) + ; else { BackendPtr notfound; @@ -739,10 +773,11 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( return notfound; } } - if (param_user && param_password) + if (param_user) { - authentication = std::string(param_user) - + "/" + std::string(param_password); + authentication = std::string(param_user); + if (param_password) + authentication += "/" + std::string(param_password); } if (param_proxy) proxy = param_proxy; @@ -751,7 +786,7 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( if (sptr->cfAuth.length()) { // A CF target - b->set_option("user", sptr->cfAuth.c_str()); + b->set_option("user", sptr->cfAuth); if (!param_user && !param_password && authentication.length()) { if (db_args.length()) @@ -787,20 +822,38 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( { db_args.clear(); // no arguments to be passed (non-CF) - if (authentication.length()) - b->set_option("user", authentication.c_str()); + size_t found = authentication.find('/'); + + if (sptr->sru.length() && found != std::string::npos) + { + b->set_option("user", authentication.substr(0, found)); + b->set_option("password", authentication.substr(found+1)); + } + else + b->set_option("user", authentication); + if (proxy.length()) - b->set_option("proxy", proxy.c_str()); + b->set_option("proxy", proxy); } if (b->sptr->contentConnector.length()) { - int fd; - char *fname = (char *) xmalloc(m_p->content_tmp_file.length() + 8); strcpy(fname, m_p->content_tmp_file.c_str()); - strcat(fname, "XXXXXX"); - fd = mkstemp(fname); - + int suffixlen; + char *xx = strstr(fname, "XXXXXX"); + if (xx) + suffixlen = strlen(xx) - 6; + else + { + suffixlen = 0; + xx = fname + strlen(fname); + strcat(fname, "XXXXXX"); + } + char tmp_char = xx[6]; + sprintf(xx, "%06d", ((unsigned) rand()) % 1000000); + xx[6] = tmp_char; + + int fd = creat(fname, 0666); if (fd == -1) { yaz_log(YLOG_WARN|YLOG_ERRNO, "create %s", fname); @@ -811,9 +864,10 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( BackendPtr backend_null; return backend_null; } - b->content_session_id.assign(fname + (strlen(fname) - 6)); + b->content_session_id.assign(xx, 6); WRBUF w = wrbuf_alloc(); wrbuf_puts(w, "#content_proxy\n"); + wrbuf_printf(w, "connector: %s\n", b->sptr->contentConnector.c_str()); if (authentication.length()) wrbuf_printf(w, "authentication: %s\n", authentication.c_str()); if (proxy.length()) @@ -828,13 +882,12 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases( yaz_log(YLOG_LOG, "file %s created\n", fname); xfree(fname); } - std::string url; if (sptr->sru.length()) { url = "http://" + sptr->target; - b->set_option("sru", sptr->sru.c_str()); + b->set_option("sru", sptr->sru); } else { @@ -973,20 +1026,52 @@ Z_Records *yf::Zoom::Frontend::get_records(Odr_int start, xmlChar *xmlrec_buf = 0; const char *rec_buf = ZOOM_record_get(recs[i], rec_type_str, &rec_len); + if (!rec_buf && !npr) + { + std::string addinfo("ZOOM_record_get failed for type "); + + addinfo += rec_type_str; + npr = zget_surrogateDiagRec( + odr, odr_database, + YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS, + addinfo.c_str()); + } + if (rec_buf && b->xsp && enable_pz2_transform) { xmlDoc *rec_doc = xmlParseMemory(rec_buf, rec_len); - if (rec_doc) + if (!rec_doc) + { + npr = zget_surrogateDiagRec( + odr, odr_database, + YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS, + "xml parse failed for record"); + } + else { - xmlDoc *rec_res; - rec_res = xsltApplyStylesheet(b->xsp, rec_doc, 0); + xmlDoc *rec_res = + xsltApplyStylesheet(b->xsp, rec_doc, 0); if (rec_res) + { xsltSaveResultToString(&xmlrec_buf, &rec_len, rec_res, b->xsp); - rec_buf = (const char *) xmlrec_buf; + rec_buf = (const char *) xmlrec_buf; + + xmlFreeDoc(rec_res); + } + if (!rec_buf) + { + std::string addinfo; + + addinfo = "xslt apply failed for " + + b->sptr->transform_xsl_fname; + npr = zget_surrogateDiagRec( + odr, odr_database, + YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS, + addinfo.c_str()); + } xmlFreeDoc(rec_doc); - xmlFreeDoc(rec_res); } } @@ -1025,20 +1110,22 @@ Z_Records *yf::Zoom::Frontend::get_records(Odr_int start, } xmlFreeDoc(doc); } - if (rec_buf) + if (!npr) { - npr = (Z_NamePlusRecord *) odr_malloc(odr, sizeof(*npr)); - npr->databaseName = odr_database; - npr->which = Z_NamePlusRecord_databaseRecord; - npr->u.databaseRecord = - z_ext_record_xml(odr, rec_buf, rec_len); - } - else - { - npr = zget_surrogateDiagRec( - odr, odr_database, - YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS, - rec_type_str); + if (!rec_buf) + npr = zget_surrogateDiagRec( + odr, odr_database, + YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS, + rec_type_str); + else + { + npr = (Z_NamePlusRecord *) + odr_malloc(odr, sizeof(*npr)); + npr->databaseName = odr_database; + npr->which = Z_NamePlusRecord_databaseRecord; + npr->u.databaseRecord = + z_ext_record_xml(odr, rec_buf, rec_len); + } } if (xmlrec_buf) xmlFree(xmlrec_buf); @@ -1104,6 +1191,110 @@ struct cql_node *yf::Zoom::Impl::convert_cql_fields(struct cql_node *cn, return r; } +static void sort_pqf_type_7(WRBUF pqf_wrbuf, const char *sru_sortkeys) +{ + /* sortkey layour: path,schema,ascending,caseSensitive,missingValue */ + /* see cql_sortby_to_sortkeys of YAZ. */ + char **sortspec; + int num_sortspec = 0; + int i; + NMEM nmem = nmem_create(); + + if (sru_sortkeys) + nmem_strsplit_blank(nmem, sru_sortkeys, &sortspec, &num_sortspec); + if (num_sortspec > 0) + { + WRBUF w = wrbuf_alloc(); + for (i = 0; i < num_sortspec; i++) + { + char **arg; + int num_arg; + int ascending = 1; + nmem_strsplitx(nmem, ",", sortspec[i], &arg, &num_arg, 0); + + if (num_arg > 2 && arg[2][0]) + ascending = atoi(arg[2]); + + wrbuf_puts(w, "@or @attr 1="); + yaz_encode_pqf_term(w, arg[0], strlen(arg[0])); + wrbuf_printf(w, "@attr 7=%d %d ", ascending ? 1 : 2, i); + } + if (wrbuf_len(w)) + { + wrbuf_puts(w, wrbuf_cstr(pqf_wrbuf)); + wrbuf_rewind(pqf_wrbuf); + wrbuf_puts(pqf_wrbuf, wrbuf_cstr(w)); + } + wrbuf_destroy(w); + } + nmem_destroy(nmem); +} + +static void sort_via_cql(WRBUF cql_sortby, const char *sru_sortkeys) +{ + /* sortkey layour: path,schema,ascending,caseSensitive,missingValue */ + /* see cql_sortby_to_sortkeys of YAZ. */ + char **sortspec; + int num_sortspec = 0; + int i; + NMEM nmem = nmem_create(); + + if (sru_sortkeys) + nmem_strsplit_blank(nmem, sru_sortkeys, &sortspec, &num_sortspec); + if (num_sortspec > 0) + { + WRBUF w = wrbuf_alloc(); + for (i = 0; i < num_sortspec; i++) + { + char **arg; + int num_arg; + int ascending = 1; + int case_sensitive = 0; + const char *missing = 0; + nmem_strsplitx(nmem, ",", sortspec[i], &arg, &num_arg, 0); + + if (num_arg > 2 && arg[2][0]) + ascending = atoi(arg[2]); + if (num_arg > 3 && arg[3][0]) + case_sensitive = atoi(arg[3]); + if (num_arg > 4 && arg[4][0]) + missing = arg[4]; + if (i > 0) + wrbuf_puts(w, " "); + else + wrbuf_puts(w, " sortby "); + wrbuf_puts(w, arg[0]); /* field */ + wrbuf_puts(w, "/"); + wrbuf_puts(w, ascending ? "ascending" : "descending"); + if (case_sensitive) + wrbuf_puts(w, "/respectCase"); + if (missing) + { + if (!strcmp(missing, "omit")) + wrbuf_puts(w, "/missingOmit"); + else if (!strcmp(missing, "abort")) + wrbuf_puts(w, "/missingFail"); + else if (!strcmp(missing, "lowValue")) + wrbuf_puts(w, "/missingLow"); + else if (!strcmp(missing, "highValue")) + wrbuf_puts(w, "/missingHigh"); + } + } + if (wrbuf_len(w)) + wrbuf_puts(cql_sortby, wrbuf_cstr(w)); + wrbuf_destroy(w); + } + nmem_destroy(nmem); +} + +#if YAZ_VERSIONL < 0x40206 +static void wrbuf_vp_puts(const char *buf, void *client_data) +{ + WRBUF b = (WRBUF) client_data; + wrbuf_puts(b, buf); +} +#endif + void yf::Zoom::Frontend::handle_search(mp::Package &package) { Z_GDU *gdu = package.request().get(); @@ -1137,6 +1328,7 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package) Z_Query *query = sr->query; WRBUF ccl_wrbuf = 0; WRBUF pqf_wrbuf = 0; + std::string sru_sortkeys; if (query->which == Z_Query_type_1 || query->which == Z_Query_type_101) { @@ -1191,6 +1383,13 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package) { ccl_wrbuf = wrbuf_alloc(); wrbuf_puts(ccl_wrbuf, ccl_buf); + + WRBUF sru_sortkeys_wrbuf = wrbuf_alloc(); + + cql_sortby_to_sortkeys(cn, wrbuf_vp_puts, sru_sortkeys_wrbuf); + + sru_sortkeys.assign(wrbuf_cstr(sru_sortkeys_wrbuf)); + wrbuf_destroy(sru_sortkeys_wrbuf); } cql_parser_destroy(cp); if (r) @@ -1270,6 +1469,9 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package) status = cql_transform_rpn2cql_wrbuf(cqlt, wrb, zquery); cql_transform_close(cqlt); + + if (status == 0) + sort_via_cql(wrb, sru_sortkeys.c_str()); } if (status == 0) { @@ -1290,12 +1492,13 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package) } else { + sort_pqf_type_7(pqf_wrbuf, sru_sortkeys.c_str()); + yaz_log(YLOG_LOG, "search PQF: %s", wrbuf_cstr(pqf_wrbuf)); b->search_pqf(wrbuf_cstr(pqf_wrbuf), &hits, &error, &addinfo, odr); wrbuf_destroy(pqf_wrbuf); } - - + const char *element_set_name = 0; Odr_int number_to_present = 0; if (!error)