Protect struct reclist
[pazpar2-moved-to-github.git] / src / logic.c
index 0d578a0..9174fa0 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of Pazpar2.
-   Copyright (C) 2006-2009 Index Data
+   Copyright (C) 2006-2010 Index Data
 
 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
@@ -92,7 +92,7 @@ static void log_xml_doc(xmlDoc *doc)
 #endif
     if (lf && len)
     {
-        fwrite(result, 1, len, lf);
+        (void) fwrite(result, 1, len, lf);
         fprintf(lf, "\n");
     }
     xmlFree(result);
@@ -297,7 +297,7 @@ void session_settings_dump(struct session *se,
 // Will be extended to take into account user associated with session
 const char *session_setting_oneval(struct session_database *db, int offset)
 {
-    if (!db->settings[offset])
+    if (offset >= db->num_settings || !db->settings[offset])
         return "";
     return db->settings[offset]->value;
 }
@@ -491,7 +491,8 @@ enum pazpar2_error_code search(struct session *se,
         {
             no_working++;
             if (client_prep_connection(cl, se->service->z3950_operation_timeout,
-                                       se->service->z3950_session_timeout))
+                                       se->service->z3950_session_timeout,
+                                       se->service->server->iochan_man))
                 client_start_search(cl);
         }
     }
@@ -523,7 +524,10 @@ static void session_init_databases_fun(void *context, struct database *db)
                                 sizeof(struct settings *) * db->num_settings);
     new->num_settings = db->num_settings;
     for (i = 0; i < db->num_settings; i++)
-        new->settings[i] = db->settings[i];
+    {
+        struct setting *setting = db->settings[i];
+        new->settings[i] = setting;
+    }
     new->next = se->databases;
     se->databases = new;
 }
@@ -547,11 +551,12 @@ void session_init_databases(struct session *se)
 static struct session_database *load_session_database(struct session *se, 
                                                       char *id)
 {
-    struct database *db = find_database(id, se->service);
+    struct database *db = new_database(id, se->session_nmem);
 
-    resolve_database(db);
+    resolve_database(se->service, db);
 
     session_init_databases_fun((void*) se, db);
+
     // New sdb is head of se->databases list
     return se->databases;
 }
@@ -608,6 +613,7 @@ void destroy_session(struct session *s)
     for (sdb = s->databases; sdb; sdb = sdb->next)
         session_database_destroy(sdb);
     normalize_cache_destroy(s->normalize_cache);
+    reclist_destroy(s->reclist);
     nmem_destroy(s->nmem);
     service_destroy(s->service);
     wrbuf_destroy(s->wrbuf);
@@ -703,7 +709,7 @@ struct record_cluster *show_single(struct session *s, const char *id,
 {
     struct record_cluster *r;
 
-    reclist_rewind(s->reclist);
+    reclist_enter(s->reclist);
     *prev_r = 0;
     *next_r = 0;
     while ((r = reclist_read_record(s->reclist)))
@@ -711,15 +717,16 @@ struct record_cluster *show_single(struct session *s, const char *id,
         if (!strcmp(r->recid, id))
         {
             *next_r = reclist_read_record(s->reclist);
-            return r;
+            break;
         }
         *prev_r = r;
     }
-    return 0;
+    reclist_leave(s->reclist);
+    return r;
 }
 
 struct record_cluster **show(struct session *s, struct reclist_sortparms *sp, 
-                             int start, int *num, int *total, int *sumhits, 
+                             int start, int *num, int *total, Odr_int *sumhits, 
                              NMEM nmem_show)
 {
     struct record_cluster **recs = nmem_malloc(nmem_show, *num 
@@ -747,6 +754,7 @@ struct record_cluster **show(struct session *s, struct reclist_sortparms *sp,
             }
         reclist_sort(s->reclist, sp);
         
+        reclist_enter(s->reclist);
         *total = reclist_get_num_records(s->reclist);
         *sumhits = s->total_hits;
         
@@ -768,6 +776,7 @@ struct record_cluster **show(struct session *s, struct reclist_sortparms *sp,
             }
             recs[i] = r;
         }
+        reclist_leave(s->reclist);
     }
 #if USE_TIMING
     yaz_timing_stop(t);
@@ -806,25 +815,32 @@ void statistics(struct session *se, struct statistics *stat)
     stat->num_clients = count;
 }
 
-
-// Master list of connections we're handling events to
-static IOCHAN channel_list = 0;  /* thread pr */
-
-void pazpar2_add_channel(IOCHAN chan)
-{
-    chan->next = channel_list;
-    channel_list = chan;
-}
-
-void pazpar2_event_loop()
-{
-    event_loop(&channel_list);
-}
-
 static struct record_metadata *record_metadata_init(
-    NMEM nmem, const char *value, enum conf_metadata_type type)
+    NMEM nmem, const char *value, enum conf_metadata_type type,
+    struct _xmlAttr *attr)
 {
     struct record_metadata *rec_md = record_metadata_create(nmem);
+    struct record_metadata_attr **attrp = &rec_md->attributes;
+    
+    for (; attr; attr = attr->next)
+    {
+        if (attr->children && attr->children->content)
+        {
+            if (strcmp((const char *) attr->name, "type"))
+            {  /* skip the "type" attribute.. Its value is already part of
+                  the element in output (md-%s) and so repeating it here
+                  is redundant */
+                *attrp = nmem_malloc(nmem, sizeof(**attrp));
+                (*attrp)->name =
+                    nmem_strdup(nmem, (const char *) attr->name);
+                (*attrp)->value =
+                    nmem_strdup(nmem, (const char *) attr->children->content);
+                attrp = &(*attrp)->next;
+            }
+        }
+    }
+    *attrp = 0;
+
     if (type == Metadata_type_generic)
     {
         char *p = nmem_strdup(nmem, value);
@@ -873,17 +889,17 @@ static int get_mergekey_from_doc(xmlDoc *doc, xmlNode *root, const char *name,
                     pp2_relevance_token_t prt =
                         pp2_relevance_tokenize(
                             service->mergekey_pct,
-                            (const char *) value);
+                            (const char *) value, 0);
                     
+                    if (wrbuf_len(norm_wr) > 0)
+                        wrbuf_puts(norm_wr, " ");
                     wrbuf_puts(norm_wr, name);
-                    wrbuf_puts(norm_wr, "=");
                     while ((norm_str =
                             pp2_relevance_token_next(prt)))
                     {
                         if (*norm_str)
                         {
-                            if (wrbuf_len(norm_wr))
-                                wrbuf_puts(norm_wr, " ");
+                            wrbuf_puts(norm_wr, " ");
                             wrbuf_puts(norm_wr, norm_str);
                         }
                     }
@@ -913,7 +929,7 @@ static const char *get_mergekey(xmlDoc *doc, struct client *cl, int record_no,
         pp2_relevance_token_t prt =
             pp2_relevance_tokenize(
                 service->mergekey_pct,
-                (const char *) mergekey);
+                (const char *) mergekey, 0);
         
         while ((norm_str = pp2_relevance_token_next(prt)))
         {
@@ -1123,7 +1139,7 @@ struct record *ingest_record(struct client *cl, const char *rec,
 
             // non-merged metadata
             rec_md = record_metadata_init(se->nmem, (const char *) value,
-                                          ser_md->type);
+                                          ser_md->type, n->properties);
             if (!rec_md)
             {
                 yaz_log(YLOG_WARN, "bad metadata data '%s' for element '%s'",
@@ -1137,7 +1153,7 @@ struct record *ingest_record(struct client *cl, const char *rec,
 
             // merged metadata
             rec_md = record_metadata_init(se->nmem, (const char *) value,
-                                          ser_md->type);
+                                          ser_md->type, 0);
             wheretoput = &cluster->metadata[md_field_id];
 
             // and polulate with data:
@@ -1175,11 +1191,11 @@ struct record *ingest_record(struct client *cl, const char *rec,
                          
                         prt = pp2_relevance_tokenize(
                             service->sort_pct,
-                            rec_md->data.text.disp);
+                            rec_md->data.text.disp, skip_article);
 
                         pp2_relevance_token_next(prt);
                          
-                        sort_str = pp2_get_sort(prt, skip_article);
+                        sort_str = pp2_get_sort(prt);
                          
                         cluster->sortkeys[sk_field_id]->text.disp = 
                             rec_md->data.text.disp;
@@ -1230,7 +1246,8 @@ struct record *ingest_record(struct client *cl, const char *rec,
             // ranking of _all_ fields enabled ... 
             if (ser_md->rank)
                 relevance_countwords(se->relevance, cluster, 
-                                     (char *) value, ser_md->rank);
+                                     (char *) value, ser_md->rank,
+                                     ser_md->name);
 
             // construct facets ... 
             if (ser_md->termlist)