* Copyright (C) 1995-2007, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: zoom-c.c,v 1.106 2007-01-10 13:25:46 adam Exp $
+ * $Id: zoom-c.c,v 1.116.2.1 2007-06-26 09:23:30 adam Exp $
*/
/**
* \file zoom-c.c
#include <yaz/cql.h>
#include <yaz/ccl.h>
+#define TASK_FIX 1
+
static int log_api = 0;
static int log_details = 0;
zoom_complete
} zoom_ret;
+static void resultset_destroy(ZOOM_resultset r);
static zoom_ret ZOOM_connection_send_init(ZOOM_connection c);
static zoom_ret do_write_ex(ZOOM_connection c, char *buf_out, int len_out);
static char *cql2pqf(ZOOM_connection c, const char *cql);
+
+/*
+ * This wrapper is just for logging failed lookups. It would be nicer
+ * if it could cause failure when a lookup fails, but that's hard.
+ */
+static Odr_oid *zoom_yaz_str_to_z3950oid(ZOOM_connection c,
+ int oid_class, const char *str) {
+ Odr_oid *res = yaz_str_to_z3950oid(c->odr_out, oid_class, str);
+ if (res == 0)
+ yaz_log(YLOG_WARN, "%p OID lookup (%d, '%s') failed",
+ c, (int) oid_class, str);
+ return res;
+}
+
+
static void initlog(void)
{
static int log_level_initialized = 0;
return event;
}
-int ZOOM_connection_peek_event(ZOOM_connection c)
+static void ZOOM_connection_remove_events(ZOOM_connection c)
+{
+ ZOOM_Event event;
+ while ((event = ZOOM_connection_get_event(c)))
+ ZOOM_Event_destroy(event);
+}
+
+ZOOM_API(int) ZOOM_connection_peek_event(ZOOM_connection c)
{
ZOOM_Event event = c->m_queue_front;
return event ? event->kind : ZOOM_EVENT_NONE;
}
+void ZOOM_connection_remove_tasks(ZOOM_connection c);
+
static void set_dset_error(ZOOM_connection c, int error,
const char *dset,
const char *addinfo, const char *addinfo2)
}
else if (addinfo)
c->addinfo = xstrdup(addinfo);
- if (error)
+ if (error != ZOOM_ERROR_NONE)
+ {
yaz_log(log_api, "%p set_dset_error %s %s:%d %s %s",
c, c->host_port ? c->host_port : "<>", dset, error,
addinfo ? addinfo : "",
addinfo2 ? addinfo2 : "");
+#if TASK_FIX
+ ZOOM_connection_remove_tasks(c);
+#endif
+ }
}
#if YAZ_HAVE_XML2
}
#endif
+
static void set_ZOOM_error(ZOOM_connection c, int error,
const char *addinfo)
{
* or Init Refused are not cleared, because they are not
* recoverable: doing another search doesn't help.
*/
+
+ ZOOM_connection_remove_events(c);
switch (c->error)
{
case ZOOM_ERROR_CONNECT:
switch (task->which)
{
case ZOOM_TASK_SEARCH:
- ZOOM_resultset_destroy(task->u.search.resultset);
+ resultset_destroy(task->u.search.resultset);
xfree(task->u.search.syntax);
xfree(task->u.search.elementSetName);
break;
case ZOOM_TASK_RETRIEVE:
- ZOOM_resultset_destroy(task->u.retrieve.resultset);
+ resultset_destroy(task->u.retrieve.resultset);
xfree(task->u.retrieve.syntax);
xfree(task->u.retrieve.elementSetName);
break;
ZOOM_package_destroy(task->u.package);
break;
case ZOOM_TASK_SORT:
- ZOOM_resultset_destroy(task->u.sort.resultset);
+ resultset_destroy(task->u.sort.resultset);
ZOOM_query_destroy(task->u.sort.q);
break;
default:
initlog();
yaz_log(log_api, "%p ZOOM_connection_connect host=%s portnum=%d",
- c, host, portnum);
+ c, host ? host : "null", portnum);
set_ZOOM_error(c, ZOOM_ERROR_NONE, 0);
ZOOM_connection_remove_tasks(c);
else
c->lang = 0;
- xfree(c->host_port);
- if (portnum)
+ if (host)
{
- char hostn[128];
- sprintf(hostn, "%.80s:%d", host, portnum);
- c->host_port = xstrdup(hostn);
- }
- else
- c->host_port = xstrdup(host);
+ xfree(c->host_port);
+ if (portnum)
+ {
+ char hostn[128];
+ sprintf(hostn, "%.80s:%d", host, portnum);
+ c->host_port = xstrdup(hostn);
+ }
+ else
+ c->host_port = xstrdup(host);
+ }
{
/*
ccl_pquery(wr, rpn);
ccl_rpn_delete(rpn);
ret = ZOOM_query_prefix(s, wrbuf_buf(wr));
- wrbuf_free(wr, 1);
+ wrbuf_destroy(wr);
}
ccl_qual_rm(&bibset);
return ret;
odr_destroy(c->odr_out);
ZOOM_options_destroy(c->options);
ZOOM_connection_remove_tasks(c);
+ ZOOM_connection_remove_events(c);
xfree(c->host_port);
xfree(c->path);
xfree(c->proxy);
for (rc = r->record_hash[i]; rc; rc = rc->next)
{
if (rc->rec.wrbuf_marc)
- wrbuf_free(rc->rec.wrbuf_marc, 1);
+ wrbuf_destroy(rc->rec.wrbuf_marc);
if (rc->rec.wrbuf_iconv)
- wrbuf_free(rc->rec.wrbuf_iconv, 1);
+ wrbuf_destroy(rc->rec.wrbuf_iconv);
if (rc->rec.wrbuf_opac)
- wrbuf_free(rc->rec.wrbuf_opac, 1);
+ wrbuf_destroy(rc->rec.wrbuf_opac);
}
r->record_hash[i] = 0;
}
ZOOM_API(void)
ZOOM_resultset_destroy(ZOOM_resultset r)
{
+ resultset_destroy(r);
+}
+
+static void resultset_destroy(ZOOM_resultset r)
+{
if (!r)
return;
(r->refcount)--;
static int ZOOM_test_reconnect(ZOOM_connection c)
{
+ ZOOM_Event event;
+
if (!c->reconnect_ok)
return 0;
do_close(c);
c->reconnect_ok = 0;
c->tasks->running = 0;
ZOOM_connection_insert_task(c, ZOOM_TASK_CONNECT);
+
+ event = ZOOM_Event_create(ZOOM_EVENT_CONNECT);
+ ZOOM_connection_put_event(c, event);
+
return 1;
}
odr_prepend(c->odr_out, "ZOOM-C",
ireq->implementationName));
- version = odr_strdup(c->odr_out, "$Revision: 1.106 $");
+ version = odr_strdup(c->odr_out, "$Revision: 1.116.2.1 $");
if (strlen(version) > 10) /* check for unexpanded CVS strings */
version[strlen(version)-2] = '\0';
ireq->implementationVersion =
}
if (syntax)
search_req->preferredRecordSyntax =
- yaz_str_to_z3950oid(c->odr_out, CLASS_RECSYN, syntax);
+ zoom_yaz_str_to_z3950oid(c, CLASS_RECSYN, syntax);
if (!r->setname)
{
if (!rec)
return;
if (rec->wrbuf_marc)
- wrbuf_free(rec->wrbuf_marc, 1);
+ wrbuf_destroy(rec->wrbuf_marc);
if (rec->wrbuf_iconv)
- wrbuf_free(rec->wrbuf_iconv, 1);
+ wrbuf_destroy(rec->wrbuf_iconv);
if (rec->wrbuf_opac)
- wrbuf_free(rec->wrbuf_opac, 1);
+ wrbuf_destroy(rec->wrbuf_opac);
odr_destroy(rec->odr);
xfree(rec);
}
resultset = c->tasks->u.search.resultset;
+ if (sr->resultSetStatus)
+ {
+ ZOOM_options_set_int(resultset->options, "resultSetStatus",
+ *sr->resultSetStatus);
+ }
+ if (sr->presentStatus)
+ {
+ ZOOM_options_set_int(resultset->options, "presentStatus",
+ *sr->presentStatus);
+ }
handle_searchResult(c, resultset, sr->additionalSearchInfo);
resultset->size = *sr->resultCount;
if (syntax && *syntax)
req->preferredRecordSyntax =
- yaz_str_to_z3950oid(c->odr_out, CLASS_RECSYN, syntax);
+ zoom_yaz_str_to_z3950oid(c, CLASS_RECSYN, syntax);
if (resultset->schema && *resultset->schema)
{
compo->u.complex->generic->which = Z_Schema_oid;
compo->u.complex->generic->schema.oid = (Odr_oid *)
- yaz_str_to_z3950oid (c->odr_out, CLASS_SCHEMA, resultset->schema);
+ zoom_yaz_str_to_z3950oid (c, CLASS_SCHEMA, resultset->schema);
if (!compo->u.complex->generic->schema.oid)
{
/* OID wasn't a schema! Try record syntax instead. */
compo->u.complex->generic->schema.oid = (Odr_oid *)
- yaz_str_to_z3950oid (c->odr_out, CLASS_RECSYN, resultset->schema);
+ zoom_yaz_str_to_z3950oid (c, CLASS_RECSYN, resultset->schema);
}
if (elementSetName && *elementSetName)
{
*req->u.esRequest->notToKeep->resultSetItem->item =
(str ? atoi(str) : 1);
}
- req->u.esRequest->notToKeep->itemRequest = encode_ill_request(p);
+
+ str = ZOOM_options_get(p->options, "doc");
+ if (str)
+ req->u.esRequest->notToKeep->itemRequest =
+ z_ext_record(p->odr_out, VAL_TEXT_XML, str, strlen(str));
+ else
+ req->u.esRequest->notToKeep->itemRequest = encode_ill_request(p);
return req;
}
return 0;
if (r <= 0)
{
- if (ZOOM_test_reconnect(c))
- {
- yaz_log(log_details, "%p do_read reconnect read", c);
- }
- else
+ if (!ZOOM_test_reconnect(c))
{
set_ZOOM_error(c, ZOOM_ERROR_CONNECTION_LOST, c->host_port);
do_close(c);
if (c->cs->io_pending & CS_WANT_READ)
mask += ZOOM_SELECT_READ;
ZOOM_connection_set_mask(c, mask);
+ event = ZOOM_Event_create(ZOOM_EVENT_NONE);
+ ZOOM_connection_put_event(c, event);
}
else if (ret == 0)
{
{
if (mask & ZOOM_SELECT_EXCEPT)
{
- if (ZOOM_test_reconnect(c))
- {
- event = ZOOM_Event_create(ZOOM_EVENT_CONNECT);
- ZOOM_connection_put_event(c, event);
- }
- else
+ if (!ZOOM_test_reconnect(c))
{
set_ZOOM_error(c, ZOOM_ERROR_CONNECTION_LOST, c->host_port);
do_close(c);
}
ZOOM_API(int)
- ZOOM_process_event(int no, ZOOM_connection *cs)
+ ZOOM_connection_process(ZOOM_connection c)
+{
+ ZOOM_Event event;
+ if (!c)
+ return 0;
+
+ event = ZOOM_connection_get_event(c);
+ if (event)
+ {
+ ZOOM_Event_destroy(event);
+ return 1;
+ }
+ ZOOM_connection_exec_task(c);
+ event = ZOOM_connection_get_event(c);
+ if (event)
+ {
+ ZOOM_Event_destroy(event);
+ return 1;
+ }
+ return 0;
+}
+
+ZOOM_API(int)
+ ZOOM_event_nonblock(int no, ZOOM_connection *cs)
{
int i;
- yaz_log(log_details, "ZOOM_event_poll(no=%d,cs=%p)", no, cs);
+ yaz_log(log_details, "ZOOM_process_event(no=%d,cs=%p)", no, cs);
for (i = 0; i<no; i++)
{
ZOOM_connection c = cs[i];
- ZOOM_Event event;
-
-#if 0
- if (c)
- ZOOM_connection_show_tasks(c);
-#endif
- if (c && (event = ZOOM_connection_get_event(c)))
- {
- ZOOM_Event_destroy(event);
+ if (c && ZOOM_connection_process(c))
return i+1;
- }
- }
- for (i = 0; i<no; i++)
- {
- ZOOM_connection c = cs[i];
- if (c)
- {
- ZOOM_Event event;
- ZOOM_connection_exec_task(c);
- if ((event = ZOOM_connection_get_event(c)))
- {
- ZOOM_Event_destroy(event);
- return i+1;
- }
- }
}
return 0;
}