Add code to compile CCL qualifiers if specified using <ccl2rpn>.
[yaz-moved-to-github.git] / src / zoom-c.c
index 1c071d6..fed3e74 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2007, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: zoom-c.c,v 1.134 2007-06-20 12:55:29 adam Exp $
+ * $Id: zoom-c.c,v 1.139 2007-07-04 11:42:14 adam Exp $
  */
 /**
  * \file zoom-c.c
@@ -28,6 +28,7 @@
 #include <yaz/ccl.h>
 #include <yaz/query-charset.h>
 #include <yaz/copy_types.h>
+#include <yaz/snprintf.h>
 
 static int log_api = 0;
 static int log_details = 0;
@@ -1341,7 +1342,7 @@ static zoom_ret ZOOM_connection_send_init(ZOOM_connection c)
                     odr_prepend(c->odr_out, "ZOOM-C",
                                 ireq->implementationName));
     
-    version = odr_strdup(c->odr_out, "$Revision: 1.134 $");
+    version = odr_strdup(c->odr_out, "$Revision: 1.139 $");
     if (strlen(version) > 10)   /* check for unexpanded CVS strings */
         version[strlen(version)-2] = '\0';
     ireq->implementationVersion = 
@@ -3124,6 +3125,7 @@ static Z_APDU *create_update_package(ZOOM_package p)
     const char *recordIdNumber = ZOOM_options_get(p->options, "recordIdNumber");
     const char *record_buf = ZOOM_options_get(p->options, "record");
     const char *syntax_str = ZOOM_options_get(p->options, "syntax");
+    const char *version = ZOOM_options_get(p->options, "updateVersion");
 
     const char *correlationInfo_note =
         ZOOM_options_get(p->options, "correlationInfo.note");
@@ -3131,7 +3133,10 @@ static Z_APDU *create_update_package(ZOOM_package p)
         ZOOM_options_get(p->options, "correlationInfo.id");
     int action_no = -1;
     Odr_oid *syntax_oid = 0;
+    const Odr_oid *package_oid = yaz_oid_extserv_database_update;
 
+    if (!version)
+        version = "3";
     if (!syntax_str)
         syntax_str = "xml";
     if (!record_buf)
@@ -3152,8 +3157,27 @@ static Z_APDU *create_update_package(ZOOM_package p)
     if (num_db > 0)
         first_db = db[0];
     
-    if (!action)
-        action = "specialUpdate";
+    switch(*version)
+    {
+    case '1':
+        package_oid = yaz_oid_extserv_database_update_first_version;
+        /* old update does not support specialUpdate */
+        if (!action)
+            action = "recordInsert";
+        break;
+    case '2':
+        if (!action)
+            action = "specialUpdate";
+        package_oid = yaz_oid_extserv_database_update_second_version;
+        break;
+    case '3':
+        if (!action)
+            action = "specialUpdate";
+        package_oid = yaz_oid_extserv_database_update;
+        break;
+    default:
+        return 0;
+    }
     
     if (!strcmp(action, "recordInsert"))
         action_no = Z_IUOriginPartToKeep_recordInsert;
@@ -3168,19 +3192,19 @@ static Z_APDU *create_update_package(ZOOM_package p)
     else
         return 0;
 
-    apdu = create_es_package(p, yaz_oid_extserv_database_update);
+    apdu = create_es_package(p, package_oid);
     if (apdu)
     {
         Z_IUOriginPartToKeep *toKeep;
         Z_IUSuppliedRecords *notToKeep;
         Z_External *r = (Z_External *)
             odr_malloc(p->odr_out, sizeof(*r));
+        const char *elementSetName =
+            ZOOM_options_get(p->options, "elementSetName");
         
         apdu->u.extendedServicesRequest->taskSpecificParameters = r;
-
         
-        r->direct_reference = odr_oiddup(p->odr_out, 
-                                         yaz_oid_extserv_database_update);
+        r->direct_reference = odr_oiddup(p->odr_out, package_oid);
         r->descriptor = 0;
         r->which = Z_External_update;
         r->indirect_reference = 0;
@@ -3196,7 +3220,11 @@ static Z_APDU *create_update_package(ZOOM_package p)
         
         toKeep->databaseName = odr_strdup(p->odr_out, first_db);
         toKeep->schema = 0;
+        
         toKeep->elementSetName = 0;
+        if (elementSetName)
+            toKeep->elementSetName = odr_strdup(p->odr_out, elementSetName);
+            
         toKeep->actionQualifier = 0;
         toKeep->action = odr_intdup(p->odr_out, action_no);
         
@@ -3529,7 +3557,7 @@ static void recv_apdu(ZOOM_connection c, Z_APDU *apdu)
     switch(apdu->which)
     {
     case Z_APDU_initResponse:
-        yaz_log(log_api, "%p recv_apd: Received Init response", c);
+        yaz_log(log_api, "%p recv_apdu: Received Init response", c);
         initrs = apdu->u.initResponse;
         ZOOM_connection_option_set(c, "serverImplementationId",
                                    initrs->implementationId ?
@@ -3847,11 +3875,19 @@ static int do_read(ZOOM_connection c)
         {
             int x;
             int err = odr_geterrorx(c->odr_in, &x);
-            char msg[60];
+            char msg[100];
             const char *element = odr_getelement(c->odr_in);
-            sprintf(msg, "ODR code %d:%d element=%-20s",
-                    err, x, element ? element : "<unknown>");
+            yaz_snprintf(msg, sizeof(msg),
+                    "ODR code %d:%d element=%s offset=%d",
+                    err, x, element ? element : "<unknown>",
+                    odr_offset(c->odr_in));
             set_ZOOM_error(c, ZOOM_ERROR_DECODE, msg);
+            if (log_api)
+            {
+                FILE *ber_file = yaz_log_file();
+                if (ber_file)
+                    odr_dumpBER(ber_file, c->buf_in, r);
+            }
             do_close(c);
         }
         else if (gdu->which == Z_GDU_Z3950)
@@ -4090,6 +4126,8 @@ static void ZOOM_connection_do_io(ZOOM_connection c, int mask)
             if (c->cs->io_pending & CS_WANT_READ)
                 mask += ZOOM_SELECT_READ;
             ZOOM_connection_set_mask(c, mask);
+            event = ZOOM_Event_create(ZOOM_EVENT_NONE);
+            ZOOM_connection_put_event(c, event);
         }
         else if (ret == 0)
         {