First work on PAZ-900
[pazpar2-moved-to-github.git] / src / session.c
index b0fbfa1..a42cedc 100644 (file)
@@ -107,7 +107,8 @@ static int session_use(int delta)
     no_sessions += delta;
     sessions = no_sessions;
     yaz_mutex_leave(g_session_mutex);
-    yaz_log(YLOG_DEBUG, "%s sessions=%d", delta == 0 ? "" : (delta > 0 ? "INC" : "DEC"), no_sessions);
+    yaz_log(YLOG_DEBUG, "%s sessions=%d", delta == 0 ? "" :
+            (delta > 0 ? "INC" : "DEC"), no_sessions);
     return sessions;
 }
 
@@ -148,10 +149,9 @@ static void session_leave(struct session *s, const char *caller)
         session_log(s, YLOG_DEBUG, "Session unlock by %s", caller);
 }
 
-static void session_normalize_facet(struct session *s, const char *type,
-                                    const char *value,
-                                    WRBUF display_wrbuf,
-                                    WRBUF facet_wrbuf)
+static void session_normalize_facet(struct session *s,
+                                    const char *type, const char *value,
+                                    WRBUF display_wrbuf, WRBUF facet_wrbuf)
 {
     struct conf_service *service = s->service;
     pp2_charset_token_t prt;
@@ -748,6 +748,7 @@ enum pazpar2_error_code session_search(struct session *se,
                                        const char *filter,
                                        const char *limit,
                                        const char **addinfo,
+                                       const char **addinfo2,
                                        struct reclist_sortparms *sp,
                                        const char *mergekey,
                                        const char *rank)
@@ -758,6 +759,11 @@ enum pazpar2_error_code session_search(struct session *se,
     int no_failed_limit = 0;
     struct client_list *l, *l0;
 
+    session_alert_watch(se, SESSION_WATCH_SHOW);
+    session_alert_watch(se, SESSION_WATCH_BYTARGET);
+    session_alert_watch(se, SESSION_WATCH_TERMLIST);
+    session_alert_watch(se, SESSION_WATCH_SHOW_PREF);
+
     session_log(se, YLOG_DEBUG, "Search");
 
     *addinfo = 0;
@@ -813,7 +819,7 @@ enum pazpar2_error_code session_search(struct session *se,
         if (prepare_map(se, client_get_database(cl)) < 0)
             continue;
 
-        parse_ret = client_parse_query(cl, query, se->facet_limits);
+        parse_ret = client_parse_query(cl, query, se->facet_limits, addinfo2);
         if (parse_ret == -1)
             no_failed_query++;
         else if (parse_ret == -2)
@@ -845,7 +851,6 @@ enum pazpar2_error_code session_search(struct session *se,
         else
             return PAZPAR2_NO_TARGETS;
     }
-    session_log(se, YLOG_LOG, "session_start_search done");
     return PAZPAR2_NO_ERROR;
 }
 
@@ -1240,7 +1245,7 @@ struct record_cluster *show_single_start(struct session *se, const char *id,
     session_enter(se, "show_single_start");
     *prev_r = 0;
     *next_r = 0;
-    reclist_limit(se->reclist, se);
+    reclist_limit(se->reclist, se, 1);
 
     reclist_enter(se->reclist);
     while ((r = reclist_read_record(se->reclist)))
@@ -1314,7 +1319,7 @@ struct record_cluster **show_range_start(struct session *se,
     *sumhits = 0;
     *approx_hits = 0;
     *total = 0;
-    reclist_limit(se->reclist, se);
+    reclist_limit(se->reclist, se, 0);
     if (se->relevance)
     {
         for (spp = sp; spp; spp = spp->next)
@@ -1467,6 +1472,7 @@ static struct record_metadata *record_metadata_init(
 
         rec_md->data.text.disp = p;
         rec_md->data.text.sort = 0;
+        rec_md->data.text.snippet = 0;
     }
     else if (type == Metadata_type_year || type == Metadata_type_date)
     {
@@ -1666,13 +1672,45 @@ static int check_record_filter(xmlNode *root, struct session_database *sdb)
     return match;
 }
 
-
 static int ingest_to_cluster(struct client *cl,
                              xmlDoc *xdoc,
                              xmlNode *root,
                              int record_no,
                              const char *mergekey_norm);
 
+static int ingest_sub_record(struct client *cl, xmlDoc *xdoc, xmlNode *root,
+                             int record_no, NMEM nmem,
+                             struct session_database *sdb)
+{
+    int ret = 0;
+    const char *mergekey_norm;
+    struct session *se = client_get_session(cl);
+    struct conf_service *service = se->service;
+
+    if (!check_record_filter(root, sdb))
+    {
+        session_log(se, YLOG_LOG, "Filtered out record no %d from %s", record_no, sdb->database->id);
+        xmlFreeDoc(xdoc);
+        return -2;
+    }
+
+    mergekey_norm = get_mergekey(xdoc, cl, record_no, service, nmem,
+        se->mergekey);
+    if (!mergekey_norm)
+    {
+        session_log(se, YLOG_WARN, "Got no mergekey");
+        xmlFreeDoc(xdoc);
+        return -1;
+    }
+    session_enter(se, "ingest_sub_record");
+    if (client_get_session(cl) == se && se->relevance)
+        ret = ingest_to_cluster(cl, xdoc, root, record_no, mergekey_norm);
+    session_leave(se, "ingest_sub_record");
+
+    xmlFreeDoc(xdoc);
+    return ret;
+}
+
 /** \brief ingest XML record
     \param cl client holds the result set for record
     \param rec record buffer (0 terminated)
@@ -1686,42 +1724,34 @@ int ingest_record(struct client *cl, const char *rec,
                   int record_no, NMEM nmem)
 {
     struct session *se = client_get_session(cl);
-    int ret = 0;
     struct session_database *sdb = client_get_database(cl);
     struct conf_service *service = se->service;
     xmlDoc *xdoc = normalize_record(se, sdb, service, rec, nmem);
     xmlNode *root;
-    const char *mergekey_norm;
 
     if (!xdoc)
         return -1;
 
     root = xmlDocGetRootElement(xdoc);
 
-    if (!check_record_filter(root, sdb))
+    if (!strcmp((const char *) root->name, "cluster"))
     {
-        session_log(se, YLOG_LOG, "Filtered out record no %d from %s", record_no, sdb->database->id);
-        xmlFreeDoc(xdoc);
-        return -2;
+        root = root->children;
+        return ingest_sub_record(cl, xdoc, root, record_no, nmem, sdb);
     }
-
-    mergekey_norm = get_mergekey(xdoc, cl, record_no, service, nmem,
-        se->mergekey);
-    if (!mergekey_norm)
+    else if (!strcmp((const char *) root->name, "record"))
     {
-        session_log(se, YLOG_WARN, "Got no mergekey");
-        xmlFreeDoc(xdoc);
+        return ingest_sub_record(cl, xdoc, root, record_no, nmem, sdb);
+    }
+    else
+    {
+        session_log(se, YLOG_WARN, "Bad pz root element: %s",
+                    (const char *) root->name);
         return -1;
     }
-    session_enter(se, "ingest_record");
-    if (client_get_session(cl) == se && se->relevance)
-        ret = ingest_to_cluster(cl, xdoc, root, record_no, mergekey_norm);
-    session_leave(se, "ingest_record");
-
-    xmlFreeDoc(xdoc);
-    return ret;
 }
 
+
 //    struct conf_metadata *ser_md = &service->metadata[md_field_id];
 //    struct record_metadata *rec_md = record->metadata[md_field_id];
 static int match_metadata_local(struct conf_service *service,
@@ -1956,6 +1986,18 @@ static int ingest_to_cluster(struct client *cl,
                             "for element '%s'", value, type);
                 continue;
             }
+
+            if (ser_md->type == Metadata_type_generic)
+            {
+                WRBUF w = wrbuf_alloc();
+                if (relevance_snippet(se->relevance,
+                                      (char*) value, ser_md->name, w))
+                    rec_md->data.text.snippet = nmem_strdup(se->nmem,
+                                                            wrbuf_cstr(w));
+                wrbuf_destroy(w);
+            }
+
+
             wheretoput = &record->metadata[md_field_id];
             while (*wheretoput)
                 wheretoput = &(*wheretoput)->next;
@@ -2183,7 +2225,6 @@ static int ingest_to_cluster(struct client *cl,
                 relevance_countwords(se->relevance, cluster,
                                      (char *) value, rank, ser_md->name);
             }
-
             // construct facets ... unless the client already has reported them
             if (ser_md->termlist && !client_has_facet(cl, (char *) type))
             {