From f60c0db8c4379047cdd75e2be50549abc0a1c74a Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 30 May 2007 08:12:16 +0000 Subject: [PATCH] Implemented a way to perform scan in a result set using Z39.50. This is achieved by attaching the result set name in the characterInfo (type InternationalString) of OtherInformation in the Scan Request PDU. The result set is identified in the otherinformation by the new OID: USERINFO, Z3950_PREFIX.10.1000.81.4, "Scan-Set This allows for scan in result set and faceted search . Zebra did some of this in the APT term using attribute type 8 and value being result set. Using the OtherInformation approach for this is cleaner and easier to work with in proxies and the like. This facility can be used in yaz-client using new command setscan which takes a result set as first --- NEWS | 12 ++++++++++++ client/client.c | 36 +++++++++++++++++++++++++++++++----- doc/yaz-client-commands.xml | 11 ++++++++++- include/yaz/backend.h | 3 ++- src/oid.csv | 3 ++- src/seshigh.c | 34 +++++++++++++++++----------------- 6 files changed, 74 insertions(+), 25 deletions(-) diff --git a/NEWS b/NEWS index 0a5e380..aec80d1 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,15 @@ +Implemented a way to perform scan in a result set using Z39.50. This +is achieved by attaching the result set name in the characterInfo +(type InternationalString) of OtherInformation in the Scan Request PDU. +The result set is identified in the otherinformation by the new OID: + USERINFO, Z3950_PREFIX.10.1000.81.4, "Scan-Set +This allows for scan in result set and faceted search . Zebra did some +of this in the APT term using attribute type 8 and value being result +set. Using the OtherInformation approach for this is cleaner and easier +to work with in proxies and the like. This facility can be used in +yaz-client using new command setscan which takes a result set as first +argument, start position (APT) as second. + Changed decoding of SRU XML packed records to deal with servers that have recordData with XML data with multiple root nodes. Also make comparison for recordPacking case insensitive. Again, one server diff --git a/client/client.c b/client/client.c index 619f963..9b050de 100644 --- a/client/client.c +++ b/client/client.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2007, Index Data ApS * See the file LICENSE for details. * - * $Id: client.c,v 1.339 2007-05-23 11:54:46 adam Exp $ + * $Id: client.c,v 1.340 2007-05-30 08:12:16 adam Exp $ */ /** \file client.c * \brief yaz-client program @@ -2853,7 +2853,8 @@ int cmd_cancel_find(const char *arg) { return fres; } -int send_scanrequest(const char *query, int pp, int num, const char *term) +int send_scanrequest(const char *set, const char *query, + int pp, int num, const char *term) { Z_APDU *apdu = zget_APDU(out, Z_APDU_scanRequest); Z_ScanRequest *req = apdu->u.scanRequest; @@ -2918,6 +2919,11 @@ int send_scanrequest(const char *query, int pp, int num, const char *term) req->numberOfTermsRequested = # req->preferredPositionInResponse = &pp; req->stepSize = odr_intdup(out, scan_stepSize); + + if (set) + yaz_oi_set_string_oid(&req->otherInfo, out, + yaz_oid_userinfo_scan_set, 1, set); + send_apdu(apdu); return 2; } @@ -3098,7 +3104,7 @@ int cmd_scansize(const char *arg) return 0; } -int cmd_scan(const char *arg) +static int cmd_scan_common(const char *set, const char *arg) { if (protocol == PROTO_HTTP) { @@ -3142,18 +3148,37 @@ int cmd_scan(const char *arg) if (*arg) { strcpy (last_scan_query, arg); - if (send_scanrequest(arg, scan_position, scan_size, 0) < 0) + if (send_scanrequest(set, arg, + scan_position, scan_size, 0) < 0) return 0; } else { - if (send_scanrequest(last_scan_query, 1, scan_size, last_scan_line) < 0) + if (send_scanrequest(set, last_scan_query, + 1, scan_size, last_scan_line) < 0) return 0; } return 2; } } +int cmd_scan(const char *arg) +{ + return cmd_scan_common(0, arg); +} + +int cmd_setscan(const char *arg) +{ + char setstring[100]; + int nor; + if (sscanf(arg, "%99s%n", setstring, &nor) < 1) + { + printf("missing set for setscan\n"); + return 0; + } + return cmd_scan_common(setstring, arg + nor); +} + int cmd_schema(const char *arg) { xfree(record_schema); @@ -4328,6 +4353,7 @@ static struct { {"delete", cmd_delete, "",NULL,0,NULL}, {"base", cmd_base, "",NULL,0,NULL}, {"show", cmd_show, "['+'<#recs>['+']]",NULL,0,NULL}, + {"setscan", cmd_setscan, "",NULL,0,NULL}, {"scan", cmd_scan, "",NULL,0,NULL}, {"scanstep", cmd_scanstep, "",NULL,0,NULL}, {"scanpos", cmd_scanpos, "",NULL,0,NULL}, diff --git a/doc/yaz-client-commands.xml b/doc/yaz-client-commands.xml index 6aabc7f..93627f0 100644 --- a/doc/yaz-client-commands.xml +++ b/doc/yaz-client-commands.xml @@ -1,5 +1,5 @@ @@ -93,6 +93,15 @@ + setscan set term + + + Scans database index for a term within a result set. This + is similar to the scan command but has a result set as its first argument. + + + + scanpos pos diff --git a/include/yaz/backend.h b/include/yaz/backend.h index dfa7f76..b508627 100644 --- a/include/yaz/backend.h +++ b/include/yaz/backend.h @@ -24,7 +24,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: backend.h,v 1.47 2007-05-08 08:22:35 adam Exp $ */ +/* $Id: backend.h,v 1.48 2007-05-30 08:12:17 adam Exp $ */ /** * \file backend.h @@ -147,6 +147,7 @@ typedef struct bend_scan_rr { int errcode; char *errstring; char *scanClause; /* CQL scan clause */ + char *setname; /* Scan in result set (NULL if omitted) */ } bend_scan_rr; /** \brief Information for SRU record update handler */ diff --git a/src/oid.csv b/src/oid.csv index 1aeb30c..94a4706 100644 --- a/src/oid.csv +++ b/src/oid.csv @@ -1,4 +1,4 @@ -"$Id: oid.csv,v 1.2 2007-04-16 21:53:09 adam Exp $" +"$Id: oid.csv,v 1.3 2007-05-30 08:12:17 adam Exp $" TRANSYN, 2.1.1, "BER" TRANSYN, 1.0.2709.1.1, "ISO2709" GENERAL, 1.0.10161.2.1, "ISOILL-1" @@ -107,6 +107,7 @@ USERINFO, Z3950_PREFIX.10.6, "DateTime" USERINFO, Z3950_PREFIX.10.1000.81.1, "Proxy" USERINFO, Z3950_PREFIX.10.1000.81.2, "Cookie" USERINFO, Z3950_PREFIX.10.1000.81.3, "Client-IP" +USERINFO, Z3950_PREFIX.10.1000.81.4, "Scan-Set" ELEMSPEC, Z3950_PREFIX.11.1, "Espec-1" VARSET, Z3950_PREFIX.12.1, "Variant-1" SCHEMA, Z3950_PREFIX.13.1, "WAIS-schema" diff --git a/src/seshigh.c b/src/seshigh.c index 1c4040c..11ffa72 100644 --- a/src/seshigh.c +++ b/src/seshigh.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2007, Index Data ApS * See the file LICENSE for details. * - * $Id: seshigh.c,v 1.119 2007-05-08 08:22:36 adam Exp $ + * $Id: seshigh.c,v 1.120 2007-05-30 08:12:17 adam Exp $ */ /** * \file seshigh.c @@ -1264,6 +1264,7 @@ static void srw_bend_scan(association *assoc, request *req, bsrr->print = assoc->print; bsrr->step_size = odr_intdup(assoc->decode, 0); bsrr->entries = 0; + bsrr->setname = 0; if (bsrr->num_entries > 0) { @@ -2358,7 +2359,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.119 $"); + version = odr_strdup(assoc->encode, "$Revision: 1.120 $"); if (strlen(version) > 10) /* check for unexpanded CVS strings */ version[strlen(version)-2] = '\0'; resp->implementationVersion = odr_prepend(assoc->encode, @@ -3014,6 +3015,8 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb, int *fd) bsrr->stream = assoc->encode; bsrr->print = assoc->print; bsrr->step_size = res->stepSize; + bsrr->setname = yaz_oi_get_string_oid(&req->otherInfo, + yaz_oid_userinfo_scan_set, 1, 0); bsrr->entries = 0; /* For YAZ 2.0 and earlier it was the backend handler that initialized entries (member display_term did not exist) @@ -3127,35 +3130,32 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb, int *fd) int i; WRBUF wr = wrbuf_alloc(); wrbuf_printf(wr, "Scan "); - for (i = 0 ; i < req->num_databaseNames; i++){ + for (i = 0 ; i < req->num_databaseNames; i++) + { if (i) wrbuf_printf(wr, "+"); wrbuf_printf(wr, req->databaseNames[i]); } + wrbuf_printf(wr, " "); - if (bsrr->errcode){ + if (bsrr->errcode) wr_diag(wr, bsrr->errcode, bsrr->errstring); - wrbuf_printf(wr, " "); - } - else - wrbuf_printf(wr, "OK "); - /* else if (*res->scanStatus == Z_Scan_success) */ - /* wrbuf_printf(wr, "OK "); */ - /* else */ - /* wrbuf_printf(wr, "Partial "); */ - - if (*res->numberOfEntriesReturned) - wrbuf_printf(wr, "%d - ", *res->numberOfEntriesReturned); else - wrbuf_printf(wr, "0 - "); + wrbuf_printf(wr, "OK"); - wrbuf_printf(wr, "%d+%d+%d ", + wrbuf_printf(wr, " %d - %d+%d+%d", + res->numberOfEntriesReturned ? + *res->numberOfEntriesReturned : 0, (req->preferredPositionInResponse ? *req->preferredPositionInResponse : 1), *req->numberOfTermsRequested, (res->stepSize ? *res->stepSize : 1)); + + if (bsrr->setname) + wrbuf_printf(wr, "+%s", bsrr->setname); + wrbuf_printf(wr, " "); yaz_scan_to_wrbuf(wr, req->termListAndStartPoint, bsrr->attributeset); yaz_log(log_request, "%s", wrbuf_cstr(wr) ); -- 1.7.10.4