std::string m_frontend_database;
SearchablePtr sptr;
xsltStylesheetPtr xsp;
+ std::string content_session_id;
public:
Backend(SearchablePtr sptr);
~Backend();
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);
};
std::string xsldir;
std::string file_path;
std::string content_proxy_server;
+ std::string content_tmp_file;
CCL_bibset bibset;
std::string element_transform;
std::string element_raw;
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);
void yf::Zoom::Impl::configure(const xmlNode *ptr, bool test_only,
const char *path)
{
+ content_tmp_file = "/tmp/mp_content_proxy.";
if (path && *path)
{
file_path = path;
{
if (!strcmp((const char *) attr->name, "server"))
content_proxy_server = mp::xml::get_text(attr->children);
+ else if (!strcmp((const char *) attr->name, "tmp_file"))
+ content_tmp_file = mp::xml::get_text(attr->children);
else
throw mp::filter::FilterException(
"Bad attribute " + std::string((const char *)
if (m_backend && m_backend->m_frontend_database == database)
return m_backend;
- const char *sru_proxy = 0;
std::string db_args;
std::string torus_db;
size_t db_arg_pos = database.find(',');
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());
+ b->set_option("rpnCharset", sptr->query_encoding);
- if (sptr->cfAuth.length())
+ b->set_option("timeout", "40");
+
+
+ std::string authentication = sptr->authentication;
+ std::string proxy = sptr->cfProxy;
+
+ const char *param_user = 0;
+ const char *param_password = 0;
+ const char *param_proxy = 0;
+ if (db_args.length())
{
- // A CF target
- b->set_option("user", sptr->cfAuth.c_str());
- if (db_args.length() == 0)
+ char **names;
+ char **values;
+ int i;
+ int no_parms = yaz_uri_to_array(db_args.c_str(),
+ odr, &names, &values);
+ for (i = 0; i < no_parms; i++)
{
- if (authentication.length())
+ const char *name = names[i];
+ const char *value = values[i];
+ if (!strcmp(name, "user"))
+ param_user = value;
+ else if (!strcmp(name, "password"))
+ param_password = value;
+ else if (!strcmp(name, "proxy"))
+ param_proxy = value;
+ else if (!strcmp(name, "cproxysession"))
+ ;
+ else
{
- // no database (auth) args specified already.. and the
- // Torus authentication has it.. Generate the args that CF
- // understands..
- size_t found = authentication.find('/');
- if (found != std::string::npos)
- {
- db_args += "user=" + mp::util::uri_encode(authentication.substr(0, found))
- + "&password=" + mp::util::uri_encode(authentication.substr(found+1));
- }
- else
- db_args += "user=" + mp::util::uri_encode(authentication);
+ BackendPtr notfound;
+ char *msg = (char*) odr_malloc(odr, strlen(name) + 30);
+ *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
+ sprintf(msg, "Bad database argument: %s", name);
+ *addinfo = msg;
+ return notfound;
}
- if (sptr->cfProxy.length())
+ }
+ if (param_user)
+ {
+ authentication = std::string(param_user);
+ if (param_password)
+ authentication += "/" + std::string(param_password);
+ }
+ if (param_proxy)
+ proxy = param_proxy;
+ }
+
+ if (sptr->cfAuth.length())
+ {
+ // A CF target
+ b->set_option("user", sptr->cfAuth);
+ if (!param_user && !param_password && authentication.length())
+ {
+ if (db_args.length())
+ db_args += "&";
+ // no database (auth) args specified already.. and the
+ // Torus authentication has it.. Generate the args that CF
+ // understands..
+ size_t found = authentication.find('/');
+ if (found != std::string::npos)
{
- if (db_args.length())
- db_args += "&";
- db_args += "proxy=" + mp::util::uri_encode(sptr->cfProxy);
+ db_args += "user=" +
+ mp::util::uri_encode(authentication.substr(0, found))
+ + "&password=" +
+ mp::util::uri_encode(authentication.substr(found+1));
}
+ else
+ db_args += "user=" + mp::util::uri_encode(authentication);
+ }
+ if (!param_proxy && proxy.length())
+ {
+ if (db_args.length())
+ db_args += "&";
+ db_args += "proxy=" + mp::util::uri_encode(proxy);
}
if (sptr->cfSubDb.length())
{
}
else
{
- // A non-CF target
- if (db_args.length())
+ db_args.clear(); // no arguments to be passed (non-CF)
+
+ size_t found = authentication.find('/');
+
+ if (sptr->sru.length() && found != std::string::npos)
{
- // user has specified backend authentication
- const char *param_user = 0;
- const char *param_password = 0;
- char **names;
- char **values;
- int i;
- int no_parms = yaz_uri_to_array(db_args.c_str(),
- odr, &names, &values);
- for (i = 0; i < no_parms; i++)
- {
- const char *name = names[i];
- const char *value = values[i];
- if (!strcmp(name, "user"))
- param_user = value;
- else if (!strcmp(name, "password"))
- param_password = value;
- else if (!strcmp(name, "proxy"))
- sru_proxy = value;
- else
- {
- BackendPtr notfound;
- char *msg = (char*) odr_malloc(odr, strlen(name) + 30);
- *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
- sprintf(msg, "Bad database argument: %s", name);
- *addinfo = msg;
- return notfound;
- }
- }
- if (param_user && param_password)
- {
- char *auth = (char*) odr_malloc(
- odr, strlen(param_user) + strlen(param_password) + 2);
- strcpy(auth, param_user);
- strcat(auth, "/");
- strcat(auth, param_password);
- b->set_option("user", auth);
- }
- db_args.clear(); // no arguments to be passed (non-CF)
+ 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);
+ }
+ 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);
+
+ if (fd == -1)
{
- // use authentication from Torus, if given
- if (authentication.length())
- b->set_option("user", authentication.c_str());
+ yaz_log(YLOG_WARN|YLOG_ERRNO, "create %s", fname);
+ *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
+ *addinfo = (char *) odr_malloc(odr, 40 + strlen(fname));
+ sprintf(*addinfo, "Could not create %s", fname);
+ xfree(fname);
+ BackendPtr backend_null;
+ return backend_null;
}
+ b->content_session_id.assign(fname + (strlen(fname) - 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())
+ wrbuf_printf(w, "proxy: %s\n", proxy.c_str());
+ if (sptr->cfAuth.length())
+ wrbuf_printf(w, "cfauth: %s\n", sptr->cfAuth.c_str());
+ if (sptr->cfProxy.length())
+ wrbuf_printf(w, "cfproxy: %s\n", sptr->cfProxy.c_str());
+
+ write(fd, wrbuf_buf(w), wrbuf_len(w));
+ close(fd);
+ yaz_log(YLOG_LOG, "file %s created\n", fname);
+ xfree(fname);
}
-
- if (sru_proxy)
- b->set_option("proxy", sru_proxy);
+
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
{
xmlDoc *doc = xmlParseMemory(rec_buf, rec_len);
std::string res =
mp::xml::url_recipe_handle(doc, b->sptr->urlRecipe);
- if (res.length() && b->sptr->contentConnector.length())
+ if (res.length() && b->content_session_id.length())
{
- yaz_log(YLOG_LOG, "contentConnector: %s",
- b->sptr->contentConnector.c_str());
size_t off = res.find_first_of("://");
if (off != std::string::npos)
{
char tmp[1024];
- long id = 12345;
- sprintf(tmp, "%ld.%s/",
- id, m_p->content_proxy_server.c_str());
+ sprintf(tmp, "%s.%s/",
+ b->content_session_id.c_str(),
+ m_p->content_proxy_server.c_str());
res.insert(off + 3, tmp);
}
}
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);
+}
+
+
void yf::Zoom::Frontend::handle_search(mp::Package &package)
{
Z_GDU *gdu = package.request().get();
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)
{
{
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)
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)
{
}
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)