added initialization of char *recsyn = 0; and char *piggyback = 0;
[pazpar2-moved-to-github.git] / src / pazpar2.c
index e1c992c..99cc6a7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pazpar2.c,v 1.73 2007-04-11 18:42:25 quinn Exp $
+/* $Id: pazpar2.c,v 1.78 2007-04-13 11:13:08 marc Exp $
    Copyright (c) 2006-2007, Index Data.
 
 This file is part of Pazpar2.
@@ -39,6 +39,11 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include <yaz/otherinfo.h>
 #include <yaz/yaz-util.h>
 #include <yaz/nmem.h>
+#include <yaz/query-charset.h>
+#include <yaz/querytowrbuf.h>
+#if YAZ_VERSIONL >= 0x020163
+#include <yaz/oid_db.h>
+#endif
 
 #if HAVE_CONFIG_H
 #include "cconfig.h"
@@ -178,9 +183,19 @@ static void send_init(IOCHAN i)
     
     if (0 < strlen(global_parameters.zproxy_override) 
         && 0 < strlen(cl->database->database->url))
-        yaz_oi_set_string_oidval(&a->u.initRequest->otherInfo, 
+    {
+#if YAZ_VERSIONL >= 0x020163
+        const int *oid_proxy = yaz_string_to_oid(yaz_oid_std(),
+                                                 CLASS_USERINFO, OID_STR_PROXY);
+        yaz_oi_set_string_oid(&a->u.initRequest->otherInfo,
+                              global_parameters.odr_out, oid_proxy,
+                              1, cl->database->database->url);
+#else
+        yaz_oi_set_string_oidval(&a->u.initRequest->otherInfo,
                                  global_parameters.odr_out, VAL_PROXY,
                                  1, cl->database->database->url);
+#endif
+    }
 
     if (send_apdu(cl, a) >= 0)
     {
@@ -232,10 +247,12 @@ static void send_search(IOCHAN i)
     Z_Query *zquery;
     struct ccl_rpn_node *cn;
     int ssub = 0, lslb = 100000, mspn = 10;
-    char *recsyn;
-    char *piggyback;
+    char *recsyn = 0;
+    char *piggyback = 0;
+    char *queryenc = 0;
+    yaz_iconv_t iconv = 0;
 
-    yaz_log(YLOG_DEBUG, "Sending search");
+    yaz_log(YLOG_DEBUG, "Sending search to %s", cl->database->database->url);
 
     cn = ccl_find_str(sdb->database->ccl_map, se->query, &cerror, &cpos);
     if (!cn)
@@ -250,12 +267,26 @@ static void send_search(IOCHAN i)
                 se->expected_maxrecs);
     }
 
+    // constructing RPN query
     a->u.searchRequest->query = zquery = odr_malloc(global_parameters.odr_out,
             sizeof(Z_Query));
     zquery->which = Z_Query_type_1;
     zquery->u.type_1 = ccl_rpn_query(global_parameters.odr_out, cn);
     ccl_rpn_delete(cn);
 
+    // converting to target encoding
+    if ((queryenc = session_setting_oneval(sdb, PZ_QUERYENCODING))){
+        iconv = yaz_iconv_open(queryenc, "UTF-8");
+        if (iconv){
+            yaz_query_charset_convert_rpnquery(zquery->u.type_1, 
+                                               global_parameters.odr_out, 
+                                               iconv);
+            yaz_iconv_close(iconv);
+        } else
+            yaz_log(YLOG_WARN, "Query encoding failed %s %s", 
+                    cl->database->database->url, queryenc);
+    }
+
     for (ndb = 0; sdb->database->databases[ndb]; ndb++)
        ;
     databaselist = odr_malloc(global_parameters.odr_out, sizeof(char*) * ndb);
@@ -265,9 +296,18 @@ static void send_search(IOCHAN i)
     if (!(piggyback = session_setting_oneval(sdb, PZ_PIGGYBACK)) || *piggyback == '1')
     {
         if ((recsyn = session_setting_oneval(sdb, PZ_REQUESTSYNTAX)))
+        {
+#if YAZ_VERSIONL >= 0x020163
+            a->u.searchRequest->preferredRecordSyntax =
+                yaz_string_to_oid_odr(yaz_oid_std(),
+                                      CLASS_RECSYN, recsyn,
+                                      global_parameters.odr_out);
+#else
             a->u.searchRequest->preferredRecordSyntax =
-                    yaz_str_to_z3950oid(global_parameters.odr_out,
-                    CLASS_RECSYN, recsyn);
+                yaz_str_to_z3950oid(global_parameters.odr_out,
+                                    CLASS_RECSYN, recsyn);
+#endif
+        }
         a->u.searchRequest->smallSetUpperBound = &ssub;
         a->u.searchRequest->largeSetLowerBound = &lslb;
         a->u.searchRequest->mediumSetPresentNumber = &mspn;
@@ -276,14 +316,32 @@ static void send_search(IOCHAN i)
     a->u.searchRequest->databaseNames = databaselist;
     a->u.searchRequest->num_databaseNames = ndb;
 
-    if (send_apdu(cl, a) >= 0)
-    {
-       iochan_setflags(i, EVENT_INPUT);
-       cl->state = Client_Searching;
-        cl->requestid = se->requestid;
-    }
-    else
-        cl->state = Client_Error;
+    
+    {  //scope for sending and logging queries 
+        WRBUF wbquery = wrbuf_alloc();
+        yaz_query_to_wrbuf(wbquery, zquery);
+
+
+        if (send_apdu(cl, a) >= 0)
+            {
+                iochan_setflags(i, EVENT_INPUT);
+                cl->state = Client_Searching;
+                cl->requestid = se->requestid;
+                yaz_log(YLOG_LOG, "SearchRequest %s %s %s", 
+                         cl->database->database->url,
+                        queryenc ? queryenc : "UTF-8",
+                        wrbuf_cstr(wbquery));
+            }
+        else {
+            cl->state = Client_Error;
+                yaz_log(YLOG_WARN, "Failed SearchRequest %s  %s %s", 
+                         cl->database->database->url, 
+                        queryenc ? queryenc : "UTF-8",
+                        wrbuf_cstr(wbquery));
+        }
+        
+        wrbuf_destroy(wbquery);
+    }    
 
     odr_reset(global_parameters.odr_out);
 }
@@ -312,9 +370,18 @@ static void send_present(IOCHAN i)
     a->u.presentRequest->resultSetId = "Default";
 
     if ((recsyn = session_setting_oneval(sdb, PZ_REQUESTSYNTAX)))
+    {
+#if YAZ_VERSIONL >= 0x020163
         a->u.presentRequest->preferredRecordSyntax =
-                yaz_str_to_z3950oid(global_parameters.odr_out,
-                CLASS_RECSYN, recsyn);
+            yaz_string_to_oid_odr(yaz_oid_std(),
+                                  CLASS_RECSYN, recsyn,
+                                  global_parameters.odr_out);
+#else
+        a->u.presentRequest->preferredRecordSyntax =
+            yaz_str_to_z3950oid(global_parameters.odr_out,
+                                CLASS_RECSYN, recsyn);
+#endif
+    }
 
     if (send_apdu(cl, a) >= 0)
     {
@@ -485,6 +552,8 @@ static xmlDoc *normalize_record(struct client *cl, Z_External *rec)
                     cl->database->database->url);
             return 0;
         }
+
+        yaz_marc_write_using_libxml2(db->yaz_marc, 1);
         if (yaz_marc_write_xml(db->yaz_marc, &res,
                     "http://www.loc.gov/MARC21/slim", 0, 0) < 0)
         {
@@ -494,16 +563,20 @@ static xmlDoc *normalize_record(struct client *cl, Z_External *rec)
         }
         rdoc = xmlNewDoc((xmlChar *) "1.0");
         xmlDocSetRootElement(rdoc, res);
+
     }
     else
     {
-        yaz_log(YLOG_FATAL, "Unknown native_syntax in normalize_record");
+        yaz_log(YLOG_FATAL, 
+                "Unknown native_syntax in normalize_record from %s",
+                cl->database->database->url);
         exit(1);
     }
 
-    if (global_parameters.dump_records)
-    {
-        fprintf(stderr, "Input Record (normalized):\n----------------\n");
+    if (global_parameters.dump_records){
+        fprintf(stderr, 
+                "Input Record (normalized) from %s\n----------------\n",
+                cl->database->database->url);
 #if LIBXML_VERSION >= 20600
         xmlDocFormatDump(stderr, rdoc, 1);
 #else
@@ -511,20 +584,50 @@ static xmlDoc *normalize_record(struct client *cl, Z_External *rec)
 #endif
     }
 
-    for (m = db->map; m; m = m->next)
-    {
-        xmlDoc *new;
-        if (!(new = xsltApplyStylesheet(m->stylesheet, rdoc, 0)))
+    for (m = db->map; m; m = m->next){
+        xmlDoc *new = 0;
+
+#if 1
         {
-            yaz_log(YLOG_WARN, "XSLT transformation failed");
+            xmlNodePtr root = 0;
+            new = xsltApplyStylesheet(m->stylesheet, rdoc, 0);
+            root= xmlDocGetRootElement(new);
+        if (!new || !root || !(root->children))
+        {
+            yaz_log(YLOG_WARN, "XSLT transformation failed from %s",
+                    cl->database->database->url);
+            xmlFreeDoc(new);
+            xmlFreeDoc(rdoc);
             return 0;
         }
+        }
+#endif
+
+#if 0
+        // do it another way to detect transformation errors right now
+        // but does not seem to work either!
+        {
+            xsltTransformContextPtr ctxt;
+            ctxt = xsltNewTransformContext(m->stylesheet, rdoc);
+            new = xsltApplyStylesheetUser(m->stylesheet, rdoc, 0, 0, 0, ctxt);
+            if ((ctxt->state == XSLT_STATE_ERROR) ||
+                (ctxt->state == XSLT_STATE_STOPPED)){
+                yaz_log(YLOG_WARN, "XSLT transformation failed from %s",
+                        cl->database->database->url);
+                xmlFreeDoc(new);
+                xmlFreeDoc(rdoc);
+                return 0;
+            }
+        }
+#endif      
+   
         xmlFreeDoc(rdoc);
         rdoc = new;
     }
     if (global_parameters.dump_records)
     {
-        fprintf(stderr, "Record:\n----------------\n");
+        fprintf(stderr, "Record from %s\n----------------\n", 
+                cl->database->database->url);
 #if LIBXML_VERSION >= 20600
         xmlDocFormatDump(stderr, rdoc, 1);
 #else
@@ -1342,7 +1445,6 @@ void session_apply_setting(struct session *se, char *dbname, char *setting, char
             new->target = dbname;
             new->name = setting;
             new->value = value;
-            new->user = "";
             new->next = sdb->settings[offset];
             sdb->settings[offset] = new;
             break;