Use elementSetName and syntax in record lookup in cache
[yaz-moved-to-github.git] / zoom / zoom-c.c
index 1d22eae..8364312 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: zoom-c.c,v 1.36 2002-07-11 10:39:05 adam Exp $
+ * $Id: zoom-c.c,v 1.40 2002-08-20 08:19:40 adam Exp $
  *
  * ZOOM layer for C, connections, result sets, queries.
  */
@@ -151,9 +151,7 @@ void ZOOM_connection_remove_tasks (ZOOM_connection c)
        ZOOM_connection_remove_task(c);
 }
 
-static ZOOM_record record_cache_lookup (ZOOM_resultset r,
-                                        int pos,
-                                        const char *elementSetName);
+static ZOOM_record record_cache_lookup (ZOOM_resultset r, int pos);
 
 ZOOM_API(ZOOM_connection)
 ZOOM_connection_create (ZOOM_options options)
@@ -1001,7 +999,7 @@ ZOOM_record_clone (ZOOM_record srec)
 ZOOM_API(ZOOM_record)
 ZOOM_resultset_record_immediate (ZOOM_resultset s,size_t pos)
 {
-    return record_cache_lookup (s, pos, 0);
+    return record_cache_lookup (s, pos);
 }
 
 ZOOM_API(ZOOM_record)
@@ -1151,18 +1149,44 @@ ZOOM_record_get (ZOOM_record rec, const char *type, int *len)
     else if (!strcmp (type, "raw"))
     {
        if (npr->which == Z_NamePlusRecord_databaseRecord)
+       {
+           Z_External *r = (Z_External *) npr->u.databaseRecord;
+           
+           if (r->which == Z_External_sutrs)
+           {
+               if (len) *len = r->u.sutrs->len;
+               return (const char *) r->u.sutrs->buf;
+           }
+           else if (r->which == Z_External_octet)
+           {
+               if (len) *len = r->u.octet_aligned->len;
+               return (const char *) r->u.octet_aligned->buf;
+           }
+           else /* grs-1, explain, ... */
+           {
+               if (len) *len = -1;
+                return (const char *) npr->u.databaseRecord;
+           }
+       }
+       return 0;
+    }
+    else if (!strcmp (type, "ext"))
+    {
+       if (npr->which == Z_NamePlusRecord_databaseRecord)
             return (const char *) npr->u.databaseRecord;
        return 0;
     }
     return 0;
 }
 
-static void record_cache_add (ZOOM_resultset r,
-                             Z_NamePlusRecord *npr,
-                             int pos,
-                             const char *elementSetName)
+static void record_cache_add (ZOOM_resultset r, Z_NamePlusRecord *npr, int pos)
 {
     ZOOM_record_cache rc;
+    const char *elementSetName =
+        ZOOM_resultset_option_get (r, "elementSetName");
+    const char *syntax = 
+        ZOOM_resultset_option_get (r, "preferredRecordSyntax");
+    
 
     for (rc = r->record_cache; rc; rc = rc->next)
     {
@@ -1172,10 +1196,15 @@ static void record_cache_add (ZOOM_resultset r,
                || (elementSetName && rc->elementSetName &&
                    !strcmp (elementSetName, rc->elementSetName)))
            {
-               /* not destroying rc->npr (it's handled by nmem )*/
-               rc->rec.npr = npr;
-               /* keeping wrbuf_marc too */
-               return;
+                if ((!syntax && !rc->syntax)
+                    || (syntax && rc->syntax &&
+                        !strcmp (syntax, rc->syntax)))
+                {
+                    /* not destroying rc->npr (it's handled by nmem )*/
+                    rc->rec.npr = npr;
+                    /* keeping wrbuf_marc too */
+                    return;
+                }
            }
        }
     }
@@ -1187,17 +1216,25 @@ static void record_cache_add (ZOOM_resultset r,
        rc->elementSetName = odr_strdup (r->odr, elementSetName);
     else
        rc->elementSetName = 0;
+
+    if (syntax)
+       rc->syntax = odr_strdup (r->odr, syntax);
+    else
+       rc->syntax = 0;
+
     rc->pos = pos;
     rc->next = r->record_cache;
     r->record_cache = rc;
 }
 
-static ZOOM_record record_cache_lookup (ZOOM_resultset r,
-                                        int pos,
-                                        const char *elementSetName)
+static ZOOM_record record_cache_lookup (ZOOM_resultset r, int pos)
 {
     ZOOM_record_cache rc;
-
+    const char *elementSetName =
+        ZOOM_resultset_option_get (r, "elementSetName");
+    const char *syntax = 
+        ZOOM_resultset_option_get (r, "preferredRecordSyntax");
+    
     for (rc = r->record_cache; rc; rc = rc->next)
     {
        if (pos == rc->pos)
@@ -1205,7 +1242,12 @@ static ZOOM_record record_cache_lookup (ZOOM_resultset r,
            if ((!elementSetName && !rc->elementSetName)
                || (elementSetName && rc->elementSetName &&
                    !strcmp (elementSetName, rc->elementSetName)))
-               return &rc->rec;
+            {
+                if ((!syntax && !rc->syntax)
+                    || (syntax && rc->syntax &&
+                        !strcmp (syntax, rc->syntax)))
+                    return &rc->rec;
+            }
        }
     }
     return 0;
@@ -1259,7 +1301,7 @@ static void handle_records (ZOOM_connection c, Z_Records *sr,
            for (i = 0; i<p->num_records; i++)
            {
                record_cache_add (resultset, p->records[i],
-                                 i+ resultset->start, 0);
+                                  i+ resultset->start);
            }
            /* transfer our response to search_nmem .. we need it later */
            nmem_transfer (resultset->odr->mem, nmem);
@@ -1368,12 +1410,9 @@ static int send_present (ZOOM_connection c)
     Z_APDU *apdu = zget_APDU(c->odr_out, Z_APDU_presentRequest);
     Z_PresentRequest *req = apdu->u.presentRequest;
     int i = 0;
-    const char *syntax = 
-       ZOOM_options_get (c->options, "preferredRecordSyntax");
-    const char *element =
-       ZOOM_options_get (c->options, "elementSetName");
-    const char *schema =
-       ZOOM_options_get (c->options, "schema");
+    const char *syntax = 0;
+    const char *elementSetName = 0;
+    const char *schema = 0;
     ZOOM_resultset  resultset;
 
     if (!c->tasks)
@@ -1398,6 +1437,10 @@ static int send_present (ZOOM_connection c)
         return 0;
     }
 
+    syntax = ZOOM_resultset_option_get (resultset, "preferredRecordSyntax");
+    elementSetName = ZOOM_resultset_option_get (resultset, "elementSetName");
+    schema = ZOOM_resultset_option_get (resultset, "schema");
+
     if (c->error)                  /* don't continue on error */
        return 0;
     if (resultset->start < 0)
@@ -1405,7 +1448,7 @@ static int send_present (ZOOM_connection c)
     for (i = 0; i<resultset->count; i++)
     {
        ZOOM_record rec =
-           record_cache_lookup (resultset, i + resultset->start, 0);
+           record_cache_lookup (resultset, i + resultset->start);
        if (!rec)
            break;
     }
@@ -1448,14 +1491,14 @@ static int send_present (ZOOM_connection c)
             compo->u.complex->generic->schema = (Odr_oid *)
                 yaz_str_to_z3950oid (c->odr_out, CLASS_RECSYN, schema);
         }
-        if (element && *element)
+        if (elementSetName && *elementSetName)
         {
             compo->u.complex->generic->elementSpec = (Z_ElementSpec *)
                 odr_malloc(c->odr_out, sizeof(Z_ElementSpec));
             compo->u.complex->generic->elementSpec->which =
                 Z_ElementSpec_elementSetName;
             compo->u.complex->generic->elementSpec->u.elementSetName =
-                odr_strdup (c->odr_out, element);
+                odr_strdup (c->odr_out, elementSetName);
         }
         else
             compo->u.complex->generic->elementSpec = 0;
@@ -1464,7 +1507,7 @@ static int send_present (ZOOM_connection c)
         compo->u.complex->num_recordSyntax = 0;
         compo->u.complex->recordSyntax = 0;
     }
-    else if (element && *element)
+    else if (elementSetName && *elementSetName)
     {
        Z_ElementSetNames *esn = (Z_ElementSetNames *)
             odr_malloc (c->odr_out, sizeof(*esn));
@@ -1472,7 +1515,7 @@ static int send_present (ZOOM_connection c)
             odr_malloc (c->odr_out, sizeof(*compo));
        
        esn->which = Z_ElementSetNames_generic;
-       esn->u.generic = odr_strdup (c->odr_out, element);
+       esn->u.generic = odr_strdup (c->odr_out, elementSetName);
        compo->which = Z_RecordComp_simple;
        compo->u.simple = esn;
        req->recordComposition = compo;
@@ -2278,6 +2321,7 @@ ZOOM_connection_last_event(ZOOM_connection cs)
 ZOOM_API(int)
 ZOOM_event (int no, ZOOM_connection *cs)
 {
+    int timeout = 5000;
 #if HAVE_SYS_POLL_H
     struct pollfd pollfds[1024];
     ZOOM_connection poll_cs[1024];
@@ -2314,9 +2358,6 @@ ZOOM_event (int no, ZOOM_connection *cs)
 #if HAVE_SYS_POLL_H
 
 #else
-    tv.tv_sec = 15;
-    tv.tv_usec = 0;
-    
     FD_ZERO (&input);
     FD_ZERO (&output);
     FD_ZERO (&except);
@@ -2326,6 +2367,7 @@ ZOOM_event (int no, ZOOM_connection *cs)
     {
        ZOOM_connection c = cs[i];
        int fd, mask;
+        int this_timeout;
        
        if (!c)
            continue;
@@ -2337,6 +2379,9 @@ ZOOM_event (int no, ZOOM_connection *cs)
        if (max_fd < fd)
            max_fd = fd;
 
+        this_timeout = ZOOM_options_get_int (c->options, "timeout", -1);
+        if (this_timeout != -1 && this_timeout < timeout)
+            timeout = this_timeout;
 #if HAVE_SYS_POLL_H
         if (mask)
         {
@@ -2372,10 +2417,14 @@ ZOOM_event (int no, ZOOM_connection *cs)
        }
 #endif
     }
+    if (timeout >= 5000)
+        timeout = 30;
+
     if (!nfds)
         return 0;
+
 #if HAVE_SYS_POLL_H
-    r = poll (pollfds, nfds, 15000);
+    r = poll (pollfds, nfds, timeout * 1000);
     for (i = 0; i<nfds; i++)
     {
         ZOOM_connection c = poll_cs[i];
@@ -2401,6 +2450,8 @@ ZOOM_event (int no, ZOOM_connection *cs)
         }
     }
 #else
+    tv.tv_sec = timeout;
+    tv.tv_usec = 0;
     yaz_log (LOG_DEBUG, "select start");
     r = select (max_fd+1, &input, &output, &except, &tv);
     yaz_log (LOG_DEBUG, "select stop, returned r=%d", r);