Removed unused client states: Disconnected, Stopped, Continue.
[pazpar2-moved-to-github.git] / src / logic.c
index 8abdcae..a882ac3 100644 (file)
@@ -21,6 +21,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     \brief high-level logic; mostly user sessions and settings
 */
 
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -30,12 +34,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#if HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#if HAVE_NETDB_H
-#include <netdb.h>
-#endif
 #include <signal.h>
 #include <ctype.h>
 #include <assert.h>
@@ -54,18 +52,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include <yaz/oid_db.h>
 #include <yaz/snprintf.h>
 
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #define USE_TIMING 0
 #if USE_TIMING
 #include <yaz/timing.h>
 #endif
 
-#if HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
 
 #include "pazpar2.h"
 #include "eventl.h"
@@ -158,109 +149,20 @@ static void add_facet(struct session *s, const char *type, const char *value)
     termlist_insert(s->termlists[i].termlist, value);
 }
 
-xmlDoc *record_to_xml(struct session_database *sdb, Z_External *rec)
+xmlDoc *record_to_xml(struct session_database *sdb, const char *rec)
 {
     struct database *db = sdb->database;
     xmlDoc *rdoc = 0;
-    const Odr_oid *oid = rec->direct_reference;
 
-    /* convert response record to XML somehow */
-    if (rec->which == Z_External_octet && oid
-        && !oid_oidcmp(oid, yaz_oid_recsyn_xml))
-    {
-        /* xml already */
-        rdoc = xmlParseMemory((char*) rec->u.octet_aligned->buf,
-                              rec->u.octet_aligned->len);
-        if (!rdoc)
-        {
-            yaz_log(YLOG_FATAL, "Non-wellformed XML received from %s",
-                    db->url);
-            return 0;
-        }
-    }
-    else if (rec->which == Z_External_OPAC)
-    {
-        if (!sdb->yaz_marc)
-        {
-            yaz_log(YLOG_WARN, "MARC decoding not configured");
-            return 0;
-        }
-        else
-        {
-            /* OPAC gets converted to XML too */
-            WRBUF wrbuf_opac = wrbuf_alloc();
-            /* MARCXML inside the OPAC XML. Charset is in effect because we
-               use the yaz_marc handle */
-            yaz_marc_xml(sdb->yaz_marc, YAZ_MARC_MARCXML);
-            yaz_opac_decode_wrbuf(sdb->yaz_marc, rec->u.opac, wrbuf_opac);
-            
-            rdoc = xmlParseMemory((char*) wrbuf_buf(wrbuf_opac),
-                                  wrbuf_len(wrbuf_opac));
-            if (!rdoc)
-            {
-                yaz_log(YLOG_WARN, "Unable to parse OPAC XML");
-                /* Was used to debug bug #1348 */
-#if 0
-                FILE *f = fopen("/tmp/opac.xml.txt", "wb");
-                if (f)
-                {
-                    fwrite(wrbuf_buf(wrbuf_opac), 1, wrbuf_len(wrbuf_opac), f);
-                    fclose(f);
-                }
-#endif
-            }
-            wrbuf_destroy(wrbuf_opac);
-        }
-    }
-    else if (oid && yaz_oid_is_iso2709(oid))
-    {
-        /* ISO2709 gets converted to MARCXML */
-        if (!sdb->yaz_marc)
-        {
-            yaz_log(YLOG_WARN, "MARC decoding not configured");
-            return 0;
-        }
-        else
-        {
-            xmlNode *res;
-            char *buf;
-            int len;
-            
-            if (rec->which != Z_External_octet)
-            {
-                yaz_log(YLOG_WARN, "Unexpected external branch, probably BER %s",
-                        db->url);
-                return 0;
-            }
-            buf = (char*) rec->u.octet_aligned->buf;
-            len = rec->u.octet_aligned->len;
-            if (yaz_marc_read_iso2709(sdb->yaz_marc, buf, len) < 0)
-            {
-                yaz_log(YLOG_WARN, "Failed to decode MARC %s", db->url);
-                return 0;
-            }
-            
-            if (yaz_marc_write_xml(sdb->yaz_marc, &res,
-                                   "http://www.loc.gov/MARC21/slim", 0, 0) < 0)
-            {
-                yaz_log(YLOG_WARN, "Failed to encode as XML %s",
-                        db->url);
-                return 0;
-            }
-            rdoc = xmlNewDoc((xmlChar *) "1.0");
-            xmlDocSetRootElement(rdoc, res);
-        }
-    }
-    else
+    rdoc = xmlParseMemory(rec, strlen(rec));
+
+    if (!rdoc)
     {
-        char oid_name_buf[OID_STR_MAX];
-        const char *oid_name = yaz_oid_to_string_buf(oid, 0, oid_name_buf);
-        yaz_log(YLOG_FATAL, 
-                "Unable to handle record of type %s from %s", 
-                oid_name, db->url);
+        yaz_log(YLOG_FATAL, "Non-wellformed XML received from %s",
+                db->url);
         return 0;
     }
-    
+
     if (global_parameters.dump_records)
     {
         FILE *lf = yaz_log_file();
@@ -275,6 +177,7 @@ xmlDoc *record_to_xml(struct session_database *sdb, Z_External *rec)
             fprintf(lf, "\n");
         }
     }
+
     return rdoc;
 }
 
@@ -343,7 +246,7 @@ static void insert_settings_values(struct session_database *sdb, xmlDoc *doc)
 }
 
 xmlDoc *normalize_record(struct session_database *sdb, struct session *se,
-                         Z_External *rec)
+                         const char *rec)
 {
     struct database_retrievalmap *m;
     xmlDoc *rdoc = record_to_xml(sdb, rec);
@@ -406,44 +309,6 @@ const char *session_setting_oneval(struct session_database *db, int offset)
     return db->settings[offset]->value;
 }
 
-
-
-// Initialize YAZ Map structures for MARC-based targets
-static int prepare_yazmarc(struct session_database *sdb)
-{
-    const char *s;
-
-    if (!sdb->settings)
-    {
-        yaz_log(YLOG_WARN, "No settings for %s", sdb->database->url);
-        return -1;
-    }
-    if ((s = session_setting_oneval(sdb, PZ_NATIVESYNTAX)) 
-        && !strncmp(s, "iso2709", 7))
-    {
-        char *encoding = "marc-8s", *e;
-        yaz_iconv_t cm;
-
-        // See if a native encoding is specified
-        if ((e = strchr(s, ';')))
-            encoding = e + 1;
-
-        sdb->yaz_marc = yaz_marc_create();
-        yaz_marc_subfield_str(sdb->yaz_marc, "\t");
-        
-        cm = yaz_iconv_open("utf-8", encoding);
-        if (!cm)
-        {
-            yaz_log(YLOG_FATAL, 
-                    "Unable to map from %s to UTF-8 for target %s", 
-                    encoding, sdb->database->url);
-            return -1;
-        }
-        yaz_marc_iconv(sdb->yaz_marc, cm);
-    }
-    return 0;
-}
-
 // Prepare XSLT stylesheets for record normalization
 // Structures are allocated on the session_wide nmem to avoid having
 // to recompute this for every search. This would lead
@@ -518,11 +383,6 @@ static int prepare_session_database(struct session *se,
                 "No settings associated with %s", sdb->database->url);
         return -1;
     }
-    if (sdb->settings[PZ_NATIVESYNTAX] && !sdb->yaz_marc)
-    {
-        if (prepare_yazmarc(sdb) < 0)
-            return -1;
-    }
     if (sdb->settings[PZ_XSLT] && !sdb->map)
     {
         if (prepare_map(se, sdb) < 0)
@@ -670,7 +530,6 @@ enum pazpar2_error_code search(struct session *se,
     se->reclist = 0;
     se->num_termlists = 0;
     criteria = parse_filter(se->nmem, filter);
-    se->requestid++;
     live_channels = select_targets(se, criteria);
     if (live_channels)
     {
@@ -694,7 +553,8 @@ enum pazpar2_error_code search(struct session *se,
         else
         {
             no_working++;
-            client_prep_connection(cl);
+            if (client_prep_connection(cl))
+                client_start_search(cl);
         }
     }
 
@@ -716,7 +576,6 @@ static void session_init_databases_fun(void *context, struct database *db)
     int i;
 
     new->database = db;
-    new->yaz_marc = 0;
     
     new->map = 0;
     new->settings 
@@ -739,8 +598,6 @@ static void session_database_destroy(struct session_database *sdb)
 
     for (m = sdb->map; m; m = m->next)
         xsltFreeStylesheet(m->stylesheet);
-    if (sdb->yaz_marc)
-        yaz_marc_destroy(sdb->yaz_marc);
 }
 
 // Initialize session_database list -- this represents this session's view
@@ -805,13 +662,6 @@ void session_apply_setting(struct session *se, char *dbname, char *setting,
     // (happens when a search starts and client connections are prepared)
     switch (offset)
     {
-    case PZ_NATIVESYNTAX:
-        if (sdb->yaz_marc)
-        {
-            yaz_marc_destroy(sdb->yaz_marc);
-            sdb->yaz_marc = 0;
-        }
-        break;
     case PZ_XSLT:
         if (sdb->map)
         {
@@ -847,9 +697,9 @@ struct session *new_session(NMEM nmem)
     session->relevance = 0;
     session->total_hits = 0;
     session->total_records = 0;
+    session->number_of_warnings_unknown_elements = 0;
     session->num_termlists = 0;
     session->reclist = 0;
-    session->requestid = -1;
     session->clients = 0;
     session->expected_maxrecs = 0;
     session->session_nmem = nmem;
@@ -1000,9 +850,7 @@ void statistics(struct session *se, struct statistics *stat)
         switch (client_get_state(cl))
         {
         case Client_Connecting: stat->num_connecting++; break;
-        case Client_Initializing: stat->num_initializing++; break;
-        case Client_Searching: stat->num_searching++; break;
-        case Client_Presenting: stat->num_presenting++; break;
+        case Client_Working: stat->num_working++; break;
         case Client_Idle: stat->num_idle++; break;
         case Client_Failed: stat->num_failed++; break;
         case Client_Error: stat->num_error++; break;
@@ -1016,7 +864,7 @@ void statistics(struct session *se, struct statistics *stat)
     stat->num_clients = count;
 }
 
-void start_http_listener(void)
+int start_http_listener(void)
 {
     char hp[128] = "";
     struct conf_server *ser = global_parameters.server;
@@ -1033,7 +881,7 @@ void start_http_listener(void)
             sprintf(hp + strlen(hp), "%d", ser->port);
         }
     }
-    http_init(hp);
+    return http_init(hp);
 }
 
 void start_proxy(void)
@@ -1103,7 +951,7 @@ static struct record_metadata *record_metadata_init(
     return rec_md;
 }
 
-struct record *ingest_record(struct client *cl, Z_External *rec,
+struct record *ingest_record(struct client *cl, const char *rec,
                              int record_no)
 {
     xmlDoc *xdoc = normalize_record(client_get_database(cl),
@@ -1225,8 +1073,10 @@ struct record *ingest_record(struct client *cl, Z_External *rec,
                          value, type);
                  continue;
              }
-             rec_md->next = record->metadata[md_field_id];
-             record->metadata[md_field_id] = rec_md;
+             wheretoput = &record->metadata[md_field_id];
+             while (*wheretoput)
+                 wheretoput = &(*wheretoput)->next;
+             *wheretoput = rec_md;
 
              // merged metadata
              rec_md = record_metadata_init(se->nmem, (char *) value,
@@ -1235,6 +1085,12 @@ struct record *ingest_record(struct client *cl, Z_External *rec,
 
              // and polulate with data:
              // assign cluster or record based on merge action
+             if (ser_md->merge == Metadata_merge_no)
+             {
+                 while (*wheretoput)
+                     wheretoput = &(*wheretoput)->next;
+                 *wheretoput = rec_md;
+             }
              if (ser_md->merge == Metadata_merge_unique)
              {
                  struct record_metadata *mnode;
@@ -1348,9 +1204,13 @@ struct record *ingest_record(struct client *cl, Z_External *rec,
             xmlFree(value);
             type = value = 0;
         }
-        else
-            yaz_log(YLOG_WARN,
-                    "Unexpected element %s in internal record", n->name);
+         else
+         {
+             if (se->number_of_warnings_unknown_elements == 0)
+                 yaz_log(YLOG_WARN,
+                         "Unexpected element in internal record: %s", n->name);
+             se->number_of_warnings_unknown_elements++;
+         }
     }
     if (type)
         xmlFree(type);