Implemented a way to perform scan in a result set using Z39.50. This
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 30 May 2007 08:12:16 +0000 (08:12 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 30 May 2007 08:12:16 +0000 (08:12 +0000)
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
client/client.c
doc/yaz-client-commands.xml
include/yaz/backend.h
src/oid.csv
src/seshigh.c

diff --git a/NEWS b/NEWS
index 0a5e380..aec80d1 100644 (file)
--- 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
index 619f963..9b050de 100644 (file)
@@ -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 = &num;
     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, "<setname>",NULL,0,NULL},
     {"base", cmd_base, "<base-name>",NULL,0,NULL},
     {"show", cmd_show, "<rec#>['+'<#recs>['+'<setname>]]",NULL,0,NULL},
+    {"setscan", cmd_setscan, "<term>",NULL,0,NULL},
     {"scan", cmd_scan, "<term>",NULL,0,NULL},
     {"scanstep", cmd_scanstep, "<size>",NULL,0,NULL},
     {"scanpos", cmd_scanpos, "<size>",NULL,0,NULL},
index 6aabc7f..93627f0 100644 (file)
@@ -1,5 +1,5 @@
 <!-- 
-   $Id: yaz-client-commands.xml,v 1.17 2007-01-24 09:54:04 adam Exp $
+   $Id: yaz-client-commands.xml,v 1.18 2007-05-30 08:12:17 adam Exp $
    Commands for YAZ client.
    Included in both manual and man page for yaz-client.
 -->
   </listitem>
  </varlistentry>
  <varlistentry><term>
+   <literal>setscan</literal> <replaceable>set</replaceable> <replaceable>term</replaceable>
+  </term>
+  <listitem>
+   <simpara>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.
+   </simpara>
+  </listitem>
+ </varlistentry>
+ <varlistentry><term>
    <literal>scanpos</literal> <replaceable>pos</replaceable>
   </term>
   <listitem>
index dfa7f76..b508627 100644 (file)
@@ -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 */
index 1aeb30c..94a4706 100644 (file)
@@ -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"
index 1c4040c..11ffa72 100644 (file)
@@ -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) );