Changed predicate for 500 subfields.
[pazpar2-moved-to-github.git] / src / logic.c
index a1de748..4239171 100644 (file)
@@ -1,35 +1,45 @@
-/* $Id: logic.c,v 1.67 2007-10-02 07:50:12 adam Exp $
-   Copyright (c) 2006-2007, Index Data.
+/* This file is part of Pazpar2.
+   Copyright (C) 2006-2008 Index Data
 
-   This file is part of Pazpar2.
+Pazpar2 is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
 
-   Pazpar2 is free software; you can redistribute it and/or modify it under
-   the terms of the GNU General Public License as published by the Free
-   Software Foundation; either version 2, or (at your option) any later
-   version.
+Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
 
-   Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY
-   WARRANTY; without even the implied warranty of MERCHANTABILITY or
-   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-   for more details.
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-   You should have received a copy of the GNU General Public License
-   along with Pazpar2; see the file LICENSE.  If not, write to the
-   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
 */
 
 /** \file logic.c
     \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>
+#if HAVE_SYS_TIME_H
 #include <sys/time.h>
+#endif
+#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>
 #include <yaz/oid_db.h>
 #include <yaz/snprintf.h>
 
-#if HAVE_CONFIG_H
-#include "cconfig.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"
@@ -65,7 +73,6 @@
 #include "termlists.h"
 #include "reclists.h"
 #include "relevance.h"
-#include "config.h"
 #include "database.h"
 #include "client.h"
 #include "settings.h"
@@ -82,20 +89,19 @@ struct parameters global_parameters =
     "",
     "", 
     0,
-    0, /* dump_records */
-    0, /* debug_mode */
-    30,
+    0,   // dump_records
+    0,   // debug_mode
+    30,  // operations timeout 
     "81",
     "Index Data PazPar2",
     VERSION,
-    600, // 10 minutes
-    60,
+    60,   // session timeout 
     100,
     MAX_CHUNK,
     0,
     0,
-    180,
-    15
+    180, // Z39.50 session timeout
+    15   // Connect timeout
 };
 
 // Recursively traverse query structure to extract terms.
@@ -526,7 +532,8 @@ static int prepare_session_database(struct session *se,
 }
 
 // called if watch should be removed because http_channel is to be destroyed
-static void session_watch_cancel(void *data, struct http_channel *c)
+static void session_watch_cancel(void *data, struct http_channel *c,
+                                 void *data2)
 {
     struct session_watchentry *ent = data;
 
@@ -554,9 +561,12 @@ void session_alert_watch(struct session *s, int what)
     if (s->watchlist[what].fun)
     {
         /* our watch is no longer associated with http_channel */
+        void *data;
+        session_watchfun fun;
+
         http_remove_observer(s->watchlist[what].obs);
-        session_watchfun fun = s->watchlist[what].fun;
-        void *data = s->watchlist[what].data;
+        fun = s->watchlist[what].fun;
+        data = s->watchlist[what].data;
 
         /* reset watch before fun is invoked - in case fun wants to set
            it again */
@@ -837,6 +847,7 @@ 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;
@@ -1006,7 +1017,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;
@@ -1023,7 +1034,7 @@ void start_http_listener(void)
             sprintf(hp + strlen(hp), "%d", ser->port);
         }
     }
-    http_init(hp);
+    return http_init(hp);
 }
 
 void start_proxy(void)
@@ -1075,11 +1086,16 @@ static struct record_metadata *record_metadata_init(
         rec_md->data.text.disp = nmem_strdup(nmem, p);
         rec_md->data.text.sort = 0;
     }
-    else if (type == Metadata_type_year)
+    else if (type == Metadata_type_year || type == Metadata_type_date)
     {
         int first, last;
-        if (extract7bit_years((char *) value, &first, &last) < 0)
+        int longdate = 0;
+
+        if (type == Metadata_type_date)
+            longdate = 1;
+        if (extract7bit_dates((char *) value, &first, &last, longdate) < 0)
             return 0;
+
         rec_md->data.number.min = first;
         rec_md->data.number.max = last;
     }
@@ -1210,8 +1226,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,
@@ -1220,6 +1238,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;
@@ -1261,6 +1285,12 @@ struct record *ingest_record(struct client *cl, Z_External *rec,
                          
                          cluster->sortkeys[sk_field_id]->text.disp = 
                              rec_md->data.text.disp;
+                         if (!sort_str)
+                         {
+                             sort_str = rec_md->data.text.disp;
+                             yaz_log(YLOG_WARN, 
+                                     "Could not make sortkey. Bug #1858");
+                         }
                          cluster->sortkeys[sk_field_id]->text.sort = 
                              nmem_strdup(se->nmem, sort_str);
 #if 0
@@ -1296,15 +1326,6 @@ struct record *ingest_record(struct client *cl, Z_External *rec,
                     if (this_max > (*wheretoput)->data.number.max)
                         (*wheretoput)->data.number.max = this_max;
                 }
-#ifdef GAGA
-                if (ser_sk)
-                {
-                    union data_types *sdata 
-                        = cluster->sortkeys[sk_field_id];
-                    yaz_log(YLOG_LOG, "SK range: %d-%d",
-                            sdata->number.min, sdata->number.max);
-                }
-#endif
             }
 
 
@@ -1336,9 +1357,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);