#include <yaz/xmalloc.h>
#include <yaz/otherinfo.h>
#include <yaz/log.h>
-#include <yaz/pquery.h>
#include <yaz/marcdisp.h>
#include <yaz/diagbib1.h>
#include <yaz/charneg.h>
-#include <yaz/ill.h>
-#include <yaz/srw.h>
-#include <yaz/cql.h>
-#include <yaz/ccl.h>
#include <yaz/query-charset.h>
#include <yaz/copy_types.h>
#include <yaz/snprintf.h>
static void resultset_destroy(ZOOM_resultset r);
static zoom_ret do_write_ex(ZOOM_connection c, char *buf_out, int len_out);
-static char *cql2pqf(ZOOM_connection c, const char *cql);
ZOOM_API(const char *) ZOOM_get_event_str(int event)
{
}
}
-static int uri_to_code(const char *uri)
+int ZOOM_uri_to_code(const char *uri)
{
int code = 0;
const char *cp;
return code;
}
+
#if YAZ_HAVE_XML2
static void set_HTTP_error(ZOOM_connection c, int error,
const char *addinfo, const char *addinfo2)
{
const char *uri = d->uri;
if (uri)
- ZOOM_set_dset_error(c, uri_to_code(uri), uri, d->details, 0);
+ ZOOM_set_dset_error(c, ZOOM_uri_to_code(uri), uri, d->details, 0);
}
#endif
}
}
-ZOOM_API(ZOOM_query)
- ZOOM_query_create(void)
-{
- ZOOM_query s = (ZOOM_query) xmalloc(sizeof(*s));
-
- s->refcount = 1;
- s->z_query = 0;
- s->sort_spec = 0;
- s->odr = odr_createmem(ODR_ENCODE);
- s->query_string = 0;
-
- return s;
-}
-
-ZOOM_API(void)
- ZOOM_query_destroy(ZOOM_query s)
-{
- if (!s)
- return;
-
- (s->refcount)--;
- if (s->refcount == 0)
- {
- odr_destroy(s->odr);
- xfree(s);
- }
-}
-
-ZOOM_API(int)
- ZOOM_query_prefix(ZOOM_query s, const char *str)
-{
- s->query_string = odr_strdup(s->odr, str);
- s->z_query = (Z_Query *) odr_malloc(s->odr, sizeof(*s->z_query));
- s->z_query->which = Z_Query_type_1;
- s->z_query->u.type_1 = p_query_rpn(s->odr, str);
- if (!s->z_query->u.type_1)
- {
- s->z_query = 0;
- return -1;
- }
- return 0;
-}
-
-ZOOM_API(int)
- ZOOM_query_cql(ZOOM_query s, const char *str)
-{
- Z_External *ext;
-
- s->query_string = odr_strdup(s->odr, str);
-
- ext = (Z_External *) odr_malloc(s->odr, sizeof(*ext));
- ext->direct_reference = odr_oiddup(s->odr, yaz_oid_userinfo_cql);
- ext->indirect_reference = 0;
- ext->descriptor = 0;
- ext->which = Z_External_CQL;
- ext->u.cql = s->query_string;
-
- s->z_query = (Z_Query *) odr_malloc(s->odr, sizeof(*s->z_query));
- s->z_query->which = Z_Query_type_104;
- s->z_query->u.type_104 = ext;
-
- return 0;
-}
-
-/*
- * Translate the CQL string client-side into RPN which is passed to
- * the server. This is useful for server's that don't themselves
- * support CQL, for which ZOOM_query_cql() is useless. `conn' is used
- * only as a place to stash diagnostics if compilation fails; if this
- * information is not needed, a null pointer may be used.
- */
-ZOOM_API(int)
- ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn)
-{
- char *rpn;
- int ret;
- ZOOM_connection freeme = 0;
-
- if (conn == 0)
- conn = freeme = ZOOM_connection_create(0);
-
- rpn = cql2pqf(conn, str);
- if (freeme != 0)
- ZOOM_connection_destroy(freeme);
- if (rpn == 0)
- return -1;
-
- ret = ZOOM_query_prefix(s, rpn);
- xfree(rpn);
- return ret;
-}
-
-/*
- * Analogous in every way to ZOOM_query_cql2rpn(), except that there
- * is no analogous ZOOM_query_ccl() that just sends uninterpreted CCL
- * to the server, as the YAZ GFS doesn't know how to handle this.
- */
-ZOOM_API(int)
- ZOOM_query_ccl2rpn(ZOOM_query s, const char *str, const char *config,
- int *ccl_error, const char **error_string,
- int *error_pos)
-{
- int ret;
- struct ccl_rpn_node *rpn;
- CCL_bibset bibset = ccl_qual_mk();
-
- if (config)
- ccl_qual_buf(bibset, config);
-
- rpn = ccl_find_str(bibset, str, ccl_error, error_pos);
- if (!rpn)
- {
- *error_string = ccl_err_msg(*ccl_error);
- ret = -1;
- }
- else
- {
- WRBUF wr = wrbuf_alloc();
- ccl_pquery(wr, rpn);
- ccl_rpn_delete(rpn);
- ret = ZOOM_query_prefix(s, wrbuf_cstr(wr));
- wrbuf_destroy(wr);
- }
- ccl_qual_rm(&bibset);
- return ret;
-}
-
-ZOOM_API(int)
- ZOOM_query_sortby(ZOOM_query s, const char *criteria)
-{
- s->sort_spec = yaz_sort_spec(s->odr, criteria);
- if (!s->sort_spec)
- return -1;
- return 0;
-}
-
ZOOM_API(void) ZOOM_resultset_release(ZOOM_resultset r)
{
#if ZOOM_RESULT_LISTS
#endif
yaz_log(c->log_api, "%p ZOOM_connection_search set %p query %p", c, r, q);
- r->r_sort_spec = q->sort_spec;
+ r->r_sort_spec = ZOOM_query_get_sortspec(q);
r->query = q;
r->options = ZOOM_options_create_with_parent(c->options);
ZOOM_resultset_addref(r);
- (q->refcount)++;
+ ZOOM_query_addref(q);
if (!c->async)
{
return 0;
}
-static void ZOOM_record_release(ZOOM_record rec)
-{
- if (!rec)
- return;
-
-#if SHPTR
- if (rec->record_wrbuf)
- YAZ_SHPTR_DEC(rec->record_wrbuf, wrbuf_destroy);
-#else
- if (rec->wrbuf)
- wrbuf_destroy(rec->wrbuf);
-#endif
-
- if (rec->odr)
- odr_destroy(rec->odr);
-}
-
-ZOOM_API(void)
- ZOOM_resultset_cache_reset(ZOOM_resultset r)
-{
- int i;
- for (i = 0; i<RECORD_HASH_SIZE; i++)
- {
- ZOOM_record_cache rc;
- for (rc = r->record_hash[i]; rc; rc = rc->next)
- {
- ZOOM_record_release(&rc->rec);
- }
- r->record_hash[i] = 0;
- }
-}
-
ZOOM_API(void)
ZOOM_resultset_destroy(ZOOM_resultset r)
{
ZOOM_resultset resultset = 0;
Z_SRW_PDU *sr = 0;
const char *option_val = 0;
+ Z_Query *z_query;
if (c->error) /* don't continue on error */
return zoom_complete;
assert(resultset->query);
sr = ZOOM_srw_get_pdu(c, Z_SRW_searchRetrieve_request);
- if (resultset->query->z_query->which == Z_Query_type_104
- && resultset->query->z_query->u.type_104->which == Z_External_CQL)
+ z_query = ZOOM_query_get_Z_Query(resultset->query);
+
+ if (z_query->which == Z_Query_type_104
+ && z_query->u.type_104->which == Z_External_CQL)
{
sr->u.request->query_type = Z_SRW_query_type_cql;
- sr->u.request->query.cql =resultset->query->z_query->u.type_104->u.cql;
+ sr->u.request->query.cql = z_query->u.type_104->u.cql;
}
- else if (resultset->query->z_query->which == Z_Query_type_1 &&
- resultset->query->z_query->u.type_1)
+ else if (z_query->which == Z_Query_type_1 && z_query->u.type_1)
{
sr->u.request->query_type = Z_SRW_query_type_pqf;
- sr->u.request->query.pqf = resultset->query->query_string;
+ sr->u.request->query.pqf =
+ ZOOM_query_get_query_string(resultset->query);
}
else
{
#endif
ZOOM_API(ZOOM_record)
- ZOOM_record_clone(ZOOM_record srec)
-{
- char *buf;
- int size;
- ODR odr_enc;
- ZOOM_record nrec;
-
- odr_enc = odr_createmem(ODR_ENCODE);
- if (!z_NamePlusRecord(odr_enc, &srec->npr, 0, 0))
- return 0;
- buf = odr_getbuf(odr_enc, &size, 0);
-
- nrec = (ZOOM_record) xmalloc(sizeof(*nrec));
- yaz_log(log_details0, "ZOOM_record create");
- nrec->odr = odr_createmem(ODR_DECODE);
-#if SHPTR
- nrec->record_wrbuf = 0;
-#else
- nrec->wrbuf = 0;
-#endif
- odr_setbuf(nrec->odr, buf, size, 0);
- z_NamePlusRecord(nrec->odr, &nrec->npr, 0, 0);
-
- nrec->schema = odr_strdup_null(nrec->odr, srec->schema);
- nrec->diag_uri = odr_strdup_null(nrec->odr, srec->diag_uri);
- nrec->diag_message = odr_strdup_null(nrec->odr, srec->diag_message);
- nrec->diag_details = odr_strdup_null(nrec->odr, srec->diag_details);
- nrec->diag_set = odr_strdup_null(nrec->odr, srec->diag_set);
- odr_destroy(odr_enc);
- return nrec;
-}
-
-ZOOM_API(ZOOM_record)
ZOOM_resultset_record_immediate(ZOOM_resultset s,size_t pos)
{
const char *syntax =
return rec;
}
-ZOOM_API(void)
- ZOOM_record_destroy(ZOOM_record rec)
-{
- ZOOM_record_release(rec);
- yaz_log(log_details0, "ZOOM_record destroy");
- xfree(rec);
-}
-
-
static yaz_iconv_t iconv_create_charset(const char *record_charset)
{
char to[40];
return 0;
}
-ZOOM_API(int)
- ZOOM_record_error(ZOOM_record rec, const char **cp,
- const char **addinfo, const char **diagset)
-{
- Z_NamePlusRecord *npr;
-
- if (!rec)
- return 0;
-
- npr = rec->npr;
- if (rec->diag_uri)
- {
- if (cp)
- *cp = rec->diag_message;
- if (addinfo)
- *addinfo = rec->diag_details;
- if (diagset)
- *diagset = rec->diag_set;
- return uri_to_code(rec->diag_uri);
- }
- if (npr && npr->which == Z_NamePlusRecord_surrogateDiagnostic)
- {
- Z_DiagRec *diag_rec = npr->u.surrogateDiagnostic;
- int error = YAZ_BIB1_UNSPECIFIED_ERROR;
- const char *add = 0;
-
- if (diag_rec->which == Z_DiagRec_defaultFormat)
- {
- Z_DefaultDiagFormat *ddf = diag_rec->u.defaultFormat;
- oid_class oclass;
-
- error = *ddf->condition;
- switch (ddf->which)
- {
- case Z_DefaultDiagFormat_v2Addinfo:
- add = ddf->u.v2Addinfo;
- break;
- case Z_DefaultDiagFormat_v3Addinfo:
- add = ddf->u.v3Addinfo;
- break;
- }
- if (diagset)
- *diagset =
- yaz_oid_to_string(yaz_oid_std(),
- ddf->diagnosticSetId, &oclass);
- }
- else
- {
- if (diagset)
- *diagset = "Bib-1";
- }
- if (addinfo)
- *addinfo = add ? add : "";
- if (cp)
- *cp = diagbib1_str(error);
- return error;
- }
- return 0;
-}
-
static const char *get_record_format(WRBUF wrbuf, int *len,
Z_NamePlusRecord *npr,
int marctype, const char *charset,
}
-static const char *npr_format(Z_NamePlusRecord *npr, const char *schema,
- WRBUF wrbuf,
- const char *type_spec, int *len)
+const char *ZOOM_npr_format(Z_NamePlusRecord *npr, const char *schema,
+ WRBUF wrbuf,
+ const char *type_spec, int *len)
{
size_t i;
char type[40];
return 0;
}
-ZOOM_API(const char *)
- ZOOM_record_get(ZOOM_record rec, const char *type_spec, int *len)
-{
- WRBUF wrbuf;
-
- if (len)
- *len = 0; /* default return */
-
- if (!rec || !rec->npr)
- return 0;
-
-#if SHPTR
- if (!rec->record_wrbuf)
- {
- WRBUF w = wrbuf_alloc();
- YAZ_SHPTR_INIT(rec->record_wrbuf, w);
- }
- wrbuf = rec->record_wrbuf->ptr;
-#else
- if (!rec->wrbuf)
- rec->wrbuf = wrbuf_alloc();
- wrbuf = rec->wrbuf;
-#endif
- return npr_format(rec->npr, rec->schema, wrbuf, type_spec, len);
-}
-
-static int strcmp_null(const char *v1, const char *v2)
-{
- if (!v1 && !v2)
- return 0;
- if (!v1 || !v2)
- return -1;
- return strcmp(v1, v2);
-}
-
-static size_t record_hash(int pos)
-{
- if (pos < 0)
- pos = 0;
- return pos % RECORD_HASH_SIZE;
-}
-
-void ZOOM_record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr,
- int pos,
- const char *syntax, const char *elementSetName,
- const char *schema,
- Z_SRW_diagnostic *diag)
-{
- ZOOM_record_cache rc = 0;
-
- ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_RECV_RECORD);
- ZOOM_connection_put_event(r->connection, event);
-
- for (rc = r->record_hash[record_hash(pos)]; rc; rc = rc->next)
- {
- if (pos == rc->pos
- && strcmp_null(r->schema, rc->schema) == 0
- && strcmp_null(elementSetName,rc->elementSetName) == 0
- && strcmp_null(syntax, rc->syntax) == 0)
- break;
- }
- if (!rc)
- {
- rc = (ZOOM_record_cache) odr_malloc(r->odr, sizeof(*rc));
- rc->rec.odr = 0;
-#if SHPTR
- YAZ_SHPTR_INC(r->record_wrbuf);
- rc->rec.record_wrbuf = r->record_wrbuf;
-#else
- rc->rec.wrbuf = 0;
-#endif
- rc->elementSetName = odr_strdup_null(r->odr, elementSetName);
-
- rc->syntax = odr_strdup_null(r->odr, syntax);
-
- rc->schema = odr_strdup_null(r->odr, r->schema);
-
- rc->pos = pos;
- rc->next = r->record_hash[record_hash(pos)];
- r->record_hash[record_hash(pos)] = rc;
- }
- rc->rec.npr = npr;
- rc->rec.schema = odr_strdup_null(r->odr, schema);
- rc->rec.diag_set = 0;
- rc->rec.diag_uri = 0;
- rc->rec.diag_message = 0;
- rc->rec.diag_details = 0;
- if (diag)
- {
- if (diag->uri)
- {
- char *cp;
- rc->rec.diag_set = odr_strdup(r->odr, diag->uri);
- if ((cp = strrchr(rc->rec.diag_set, '/')))
- *cp = '\0';
- rc->rec.diag_uri = odr_strdup(r->odr, diag->uri);
- }
- rc->rec.diag_message = odr_strdup_null(r->odr, diag->message);
- rc->rec.diag_details = odr_strdup_null(r->odr, diag->details);
- }
-}
-
-ZOOM_record ZOOM_record_cache_lookup(ZOOM_resultset r, int pos,
- const char *syntax,
- const char *elementSetName)
-{
- ZOOM_record_cache rc;
-
- for (rc = r->record_hash[record_hash(pos)]; rc; rc = rc->next)
- {
- if (pos == rc->pos)
- {
- if (strcmp_null(r->schema, rc->schema))
- continue;
- if (strcmp_null(elementSetName,rc->elementSetName))
- continue;
- if (strcmp_null(syntax, rc->syntax))
- continue;
- return &rc->rec;
- }
- }
- return 0;
-}
-
-
ZOOM_API(ZOOM_scanset)
ZOOM_connection_scan(ZOOM_connection c, const char *start)
{
ZOOM_connection_scan1(ZOOM_connection c, ZOOM_query q)
{
ZOOM_scanset scan = 0;
+ Z_Query *z_query = ZOOM_query_get_Z_Query(q);
- if (!q->z_query)
+ if (!z_query)
return 0;
scan = (ZOOM_scanset) xmalloc(sizeof(*scan));
scan->connection = c;
scan->srw_scan_response = 0;
scan->query = q;
- (q->refcount)++;
+ ZOOM_query_addref(q);
scan->databaseNames = ZOOM_connection_get_databases(c, c->options,
&scan->num_databaseNames,
scan->odr);
ZOOM_scanset scan;
Z_SRW_PDU *sr = 0;
const char *option_val = 0;
+ Z_Query *z_query;
if (!c->tasks)
return zoom_complete;
sr = ZOOM_srw_get_pdu(c, Z_SRW_scan_request);
+ z_query = ZOOM_query_get_Z_Query(scan->query);
/* SRU scan can only carry CQL and PQF */
- if (scan->query->z_query->which == Z_Query_type_104)
+ if (z_query->which == Z_Query_type_104)
{
sr->u.scan_request->query_type = Z_SRW_query_type_cql;
- sr->u.scan_request->scanClause.cql = scan->query->query_string;
+ sr->u.scan_request->scanClause.cql =
+ ZOOM_query_get_query_string(scan->query);
}
- else if (scan->query->z_query->which == Z_Query_type_1
- || scan->query->z_query->which == Z_Query_type_101)
+ else if (z_query->which == Z_Query_type_1
+ || z_query->which == Z_Query_type_101)
{
sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
- sr->u.scan_request->scanClause.pqf = scan->query->query_string;
+ sr->u.scan_request->scanClause.pqf =
+ ZOOM_query_get_query_string(scan->query);
}
else
{
break;
case ZOOM_TASK_SORT:
c->tasks->u.sort.resultset->r_sort_spec =
- c->tasks->u.sort.q->sort_spec;
+ ZOOM_query_get_sortspec(c->tasks->u.sort.q);
ret = send_Z3950_sort(c, c->tasks->u.sort.resultset);
break;
}
}
-static void cql2pqf_wrbuf_puts(const char *buf, void *client_data)
-{
- WRBUF wrbuf = (WRBUF) client_data;
- wrbuf_puts(wrbuf, buf);
-}
-
-/*
- * Returns an xmalloc()d string containing RPN that corresponds to the
- * CQL passed in. On error, sets the Connection object's error state
- * and returns a null pointer.
- * ### We could cache CQL parser and/or transformer in Connection.
- */
-static char *cql2pqf(ZOOM_connection c, const char *cql)
-{
- CQL_parser parser;
- int error;
- const char *cqlfile;
- cql_transform_t trans;
- char *result = 0;
-
- parser = cql_parser_create();
- if ((error = cql_parser_string(parser, cql)) != 0) {
- cql_parser_destroy(parser);
- ZOOM_set_error(c, ZOOM_ERROR_CQL_PARSE, cql);
- return 0;
- }
-
- cqlfile = ZOOM_connection_option_get(c, "cqlfile");
- if (cqlfile == 0)
- {
- ZOOM_set_error(c, ZOOM_ERROR_CQL_TRANSFORM, "no CQL transform file");
- }
- else if ((trans = cql_transform_open_fname(cqlfile)) == 0)
- {
- char buf[512];
- sprintf(buf, "can't open CQL transform file '%.200s': %.200s",
- cqlfile, strerror(errno));
- ZOOM_set_error(c, ZOOM_ERROR_CQL_TRANSFORM, buf);
- }
- else
- {
- WRBUF wrbuf_result = wrbuf_alloc();
- error = cql_transform(trans, cql_parser_result(parser),
- cql2pqf_wrbuf_puts, wrbuf_result);
- if (error != 0) {
- char buf[512];
- const char *addinfo;
- error = cql_transform_error(trans, &addinfo);
- sprintf(buf, "%.200s (addinfo=%.200s)",
- cql_strerror(error), addinfo);
- ZOOM_set_error(c, ZOOM_ERROR_CQL_TRANSFORM, buf);
- }
- else
- {
- result = xstrdup(wrbuf_cstr(wrbuf_result));
- }
- cql_transform_close(trans);
- wrbuf_destroy(wrbuf_result);
- }
- cql_parser_destroy(parser);
- return result;
-}
-
ZOOM_API(int) ZOOM_connection_fire_event_timeout(ZOOM_connection c)
{
if (c->mask)