X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fzoom-c.c;h=1dfe91866056276f8895de46ebbb807785e63d37;hb=6e8a098c117cb6a92c30c536f7ec939520c18e22;hp=9fa1e49dbda6b594492a81e566e77cb76eedc650;hpb=976e19ac608c2992096baf821426186570ea2df9;p=yaz-moved-to-github.git diff --git a/src/zoom-c.c b/src/zoom-c.c index 9fa1e49..1dfe918 100644 --- a/src/zoom-c.c +++ b/src/zoom-c.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2005, Index Data ApS * See the file LICENSE for details. * - * $Id: zoom-c.c,v 1.47 2005-10-17 12:29:44 mike Exp $ + * $Id: zoom-c.c,v 1.56 2005-12-19 17:04:35 mike Exp $ */ /** * \file zoom-c.c @@ -388,6 +388,37 @@ ZOOM_connection_connect(ZOOM_connection c, else c->host_port = xstrdup(host); + { + /* + * If the ":" part of the host string is preceded by one + * or more comma-separated = pairs, these are taken + * to be options to be set on the connection object. Among other + * applications, this facility can be used to embed authentication + * in a host string: + * user=admin,password=secret,tcp:localhost:9999 + */ + char *remainder = c->host_port; + char *pcolon = strchr(remainder, ':'); + char *pcomma; + char *pequals; + while ((pcomma = strchr(remainder, ',')) != 0 && + (pcolon == 0 || pcomma < pcolon)) { + *pcomma = '\0'; + if ((pequals = strchr(remainder, '=')) != 0) { + *pequals = '\0'; + /*printf("# setting '%s'='%s'\n", remainder, pequals+1);*/ + ZOOM_connection_option_set(c, remainder, pequals+1); + } + remainder = pcomma+1; + } + + if (remainder != c->host_port) { + xfree(c->host_port); + c->host_port = xstrdup(remainder); + /*printf("# reset hp='%s'\n", remainder);*/ + } + } + ZOOM_options_set(c->options, "host", c->host_port); val = ZOOM_options_get (c->options, "cookie"); @@ -644,17 +675,34 @@ ZOOM_connection_search(ZOOM_connection c, ZOOM_query q) return r; } +/* + * This is the old result-set sorting API, which is maintained only + * for the sake of binary compatibility. There is no reason ever to + * use this rather than ZOOM_resultset_sort1(). + */ ZOOM_API(void) - ZOOM_resultset_sort(ZOOM_resultset r, - const char *sort_type, const char *sort_spec) +ZOOM_resultset_sort(ZOOM_resultset r, + const char *sort_type, const char *sort_spec) +{ + (void) ZOOM_resultset_sort1(r, sort_type, sort_spec); +} + +ZOOM_API(int) +ZOOM_resultset_sort1(ZOOM_resultset r, + const char *sort_type, const char *sort_spec) { ZOOM_connection c = r->connection; ZOOM_task task; + ZOOM_query newq; + + newq = ZOOM_query_create(); + if (ZOOM_query_sortby(newq, sort_spec) < 0) + return -1; yaz_log(log_api, "%p ZOOM_resultset_sort r=%p sort_type=%s sort_spec=%s", r, r, sort_type, sort_spec); if (!c) - return; + return 0; if (c->host_port && c->proto == PROTO_HTTP) { @@ -674,8 +722,7 @@ ZOOM_API(void) ZOOM_resultset_cache_reset(r); task = ZOOM_connection_add_task (c, ZOOM_TASK_SORT); task->u.sort.resultset = r; - task->u.sort.q = ZOOM_query_create(); - ZOOM_query_sortby(task->u.sort.q, sort_spec); + task->u.sort.q = newq; ZOOM_resultset_addref (r); @@ -684,6 +731,8 @@ ZOOM_API(void) while (ZOOM_event (1, &c)) ; } + + return 0; } ZOOM_API(void) @@ -1045,7 +1094,7 @@ static zoom_ret ZOOM_connection_send_init (ZOOM_connection c) ZOOM_options_get(c->options, "implementationName"), odr_prepend(c->odr_out, "ZOOM-C", ireq->implementationName)); - version = odr_strdup(c->odr_out, "$Revision: 1.47 $"); + version = odr_strdup(c->odr_out, "$Revision: 1.56 $"); if (strlen(version) > 10) /* check for unexpanded CVS strings */ version[strlen(version)-2] = '\0'; ireq->implementationVersion = odr_prepend(c->odr_out, @@ -2028,6 +2077,111 @@ static void handle_present_response (ZOOM_connection c, Z_PresentResponse *pr) handle_records (c, pr->records, 1); } +static void handle_queryExpressionTerm(ZOOM_options opt, const char *name, + Z_Term *term) +{ + switch (term->which) + { + case Z_Term_general: + ZOOM_options_setl(opt, name, + term->u.general->buf, term->u.general->len); + break; + case Z_Term_characterString: + ZOOM_options_set(opt, name, term->u.characterString); + break; + case Z_Term_numeric: + ZOOM_options_set_int(opt, name, *term->u.numeric); + break; + } +} + +static void handle_queryExpression(ZOOM_options opt, const char *name, + Z_QueryExpression *exp) +{ + char opt_name[80]; + + switch (exp->which) + { + case Z_QueryExpression_term: + if (exp->u.term && exp->u.term->queryTerm) + { + sprintf(opt_name, "%s.term", name); + handle_queryExpressionTerm(opt, opt_name, exp->u.term->queryTerm); + } + break; + case Z_QueryExpression_query: + break; + } +} + +static void handle_searchResult(ZOOM_connection c, ZOOM_resultset resultset, + Z_OtherInformation *o) +{ + int i; + for (i = 0; o && i < o->num_elements; i++) + { + if (o->list[i]->which == Z_OtherInfo_externallyDefinedInfo) + { + Z_External *ext = o->list[i]->information.externallyDefinedInfo; + + if (ext->which == Z_External_searchResult1) + { + int j; + Z_SearchInfoReport *sr = ext->u.searchResult1; + + if (sr->num) + ZOOM_options_set_int( + resultset->options, "searchresult.size", sr->num); + + for (j = 0; j < sr->num; j++) + { + Z_SearchInfoReport_s *ent = + ext->u.searchResult1->elements[j]; + char pref[80]; + + sprintf(pref, "searchresult.%d", j); + + if (ent->subqueryId) + { + char opt_name[80]; + sprintf(opt_name, "%s.id", pref); + ZOOM_options_set(resultset->options, opt_name, + ent->subqueryId); + } + if (ent->subqueryExpression) + { + char opt_name[80]; + sprintf(opt_name, "%s.subquery", pref); + handle_queryExpression(resultset->options, opt_name, + ent->subqueryExpression); + } + if (ent->subqueryInterpretation) + { + char opt_name[80]; + sprintf(opt_name, "%s.interpretation", pref); + handle_queryExpression(resultset->options, opt_name, + ent->subqueryInterpretation); + } + if (ent->subqueryRecommendation) + { + char opt_name[80]; + sprintf(opt_name, "%s.recommendation", pref); + handle_queryExpression(resultset->options, opt_name, + ent->subqueryRecommendation); + } + if (ent->subqueryCount) + { + char opt_name[80]; + sprintf(opt_name, "%s.count", pref); + ZOOM_options_set_int(resultset->options, opt_name, + *ent->subqueryCount); + } + } + } + } + } +} + static void handle_search_response (ZOOM_connection c, Z_SearchResponse *sr) { ZOOM_resultset resultset; @@ -2035,12 +2189,14 @@ static void handle_search_response (ZOOM_connection c, Z_SearchResponse *sr) if (!c->tasks || c->tasks->which != ZOOM_TASK_SEARCH) return ; - + event = ZOOM_Event_create(ZOOM_EVENT_RECV_SEARCH); ZOOM_connection_put_event(c, event); resultset = c->tasks->u.search.resultset; + handle_searchResult(c, resultset, sr->additionalSearchInfo); + resultset->size = *sr->resultCount; handle_records (c, sr->records, 0); } @@ -2241,7 +2397,22 @@ static zoom_ret send_present(ZOOM_connection c) ZOOM_API(ZOOM_scanset) ZOOM_connection_scan (ZOOM_connection c, const char *start) { + ZOOM_scanset s; + ZOOM_query q = ZOOM_query_create(); + + ZOOM_query_prefix (q, start); + + s = ZOOM_connection_scan1(c, q); + ZOOM_query_destroy (q); + return s; + +} + +ZOOM_API(ZOOM_scanset) +ZOOM_connection_scan1 (ZOOM_connection c, ZOOM_query q) +{ ZOOM_scanset scan = (ZOOM_scanset) xmalloc (sizeof(*scan)); + char *start; scan->connection = c; scan->odr = odr_createmem (ODR_DECODE); @@ -2249,9 +2420,32 @@ ZOOM_connection_scan (ZOOM_connection c, const char *start) scan->refcount = 1; scan->scan_response = 0; + /* + * We need to check the query-type, so we can recognise CQL and + * compile it into a form that we can use here. The ZOOM_query + * structure has no explicit `type' member, but inspection of the + * ZOOM_query_prefix() and ZOOM_query_cql() functions shows how + * the structure is set up in each case. + */ + + if (q->z_query->which == Z_Query_type_1) { + yaz_log(log_api, "%p ZOOM_connection_scan1 q=%p PQF '%s'", + c, q, q->query_string); + start = q->query_string; + } else if (q->z_query->which == Z_Query_type_104) { + yaz_log(log_api, "%p ZOOM_connection_scan1 q=%p CQL '%s'", + c, q, q->query_string); + /* Not yet supported */ + abort(); + } else { + yaz_log(YLOG_FATAL, "%p ZOOM_connection_scan1 q=%p unknown type '%s'", + c, q, q->query_string); + abort(); + } + if ((scan->termListAndStartPoint = p_query_scan(scan->odr, PROTO_Z3950, &scan->attributeSet, - start))) + start)) != 0) { ZOOM_task task = ZOOM_connection_add_task (c, ZOOM_TASK_SCAN); task->u.scan.scan = scan; @@ -3467,6 +3661,14 @@ ZOOM_connection_addinfo (ZOOM_connection c) } ZOOM_API(const char *) +ZOOM_connection_diagset (ZOOM_connection c) +{ + const char *diagset; + ZOOM_connection_error_x (c, 0, 0, &diagset); + return diagset; +} + +ZOOM_API(const char *) ZOOM_diag_str (int error) { switch (error)