ZOOM option: step. More verbose GFS SRW server display
[yaz-moved-to-github.git] / zutil / zoom-c.c
index 2f636e2..578c57f 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2000-2003, Index Data
  * See the file LICENSE for details.
  *
- * $Id: zoom-c.c,v 1.29 2003-03-11 11:09:17 adam Exp $
+ * $Id: zoom-c.c,v 1.35 2003-05-20 08:22:33 adam Exp $
  *
  * ZOOM layer for C, connections, result sets, queries.
  */
@@ -68,7 +68,10 @@ static ZOOM_Event ZOOM_connection_get_event(ZOOM_connection c)
 {
     ZOOM_Event event = c->m_queue_front;
     if (!event)
+    {
+        c->last_event = ZOOM_EVENT_NONE;
        return 0;
+    }
     assert (c->m_queue_back);
     c->m_queue_front = event->prev;
     if (c->m_queue_front)
@@ -106,11 +109,13 @@ static void set_dset_error (ZOOM_connection c, int error,
                 addinfo2 ? addinfo2 : "");
 }
 
+#if HAVE_XML2
 static void set_HTTP_error (ZOOM_connection c, int error,
                             const char *addinfo, const char *addinfo2)
 {
     set_dset_error(c, error, "HTTP", addinfo, addinfo2);
 }
+#endif
 
 static void set_ZOOM_error (ZOOM_connection c, int error,
                            const char *addinfo)
@@ -172,6 +177,7 @@ void ZOOM_connection_remove_task (ZOOM_connection c)
        switch (task->which)
        {
        case ZOOM_TASK_SEARCH:
+
            ZOOM_resultset_destroy (task->u.search.resultset);
            break;
        case ZOOM_TASK_RETRIEVE:
@@ -502,6 +508,7 @@ ZOOM_resultset ZOOM_resultset_create ()
     r->setname = 0;
     r->schema = 0;
     r->count = 0;
+    r->step = 0;
     r->record_cache = 0;
     r->r_sort_spec = 0;
     r->query = 0;
@@ -537,6 +544,7 @@ ZOOM_connection_search(ZOOM_connection c, ZOOM_query q)
 
     r->start = ZOOM_options_get_int(r->options, "start", 0);
     r->count = ZOOM_options_get_int(r->options, "count", 0);
+    r->step = ZOOM_options_get_int(r->options, "step", 0);
     r->piggyback = ZOOM_options_get_bool (r->options, "piggyback", 1);
     cp = ZOOM_options_get (r->options, "setname");
     if (cp)
@@ -722,7 +730,9 @@ static zoom_ret do_connect (ZOOM_connection c)
         c->proto = PROTO_HTTP;
         cs_get_host_args(c->host_port, &path);
         xfree(c->path);
-        c->path = xstrdup(path);
+        c->path = xmalloc(strlen(path)+2);
+        c->path[0] = '/';
+        strcpy (c->path+1, path);
 #else
         set_ZOOM_error(c, ZOOM_ERROR_UNSUPPORTED_PROTOCOL, "SRW");
         do_close(c);
@@ -989,6 +999,29 @@ static zoom_ret send_srw (ZOOM_connection c, Z_SRW_PDU *sr)
     gdu = z_get_HTTP_Request(c->odr_out);
     gdu->u.HTTP_Request->path = c->path;
 
+    if (c->host_port)
+    {
+        const char *cp0 = strstr(c->host_port, "://");
+        const char *cp1 = 0;
+        if (cp0)
+            cp0 = cp0+3;
+        else
+            cp0 = c->host_port;
+
+        cp1 = strchr(cp0, '/');
+        if (!cp1)
+            cp1 = cp0+strlen(cp0);
+
+        if (cp0 && cp1)
+        {
+            char *h = odr_malloc(c->odr_out, cp1 - cp0 + 1);
+            memcpy (h, cp0, cp1 - cp0);
+            h[cp1-cp0] = '\0';
+            z_HTTP_header_add(c->odr_out, &gdu->u.HTTP_Request->headers,
+                              "host", h);
+        }
+    }
+
     strcpy(ctype, "text/xml");
     if (c->charset && strlen(c->charset) < 20)
     {
@@ -1030,6 +1063,7 @@ static zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
     int i;
     ZOOM_resultset resultset = 0;
     Z_SRW_PDU *sr = 0;
+    const char *recordPacking = 0;
 
     if (c->error)                  /* don't continue on error */
        return zoom_complete;
@@ -1085,10 +1119,15 @@ static zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
         return zoom_complete;
     }
     sr->u.request->startRecord = odr_intdup (c->odr_out, resultset->start + 1);
-    sr->u.request->maximumRecords = odr_intdup (c->odr_out, resultset->count);
+    sr->u.request->maximumRecords = odr_intdup (
+        c->odr_out, resultset->step>0 ? resultset->step : resultset->count);
     sr->u.request->recordSchema = resultset->schema;
 
+    recordPacking = ZOOM_resultset_option_get (resultset, "recordPacking");
+
+    if (recordPacking)
+        sr->u.request->recordPacking = odr_strdup(c->odr_out, recordPacking);
+    
     return send_srw(c, sr);
 }
 #else
@@ -1155,7 +1194,7 @@ static zoom_ret ZOOM_connection_send_search (ZOOM_connection c)
        /* Regular piggyback - do it unless we're going to do sort */
        *search_req->largeSetLowerBound = 2000000000;
        *search_req->smallSetUpperBound = 0;
-       *search_req->mediumSetPresentNumber = r->count;
+       *search_req->mediumSetPresentNumber = r->step>0 ? r->step : r->count;
        smallSetElementSetName = 0;
     }
     else
@@ -1277,8 +1316,14 @@ ZOOM_resultset_record_immediate (ZOOM_resultset s,size_t pos)
 ZOOM_API(ZOOM_record)
 ZOOM_resultset_record (ZOOM_resultset r, size_t pos)
 {
-    ZOOM_resultset_retrieve (r, 1, pos, 1);
-    return ZOOM_resultset_record_immediate (r, pos);
+    ZOOM_record rec = ZOOM_resultset_record_immediate(r, pos);
+
+    if (!rec)
+    {
+        ZOOM_resultset_retrieve (r, 1, pos, 1);
+        rec = ZOOM_resultset_record_immediate (r, pos);
+    }
+    return rec;
 }
 
 ZOOM_API(void)
@@ -1438,6 +1483,11 @@ ZOOM_record_get (ZOOM_record rec, const char *type, int *len)
             if (len) *len = 5;
             return "GRS-1";
         }
+       else if (r->which == Z_External_OPAC)
+        {
+            if (len) *len = 4;
+            return "OPAC";
+        }
        return 0;
     }
     else if (!strcmp (type, "raw"))
@@ -1491,6 +1541,9 @@ static void record_cache_add (ZOOM_resultset r, Z_NamePlusRecord *npr,
     const char *syntax = 
         ZOOM_resultset_option_get (r, "preferredRecordSyntax");
     
+    ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_RECV_RECORD);
+    ZOOM_connection_put_event(r->connection, event);
+
     for (rc = r->record_cache; rc; rc = rc->next)
     {
        if (pos == rc->pos)
@@ -1630,11 +1683,15 @@ static void handle_present_response (ZOOM_connection c, Z_PresentResponse *pr)
 static void handle_search_response (ZOOM_connection c, Z_SearchResponse *sr)
 {
     ZOOM_resultset resultset;
-
+    ZOOM_Event event;
+    
     yaz_log (LOG_DEBUG, "got search response");
-
+    
     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;
 
@@ -1760,7 +1817,8 @@ static zoom_ret send_present (ZOOM_connection c)
     resultset->start += i;
     resultset->count -= i;
     *req->resultSetStartPoint = resultset->start + 1;
-    *req->numberOfRecordsRequested = resultset->count;
+    *req->numberOfRecordsRequested = resultset->step>0 ?
+        resultset->step : resultset->count;
     assert (*req->numberOfRecordsRequested > 0);
 
     if (syntax && *syntax)
@@ -2081,21 +2139,26 @@ static Z_ItemOrder *encode_item_order(ZOOM_package p)
     req->u.esRequest->notToKeep = (Z_IOOriginPartNotToKeep *)
         odr_malloc(p->odr_out,sizeof(Z_IOOriginPartNotToKeep));
        
-    req->u.esRequest->notToKeep->resultSetItem = (Z_IOResultSetItem *)
-        odr_malloc(p->odr_out, sizeof(Z_IOResultSetItem));
-
     str = ZOOM_options_get(p->options, "itemorder-setname");
     if (!str)
         str = "default";
-    req->u.esRequest->notToKeep->resultSetItem->resultSetId =
-        nmem_strdup (p->odr_out->mem, str);
-    req->u.esRequest->notToKeep->resultSetItem->item =
-        (int *) odr_malloc(p->odr_out, sizeof(int));
+
+    if (!*str) 
+        req->u.esRequest->notToKeep->resultSetItem = 0;
+    else
+    {
+        req->u.esRequest->notToKeep->resultSetItem = (Z_IOResultSetItem *)
+           odr_malloc(p->odr_out, sizeof(Z_IOResultSetItem));
+
+        req->u.esRequest->notToKeep->resultSetItem->resultSetId =
+           nmem_strdup (p->odr_out->mem, str);
+        req->u.esRequest->notToKeep->resultSetItem->item =
+            (int *) odr_malloc(p->odr_out, sizeof(int));
        
-    str = ZOOM_options_get(p->options, "itemorder-item");
-    *req->u.esRequest->notToKeep->resultSetItem->item =
-        (str ? atoi(str) : 1);
-    
+        str = ZOOM_options_get(p->options, "itemorder-item");
+        *req->u.esRequest->notToKeep->resultSetItem->item =
+            (str ? atoi(str) : 1);
+    }
     req->u.esRequest->notToKeep->itemRequest = encode_ill_request(p);
     
     return req;
@@ -2409,6 +2472,7 @@ static void handle_srw_response(ZOOM_connection c,
     ZOOM_resultset resultset = 0;
     int i;
     NMEM nmem;
+    ZOOM_Event event;
 
     if (!c->tasks)
         return;
@@ -2420,6 +2484,9 @@ static void handle_srw_response(ZOOM_connection c,
     else
        return ;
 
+    event = ZOOM_Event_create(ZOOM_EVENT_RECV_SEARCH);
+    ZOOM_connection_put_event(c, event);
+
     resultset->size = 0;
 
     yaz_log(LOG_DEBUG, "got SRW response OK");
@@ -2568,6 +2635,7 @@ static int do_read (ZOOM_connection c)
     {
         Z_GDU *gdu;
         ZOOM_Event event;
+
        odr_reset (c->odr_in);
        odr_setbuf (c->odr_in, c->buf_in, r, 0);
         event = ZOOM_Event_create (ZOOM_EVENT_RECV_APDU);