From: Adam Dickmeiss Date: Mon, 29 Dec 2003 14:54:33 +0000 (+0000) Subject: SRW scan X-Git-Tag: YAZ.2.0.9~12 X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=commitdiff_plain;h=037037e14faa1f992ed3574817086eabc469c9c4 SRW scan --- diff --git a/include/yaz/backend.h b/include/yaz/backend.h index d321de5..1c63474 100644 --- a/include/yaz/backend.h +++ b/include/yaz/backend.h @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: backend.h,v 1.21 2003-04-24 13:30:32 adam Exp $ + * $Id: backend.h,v 1.22 2003-12-29 14:54:33 adam Exp $ */ #ifndef BACKEND_H @@ -190,6 +190,7 @@ typedef struct { ODR decode; ODR print; char *explain_buf; + char *database; } bend_explain_rr; typedef struct bend_initrequest diff --git a/include/yaz/srw.h b/include/yaz/srw.h index a1ecadd..c031b24 100644 --- a/include/yaz/srw.h +++ b/include/yaz/srw.h @@ -2,7 +2,7 @@ * Copyright (c) 2002-2003, Index Data. * See the file LICENSE for details. * - * $Id: srw.h,v 1.9 2003-12-20 00:51:19 adam Exp $ + * $Id: srw.h,v 1.10 2003-12-29 14:54:33 adam Exp $ */ #ifndef YAZ_SRW_H @@ -50,10 +50,13 @@ typedef struct { char *xSortKeys; } sort; int *startRecord; - int *maximumRecords; + int *maximumRecords; char *recordSchema; char *recordPacking; + char *recordXPath; char *database; + char *stylesheet; + int *resultSetTTL; } Z_SRW_searchRetrieveRequest; typedef struct { @@ -76,12 +79,37 @@ typedef struct { typedef struct { Z_SRW_record record; + Z_SRW_diagnostic *diagnostics; + int num_diagnostics; } Z_SRW_explainResponse; +typedef struct { + char *scanClause; + int *responsePosition; + int *maximumTerms; + char *stylesheet; + char *database; +} Z_SRW_scanRequest; + +typedef struct { + char *value; + int *numberOfRecords; + char *displayTerm; +} Z_SRW_scanTerm; + +typedef struct { + Z_SRW_scanTerm *terms; + int num_terms; + Z_SRW_diagnostic *diagnostics; + int num_diagnostics; +} Z_SRW_scanResponse; + #define Z_SRW_searchRetrieve_request 1 #define Z_SRW_searchRetrieve_response 2 #define Z_SRW_explain_request 3 #define Z_SRW_explain_response 4 +#define Z_SRW_scan_request 5 +#define Z_SRW_scan_response 6 typedef struct { int which; @@ -90,9 +118,10 @@ typedef struct { Z_SRW_searchRetrieveResponse *response; Z_SRW_explainRequest *explain_request; Z_SRW_explainResponse *explain_response; + Z_SRW_scanRequest *scan_request; + Z_SRW_scanResponse *scan_response; } u; char *srw_version; - char *database; } Z_SRW_PDU; YAZ_EXPORT int yaz_srw_codec(ODR o, void * pptr, diff --git a/src/seshigh.c b/src/seshigh.c index 7e5f65b..cc5f47d 100644 --- a/src/seshigh.c +++ b/src/seshigh.c @@ -2,7 +2,7 @@ * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: seshigh.c,v 1.8 2003-12-29 13:39:41 adam Exp $ + * $Id: seshigh.c,v 1.9 2003-12-29 14:54:33 adam Exp $ */ /* @@ -546,12 +546,14 @@ static int srw_bend_fetch(association *assoc, int pos, static void srw_bend_search(association *assoc, request *req, Z_SRW_searchRetrieveRequest *srw_req, - Z_SRW_searchRetrieveResponse *srw_res) + Z_SRW_searchRetrieveResponse *srw_res, + int *http_code) { int srw_error = 0; bend_search_rr rr; Z_External *ext; + *http_code = 200; yaz_log(LOG_LOG, "Got SRW SearchRetrieveRequest"); yaz_log(LOG_DEBUG, "srw_bend_search"); if (!assoc->init) @@ -654,6 +656,11 @@ static void srw_bend_search(association *assoc, request *req, if (rr.errcode) { yaz_log(LOG_DEBUG, "bend_search returned Bib-1 code %d", rr.errcode); + if (rr.errcode == 109) /* database unavailable */ + { + *http_code = 404; + return; + } srw_res->num_diagnostics = 1; srw_res->diagnostics = (Z_SRW_diagnostic *) odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics)); @@ -728,14 +735,18 @@ static void srw_bend_search(association *assoc, request *req, static void srw_bend_explain(association *assoc, request *req, Z_SRW_explainRequest *srw_req, - Z_SRW_explainResponse *srw_res) + Z_SRW_explainResponse *srw_res, + int *http_code) { yaz_log(LOG_LOG, "Got SRW ExplainRequest"); + *http_code = 404; if (!assoc->init) { yaz_log(LOG_DEBUG, "srw_bend_init"); if (!srw_bend_init(assoc)) + { return; + } } if (assoc->init && assoc->init->bend_explain) { @@ -745,6 +756,7 @@ static void srw_bend_explain(association *assoc, request *req, rr.decode = assoc->decode; rr.print = assoc->print; rr.explain_buf = 0; + rr.database = srw_req->database; (*assoc->init->bend_explain)(assoc->backend, &rr); if (rr.explain_buf) { @@ -757,6 +769,7 @@ static void srw_bend_explain(association *assoc, request *req, srw_res->record.recordData_buf = rr.explain_buf; srw_res->record.recordData_len = strlen(rr.explain_buf); srw_res->record.recordPosition = 0; + *http_code = 200; } } } @@ -807,6 +820,7 @@ static void process_http_request(association *assoc, request *req) char *query = yaz_uri_val(p1, "query", o); char *pQuery = yaz_uri_val(p1, "pQuery", o); char *sortKeys = yaz_uri_val(p1, "sortKeys", o); + int http_code = 200; if (query) { @@ -832,7 +846,8 @@ static void process_http_request(association *assoc, request *req) yaz_uri_val_int(p1, "startRecord", o, &sr->u.request->startRecord); sr->u.request->database = db; - srw_bend_search(assoc, req, sr->u.request, res->u.response); + srw_bend_search(assoc, req, sr->u.request, res->u.response, + &http_code); soap_package = odr_malloc(o, sizeof(*soap_package)); soap_package->which = Z_SOAP_generic; @@ -846,34 +861,39 @@ static void process_http_request(association *assoc, request *req) soap_package->ns = "SRU"; - p = z_get_HTTP_Response(o, 200); - hres = p->u.HTTP_Response; - - ret = z_soap_codec_enc(assoc->encode, &soap_package, - &hres->content_buf, &hres->content_len, - soap_handlers, charset); - if (!charset) - z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/xml"); - else - { - char ctype[60]; - strcpy(ctype, "text/xml; charset="); - strcat(ctype, charset); - z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype); - } + p = z_get_HTTP_Response(o, http_code); + if (http_code == 200) + { + hres = p->u.HTTP_Response; + + ret = z_soap_codec_enc(assoc->encode, &soap_package, + &hres->content_buf, &hres->content_len, + soap_handlers, charset); + if (!charset) + z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/xml"); + else + { + char ctype[60]; + strcpy(ctype, "text/xml; charset="); + strcat(ctype, charset); + z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype); + } + } } else if (p1 && !strcmp(operation, "explain")) { Z_SRW_PDU *res = yaz_srw_get(o, Z_SRW_explain_response); Z_SRW_PDU *sr = yaz_srw_get(o, Z_SRW_explain_request); + int http_code = 200; + sr->u.explain_request->database = db; sr->u.explain_request->recordPacking = yaz_uri_val(p1, "recordPacking", o); if (!sr->u.explain_request->recordPacking) sr->u.explain_request->recordPacking = "xml"; srw_bend_explain(assoc, req, sr->u.explain_request, - res->u.explain_response); + res->u.explain_response, &http_code); if (res->u.explain_response->record.recordData_buf) { @@ -1061,31 +1081,20 @@ static void process_http_request(association *assoc, request *req) sr->u.request->database = db; srw_bend_search(assoc, req, sr->u.request, - res->u.response); + res->u.response, &http_code); soap_package->u.generic->p = res; - http_code = 200; } else if (sr->which == Z_SRW_explain_request) { Z_SRW_PDU *res = yaz_srw_get(assoc->encode, Z_SRW_explain_response); - - if (!sr->u.explain_request->database) - sr->u.explain_request->database = db; + sr->u.explain_request->database = db; srw_bend_explain(assoc, req, sr->u.explain_request, - res->u.explain_response); - if (!res->u.explain_response->record.recordData_buf) - { - z_soap_error(assoc->encode, soap_package, - "SOAP-ENV:Client", "Explain Not Supported", 0); - } - else - { + res->u.explain_response, &http_code); + if (http_code == 200) soap_package->u.generic->p = res; - http_code = 200; - } } else { @@ -1094,21 +1103,26 @@ static void process_http_request(association *assoc, request *req) } } #endif - p = z_get_HTTP_Response(o, 200); - hres = p->u.HTTP_Response; - ret = z_soap_codec_enc(assoc->encode, &soap_package, - &hres->content_buf, &hres->content_len, - soap_handlers, charset); - hres->code = http_code; - if (!charset) - z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/xml"); - else - { - char ctype[60]; - strcpy(ctype, "text/xml; charset="); - strcat(ctype, charset); - z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype); - } + if (http_code == 200 || http_code == 500) + { + p = z_get_HTTP_Response(o, 200); + hres = p->u.HTTP_Response; + ret = z_soap_codec_enc(assoc->encode, &soap_package, + &hres->content_buf, &hres->content_len, + soap_handlers, charset); + hres->code = http_code; + if (!charset) + z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/xml"); + else + { + char ctype[60]; + strcpy(ctype, "text/xml; charset="); + strcat(ctype, charset); + z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype); + } + } + else + p = z_get_HTTP_Response(o, http_code); } if (!p) /* still no response ? */ p = z_get_HTTP_Response(o, 500); @@ -1539,7 +1553,7 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) assoc->init->implementation_name, odr_prepend(assoc->encode, "GFS", resp->implementationName)); - version = odr_strdup(assoc->encode, "$Revision: 1.8 $"); + version = odr_strdup(assoc->encode, "$Revision: 1.9 $"); if (strlen(version) > 10) /* check for unexpanded CVS strings */ version[strlen(version)-2] = '\0'; resp->implementationVersion = odr_prepend(assoc->encode, diff --git a/src/srw.c b/src/srw.c index 5627335..d4970b2 100644 --- a/src/srw.c +++ b/src/srw.c @@ -2,7 +2,7 @@ * Copyright (c) 2002-2003, Index Data. * See the file LICENSE for details. * - * $Id: srw.c,v 1.6 2003-12-22 22:47:20 adam Exp $ + * $Id: srw.c,v 1.7 2003-12-29 14:54:33 adam Exp $ */ #include @@ -314,6 +314,73 @@ static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs, return 0; } +static int yaz_srw_term(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm *term, + void *client_data, const char *ns) +{ + if (o->direction == ODR_DECODE) + { + xmlNodePtr ptr; + term->value = 0; + term->numberOfRecords = 0; + term->displayTerm = 0; + for (ptr = pptr->children; ptr; ptr = ptr->next) + { + char *spack = 0; + + if (match_xsd_string(ptr, "value", o, &term->value)) + ; + else if (match_xsd_integer(ptr, "numberOfRecords", o, + &term->numberOfRecords)) + ; + else if (match_xsd_string(ptr, "displayTerm", o, + &term->displayTerm)) + ; + } + } + else if (o->direction == ODR_ENCODE) + { + xmlNodePtr ptr = pptr; + add_xsd_string(ptr, "value", term->value); + add_xsd_integer(ptr, "value", term->numberOfRecords); + add_xsd_string(ptr, "displayTerm", term->displayTerm); + } +} + +static int yaz_srw_terms(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm **terms, + int *num, void *client_data, const char *ns) +{ + if (o->direction == ODR_DECODE) + { + int i; + xmlNodePtr ptr; + *num = 0; + for (ptr = pptr->children; ptr; ptr = ptr->next) + { + if (ptr->type == XML_ELEMENT_NODE && + !strcmp(ptr->name, "term")) + (*num)++; + } + if (!*num) + return 1; + *terms = odr_malloc(o, *num * sizeof(**terms)); + for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++) + { + if (ptr->type == XML_ELEMENT_NODE && + !strcmp(ptr->name, "term")) + yaz_srw_term(o, ptr, (*terms)+i, client_data, ns); + } + } + else if (o->direction == ODR_ENCODE) + { + int i; + for (i = 0; i < *num; i++) + { + xmlNodePtr rptr = xmlNewChild(pptr, 0, "term", 0); + yaz_srw_term(o, rptr, (*terms)+i, client_data, ns); + } + } + return 0; +} int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, void *client_data, const char *ns) @@ -350,6 +417,9 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, req->maximumRecords = 0; req->recordSchema = 0; req->recordPacking = 0; + req->recordXPath = 0; + req->resultSetTTL = 0; + req->stylesheet = 0; req->database = 0; for (; ptr; ptr = ptr->next) @@ -372,15 +442,24 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if (match_xsd_string(ptr, "recordPacking", o, &req->recordPacking)) ; + else if (match_xsd_string(ptr, "recordXPath", o, + &req->recordXPath)) + ; else if (match_xsd_integer(ptr, "startRecord", o, &req->startRecord)) ; else if (match_xsd_integer(ptr, "maximumRecords", o, &req->maximumRecords)) ; + else if (match_xsd_string(ptr, "stylesheet", o, + &req->stylesheet)) + ; else if (match_xsd_string(ptr, "database", o, &req->database)) ; + else if (match_xsd_string(ptr, "resultSetTTL", o, + &req->database)) + ; else if (match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; @@ -442,7 +521,10 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, req->database = 0; for (; ptr; ptr = ptr->next) { - if (match_xsd_string(ptr, "recordPacking", o, + if (match_xsd_string(ptr, "database", o, + &req->database)) + ; + else if (match_xsd_string(ptr, "recordPacking", o, &req->recordPacking)) ; else if (match_xsd_string(ptr, "version", o, @@ -457,7 +539,9 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, (*p)->which = Z_SRW_explain_response; res = (*p)->u.explain_response = odr_malloc(o, sizeof(*res)); - + res->diagnostics = 0; + res->num_diagnostics = 0; + for (; ptr; ptr = ptr->next) { if (match_element(ptr, "record")) @@ -465,6 +549,73 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if (match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; + else if (match_element(ptr, "diagnostics")) + yaz_srw_diagnostics(o, ptr, &res->diagnostics, + &res->num_diagnostics, + client_data, ns); + ; + } + } + else if (!strcmp(method->name, "scanRequest")) + { + Z_SRW_scanRequest *req; + xmlNodePtr ptr = method->children; + + (*p)->which = Z_SRW_scan_request; + req = (*p)->u.scan_request = odr_malloc(o, sizeof(*req)); + req->database = 0; + req->scanClause = 0; + req->stylesheet = 0; + req->responsePosition = 0; + req->maximumTerms = 0; + + for (; ptr; ptr = ptr->next) + { + if (match_xsd_string(ptr, "version", o, + &(*p)->srw_version)) + ; + else if (match_xsd_string(ptr, "scanClause", o, + &req->scanClause)) + ; + else if (match_xsd_string(ptr, "database", o, + &req->database)) + ; + else if (match_xsd_string(ptr, "stylesheet", o, + &req->stylesheet)) + ; + else if (match_xsd_integer(ptr, "responsePosition", o, + &req->responsePosition)) + ; + else if (match_xsd_integer(ptr, "maximumTerms", o, + &req->maximumTerms)) + ; + } + } + else if (!strcmp(method->name, "scanResponse")) + { + Z_SRW_scanResponse *res; + xmlNodePtr ptr = method->children; + + (*p)->which = Z_SRW_scan_response; + res = (*p)->u.scan_response = odr_malloc(o, sizeof(*res)); + res->terms = 0; + res->num_terms = 0; + res->diagnostics = 0; + res->num_diagnostics = 0; + + for (; ptr; ptr = ptr->next) + { + if (match_element(ptr, "terms")) + yaz_srw_terms(o, ptr, &res->terms, + &res->num_terms, client_data, + ns); + else if (match_element(ptr, "diagnostics")) + yaz_srw_diagnostics(o, ptr, &res->diagnostics, + &res->num_diagnostics, + client_data, ns); + else if (match_xsd_string(ptr, "version", o, + &(*p)->srw_version)) + ; } } else @@ -515,7 +666,10 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, add_xsd_integer(ptr, "maximumRecords", req->maximumRecords); add_xsd_string(ptr, "recordSchema", req->recordSchema); add_xsd_string(ptr, "recordPacking", req->recordPacking); + add_xsd_string(ptr, "recordXPath", req->recordXPath); add_xsd_string(ptr, "database", req->database); + add_xsd_integer(ptr, "resultSetTTL", req->resultSetTTL); + add_xsd_string(ptr, "stylesheet", req->stylesheet); } else if ((*p)->which == Z_SRW_searchRetrieve_response) { @@ -550,8 +704,7 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, ns_srw = xmlNewNs(ptr, ns, "zs"); xmlSetNs(ptr, ns_srw); - if ((*p)->srw_version) - add_xsd_string(ptr, "version", (*p)->srw_version); + add_xsd_string(ptr, "version", (*p)->srw_version); } else if ((*p)->which == Z_SRW_explain_response) { @@ -560,10 +713,53 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, ns_srw = xmlNewNs(ptr, ns, "zs"); xmlSetNs(ptr, ns_srw); - if ((*p)->srw_version) - add_xsd_string(ptr, "version", (*p)->srw_version); - ptr = xmlNewChild(ptr, 0, "record", 0); - yaz_srw_record(o, ptr, &res->record, client_data, ns); + add_xsd_string(ptr, "version", (*p)->srw_version); + if (1) + { + xmlNodePtr ptr1 = xmlNewChild(ptr, 0, "record", 0); + yaz_srw_record(o, ptr1, &res->record, client_data, ns); + } + if (res->num_diagnostics) + { + xmlNodePtr rptr = xmlNewChild(ptr, 0, "diagnostics", 0); + yaz_srw_diagnostics(o, rptr, &res->diagnostics, + &res->num_diagnostics, client_data, ns); + } + } + else if ((*p)->which == Z_SRW_scan_request) + { + Z_SRW_scanRequest *req = (*p)->u.scan_request; + xmlNodePtr ptr = xmlNewChild(pptr, 0, "scanRequest", 0); + ns_srw = xmlNewNs(ptr, ns, "zs"); + xmlSetNs(ptr, ns_srw); + + add_xsd_string(ptr, "version", (*p)->srw_version); + add_xsd_string(ptr, "scanClause", req->scanClause); + add_xsd_integer(ptr, "responsePosition", req->responsePosition); + add_xsd_integer(ptr, "maximumTerms", req->maximumTerms); + add_xsd_string(ptr, "stylesheet", req->stylesheet); + } + else if ((*p)->which == Z_SRW_scan_response) + { + Z_SRW_scanResponse *res = (*p)->u.scan_response; + xmlNodePtr ptr = xmlNewChild(pptr, 0, "scanResponse", 0); + ns_srw = xmlNewNs(ptr, ns, "zs"); + xmlSetNs(ptr, ns_srw); + + add_xsd_string(ptr, "version", (*p)->srw_version); + + if (res->num_terms) + { + xmlNodePtr rptr = xmlNewChild(ptr, 0, "terms", 0); + yaz_srw_terms(o, rptr, &res->terms, &res->num_terms, + client_data, ns); + } + if (res->num_diagnostics) + { + xmlNodePtr rptr = xmlNewChild(ptr, 0, "diagnostics", 0); + yaz_srw_diagnostics(o, rptr, &res->diagnostics, + &res->num_diagnostics, client_data, ns); + } } else return -1; @@ -592,6 +788,8 @@ Z_SRW_PDU *yaz_srw_get(ODR o, int which) sr->u.request->recordSchema = 0; sr->u.request->recordPacking = 0; sr->u.request->database = 0; + sr->u.request->resultSetTTL = 0; + sr->u.request->stylesheet = 0; break; case Z_SRW_searchRetrieve_response: sr->u.response = (Z_SRW_searchRetrieveResponse *) @@ -618,7 +816,10 @@ Z_SRW_PDU *yaz_srw_get(ODR o, int which) sr->u.explain_response->record.recordData_len = 0; sr->u.explain_response->record.recordSchema = 0; sr->u.explain_response->record.recordPosition = 0; - sr->u.explain_response->record.recordPacking = Z_SRW_recordPacking_string; + sr->u.explain_response->record.recordPacking = + Z_SRW_recordPacking_string; + sr->u.explain_response->diagnostics = 0; + sr->u.explain_response->num_diagnostics = 0; } return sr; } diff --git a/ztest/ztest.c b/ztest/ztest.c index 2574a8c..4795ee6 100644 --- a/ztest/ztest.c +++ b/ztest/ztest.c @@ -2,7 +2,7 @@ * Copyright (c) 1995-2003, Index Data. * See the file LICENSE for details. * - * $Id: ztest.c,v 1.58 2003-09-02 12:12:13 adam Exp $ + * $Id: ztest.c,v 1.59 2003-12-29 14:54:33 adam Exp $ */ /* @@ -602,12 +602,15 @@ int ztest_scan(void *handle, bend_scan_rr *q) static int ztest_explain(void *handle, bend_explain_rr *rr) { - rr->explain_buf = "\n" - "\t\n" - "\t\tlocalhost\n" - "\t\t210\n" - "\t\n" - "\n"; + if (rr->database && !strcmp(rr->database, "Default")) + { + rr->explain_buf = "\n" + "\t\n" + "\t\tlocalhost\n" + "\t\t210\n" + "\t\n" + "\n"; + } return 0; }