#include <yaz/oid_db.h>
#include <yaz/diagbib1.h>
#include <yaz/snprintf.h>
+#include <yaz/rpn2cql.h>
#define USE_TIMING 0
#if USE_TIMING
struct connection *connection;
struct session *session;
char *pquery; // Current search
+ char *cqlquery; // used for SRU targets only
int hits;
- int records;
+ int record_offset;
int setno;
int requestid; // ID of current outstanding request
int diagnostic;
"Client_Connecting",
"Client_Connected",
"Client_Idle",
- "Client_Initializing",
- "Client_Searching",
- "Client_Presenting",
+ "Client_Working",
"Client_Error",
"Client_Failed",
"Client_Disconnected",
// Close connection and set state to error
void client_fatal(struct client *cl)
{
- //client_show_raw_error(cl, "client connection failure");
yaz_log(YLOG_WARN, "Fatal error from %s", client_get_url(cl));
connection_destroy(cl->connection);
client_set_state(cl, Client_Error);
}
else
return -1;
- yaz_log(YLOG_LOG, "Returned type %s", type);
return 0;
}
return -1;
if (ZOOM_connection_error(link, &error, &addinfo))
{
cl->hits = 0;
- cl->state = Client_Error;
+ client_set_state(cl, Client_Error);
yaz_log(YLOG_WARN, "Search error %s (%s): %s",
error, addinfo, client_get_url(cl));
}
ZOOM_resultset resultset = connection_get_resultset(co);
const char *error, *addinfo;
- yaz_log(YLOG_LOG, "client_record_response");
if (ZOOM_connection_error(link, &error, &addinfo))
{
- cl->state = Client_Error;
+ client_set_state(cl, Client_Error);
yaz_log(YLOG_WARN, "Search error %s (%s): %s",
error, addinfo, client_get_url(cl));
}
ZOOM_record rec = 0;
const char *msg, *addinfo;
- yaz_log(YLOG_LOG, "show_raw=%p show_raw->active=%d",
- cl->show_raw, cl->show_raw ? cl->show_raw->active : 0);
if (cl->show_raw && cl->show_raw->active)
{
if ((rec = ZOOM_resultset_record(resultset,
cl->show_raw->active = 0;
ingest_raw_record(cl, rec);
}
+ else
+ {
+ yaz_log(YLOG_WARN, "Expected record, but got NULL, offset=%d",
+ cl->show_raw->position-1);
+ }
}
else
{
- int offset = cl->records;
+ int offset = cl->record_offset;
if ((rec = ZOOM_resultset_record(resultset, offset)))
{
- yaz_log(YLOG_LOG, "Record with offset %d", offset);
-
- cl->records++;
+ cl->record_offset++;
if (ZOOM_record_error(rec, &msg, &addinfo, 0))
yaz_log(YLOG_WARN, "Record error %s (%s): %s (rec #%d)",
- error, addinfo, client_get_url(cl), cl->records);
+ error, addinfo, client_get_url(cl),
+ cl->record_offset);
else
{
struct session_database *sdb = client_get_database(cl);
nativesyntax_to_type(sdb, type);
if ((xmlrec = ZOOM_record_get(rec, type, NULL)))
{
- if (ingest_record(cl, xmlrec, cl->records))
+ if (ingest_record(cl, xmlrec, cl->record_offset))
{
session_alert_watch(cl->session, SESSION_WATCH_SHOW);
session_alert_watch(cl->session, SESSION_WATCH_RECORD);
}
}
+ else
+ {
+ yaz_log(YLOG_WARN, "Expected record, but got NULL, offset=%d",
+ offset);
+ }
}
- if (!rec)
- yaz_log(YLOG_WARN, "Expected record, but got NULL");
}
}
const char *opt_elements = session_setting_oneval(sdb, PZ_ELEMENTS);
const char *opt_requestsyn = session_setting_oneval(sdb, PZ_REQUESTSYNTAX);
const char *opt_maxrecs = session_setting_oneval(sdb, PZ_MAXRECS);
+ const char *opt_sru = session_setting_oneval(sdb, PZ_SRU);
assert(link);
cl->hits = -1;
- cl->records = 0;
+ cl->record_offset = 0;
cl->diagnostic = 0;
+ client_set_state(cl, Client_Working);
if (*opt_piggyback)
ZOOM_connection_option_set(link, "piggyback", opt_piggyback);
ZOOM_connection_option_set(link, "piggyback", "1");
if (*opt_queryenc)
ZOOM_connection_option_set(link, "rpnCharset", opt_queryenc);
- if (*opt_elements)
+ if (*opt_sru && *opt_elements)
+ ZOOM_connection_option_set(link, "schema", opt_elements);
+ else if (*opt_elements)
ZOOM_connection_option_set(link, "elementSetName", opt_elements);
if (*opt_requestsyn)
ZOOM_connection_option_set(link, "preferredRecordSyntax", opt_requestsyn);
sprintf(n, "%d", global_parameters.toget);
ZOOM_connection_option_set(link, "count", n);
}
- if (!databaseName || !*databaseName)
- databaseName = "Default";
- ZOOM_connection_option_set(link, "databaseName", databaseName);
+ if (databaseName)
+ ZOOM_connection_option_set(link, "databaseName", databaseName);
ZOOM_connection_option_set(link, "presentChunk", "20");
- rs = ZOOM_connection_search_pqf(link, cl->pquery);
+ if (cl->cqlquery)
+ {
+ ZOOM_query q = ZOOM_query_create();
+ ZOOM_query_cql(q, cl->cqlquery);
+ rs = ZOOM_connection_search(link, q);
+ ZOOM_query_destroy(q);
+ }
+ else
+ rs = ZOOM_connection_search_pqf(link, cl->pquery);
connection_set_resultset(co, rs);
connection_continue(co);
}
else
r = xmalloc(sizeof(struct client));
r->pquery = 0;
+ r->cqlquery = 0;
r->database = 0;
r->connection = 0;
r->session = 0;
r->hits = 0;
- r->records = 0;
+ r->record_offset = 0;
r->setno = 0;
r->requestid = -1;
r->diagnostic = 0;
cc->next = c->next;
}
xfree(c->pquery);
+ xfree(c->cqlquery);
if (c->connection)
connection_release(c->connection);
return res;
}
+// returns a xmalloced CQL query corresponding to the pquery in client
+static char *make_cqlquery(struct client *cl)
+{
+ cql_transform_t cqlt = cql_transform_create();
+ Z_RPNQuery *zquery;
+ char *r;
+ WRBUF wrb = wrbuf_alloc();
+ int status;
+
+ zquery = p_query_rpn(global_parameters.odr_out, cl->pquery);
+ if ((status = cql_transform_rpn2cql_wrbuf(cqlt, wrb, zquery)))
+ {
+ yaz_log(YLOG_WARN, "failed to generate CQL query, code=%d", status);
+ return 0;
+ }
+ r = xstrdup(wrbuf_cstr(wrb));
+
+ wrbuf_destroy(wrb);
+ odr_reset(global_parameters.odr_out); // releases the zquery
+ cql_transform_close(cqlt);
+ return r;
+}
+
// Parse the query given the settings specific to this client
int client_parse_query(struct client *cl, const char *query)
{
struct session *se = client_get_session(cl);
+ struct session_database *sdb = client_get_database(cl);
struct ccl_rpn_node *cn;
int cerror, cpos;
CCL_bibset ccl_map = prepare_cclmap(cl);
+ const char *sru = session_setting_oneval(sdb, PZ_SRU);
if (!ccl_map)
return -1;
ccl_qual_rm(&ccl_map);
if (!cn)
{
- cl->state = Client_Error;
+ client_set_state(cl, Client_Error);
yaz_log(YLOG_WARN, "Failed to parse query for %s",
client_get_database(cl)->database->url);
return -1;
xfree(cl->pquery);
cl->pquery = xstrdup(wrbuf_cstr(se->wrbuf));
+ xfree(cl->cqlquery);
+ if (*sru)
+ {
+ if (!(cl->cqlquery = make_cqlquery(cl)))
+ return -1;
+ }
+ else
+ cl->cqlquery = 0;
+
if (!se->relevance)
{
// Initialize relevance structure with query terms
int client_get_num_records(struct client *cl)
{
- return cl->records;
+ return cl->record_offset;
}
int client_get_diagnostic(struct client *cl)