Included description of settings exposed to records.
[pazpar2-moved-to-github.git] / src / logic.c
index ce3eee6..e9fa969 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: logic.c,v 1.51 2007-07-13 09:25:41 adam Exp $
+/* $Id: logic.c,v 1.58 2007-07-30 23:16:33 quinn Exp $
    Copyright (c) 2006-2007, Index Data.
 
 This file is part of Pazpar2.
@@ -46,6 +46,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include <yaz/query-charset.h>
 #include <yaz/querytowrbuf.h>
 #include <yaz/oid_db.h>
+#include <yaz/snprintf.h>
 
 #if HAVE_CONFIG_H
 #include "cconfig.h"
@@ -92,10 +93,11 @@ struct parameters global_parameters =
     100,
     MAX_CHUNK,
     0,
-    0
+    0,
+    180,
+    30
 };
 
-
 // Recursively traverse query structure to extract terms.
 void pull_terms(NMEM nmem, struct ccl_rpn_node *n, char **termlist, int *num)
 {
@@ -243,31 +245,105 @@ xmlDoc *record_to_xml(struct session_database *sdb, Z_External *rec)
         return 0;
     }
     
-    if (global_parameters.dump_records){
-        fprintf(stderr, 
-                "Input Record (normalized) from %s\n----------------\n",
-                db->url);
+    if (global_parameters.dump_records)
+    {
+        FILE *lf = yaz_log_file();
+        if (lf)
+        {
+            yaz_log(YLOG_LOG, "Un-normalized record from %s", db->url);
 #if LIBXML_VERSION >= 20600
-        xmlDocFormatDump(stderr, rdoc, 1);
+            xmlDocFormatDump(lf, rdoc, 1);
 #else
-        xmlDocDump(stderr, rdoc);
+            xmlDocDump(lf, rdoc);
 #endif
+            fprintf(lf, "\n");
+        }
     }
     return rdoc;
 }
 
-xmlDoc *normalize_record(struct session_database *sdb, Z_External *rec)
+#define MAX_XSLT_ARGS 16
+
+// Add static values from session database settings if applicable
+static void insert_settings_parameters(struct session_database *sdb,
+        struct session *se, char **parms)
+{
+    struct conf_service *service = global_parameters.server->service;
+    int i;
+    int nparms = 0;
+    int offset = 0;
+
+    for (i = 0; i < service->num_metadata; i++)
+    {
+        struct conf_metadata *md = &service->metadata[i];
+        int setting;
+
+        if (md->setting == Metadata_setting_parameter &&
+                (setting = settings_offset(md->name)) > 0)
+        {
+            char *val = session_setting_oneval(sdb, setting);
+            if (val && nparms < MAX_XSLT_ARGS)
+            {
+                char *buf;
+                int len = strlen(val);
+                buf = nmem_malloc(se->nmem, len + 3);
+                buf[0] = '\'';
+                strcpy(buf + 1, val);
+                buf[len+1] = '\'';
+                buf[len+2] = '\0';
+                parms[offset++] = md->name;
+                parms[offset++] = buf;
+                nparms++;
+            }
+        }
+    }
+    parms[offset] = 0;
+}
+
+// Add static values from session database settings if applicable
+static void insert_settings_values(struct session_database *sdb, xmlDoc *doc)
+{
+    struct conf_service *service = global_parameters.server->service;
+    int i;
+
+    for (i = 0; i < service->num_metadata; i++)
+    {
+        struct conf_metadata *md = &service->metadata[i];
+        int offset;
+
+        if (md->setting == Metadata_setting_postproc &&
+                (offset = settings_offset(md->name)) > 0)
+        {
+            char *val = session_setting_oneval(sdb, offset);
+            if (val)
+            {
+                xmlNode *r = xmlDocGetRootElement(doc);
+                xmlNode *n = xmlNewTextChild(r, 0, (xmlChar *) "metadata",
+                        (xmlChar *) val);
+                xmlSetProp(n, (xmlChar *) "type", (xmlChar *) md->name);
+            }
+        }
+    }
+}
+
+xmlDoc *normalize_record(struct session_database *sdb, struct session *se,
+        Z_External *rec)
 {
     struct database_retrievalmap *m;
     xmlDoc *rdoc = record_to_xml(sdb, rec);
     if (rdoc)
     {
-        for (m = sdb->map; m; m = m->next){
+        for (m = sdb->map; m; m = m->next)
+        {
             xmlDoc *new = 0;
             
             {
                 xmlNodePtr root = 0;
-                new = xsltApplyStylesheet(m->stylesheet, rdoc, 0);
+                char *parms[MAX_XSLT_ARGS*2+1];
+
+                insert_settings_parameters(sdb, se, parms);
+
+                new = xsltApplyStylesheet(m->stylesheet, rdoc, (const char **) parms);
                 root= xmlDocGetRootElement(new);
                 if (!new || !root || !(root->children))
                 {
@@ -282,15 +358,24 @@ xmlDoc *normalize_record(struct session_database *sdb, Z_External *rec)
             xmlFreeDoc(rdoc);
             rdoc = new;
         }
+
+        insert_settings_values(sdb, rdoc);
+
         if (global_parameters.dump_records)
         {
-            fprintf(stderr, "Record from %s\n----------------\n", 
-                    sdb->database->url);
+            FILE *lf = yaz_log_file();
+            
+            if (lf)
+            {
+                yaz_log(YLOG_LOG, "Normalized record from %s", 
+                        sdb->database->url);
 #if LIBXML_VERSION >= 20600
-            xmlDocFormatDump(stderr, rdoc, 1);
+                xmlDocFormatDump(lf, rdoc, 1);
 #else
-            xmlDocDump(stderr, rdoc);
+                xmlDocDump(lf, rdoc);
 #endif
+                fprintf(lf, "\n");
+            }
         }
     }
     return rdoc;
@@ -362,7 +447,30 @@ static int prepare_map(struct session *se, struct session_database *sdb)
         char **stylesheets;
         struct database_retrievalmap **m = &sdb->map;
         int num, i;
+        char auto_stylesheet[256];
 
+        if (!strcmp(s, "auto"))
+        {
+            char *request_syntax = session_setting_oneval(sdb,
+                                                          PZ_REQUESTSYNTAX);
+            if (request_syntax)
+            {
+                char *cp;
+                yaz_snprintf(auto_stylesheet, sizeof(auto_stylesheet),
+                             "%s.xsl", request_syntax);
+                for (cp = auto_stylesheet; *cp; cp++)
+                {
+                    /* deliberately only consider ASCII */
+                    if (*cp > 32 && *cp < 127)
+                        *cp = tolower(*cp);
+                }
+                s = auto_stylesheet;
+            }
+            else
+            {
+                yaz_log(YLOG_WARN, "No pz:requestsyntax for auto stylesheet");
+            }
+        }
         nmem_strsplit(se->session_nmem, ",", s, &stylesheets, &num);
         for (i = 0; i < num; i++)
         {
@@ -787,13 +895,13 @@ void report_nmem_stats(void)
 }
 #endif
 
-struct record_cluster *show_single(struct session *s, int id)
+struct record_cluster *show_single(struct session *s, const char *id)
 {
     struct record_cluster *r;
 
     reclist_rewind(s->reclist);
     while ((r = reclist_read_record(s->reclist)))
-        if (r->recid == id)
+        if (!strcmp(r->recid, id))
             return r;
     return 0;
 }
@@ -972,7 +1080,8 @@ static struct record_metadata *record_metadata_init(
 struct record *ingest_record(struct client *cl, Z_External *rec,
                              int record_no)
 {
-    xmlDoc *xdoc = normalize_record(client_get_database(cl), rec);
+    xmlDoc *xdoc = normalize_record(client_get_database(cl),
+        client_get_session(cl), rec);
     xmlNode *root, *n;
     struct record *record;
     struct record_cluster *cluster;
@@ -1006,7 +1115,7 @@ struct record *ingest_record(struct client *cl, Z_External *rec,
                              record, (char *) mergekey_norm, 
                              &se->total_merged);
     if (global_parameters.dump_records)
-        yaz_log(YLOG_LOG, "Cluster id %d from %s (#%d)", cluster->recid,
+        yaz_log(YLOG_LOG, "Cluster id %s from %s (#%d)", cluster->recid,
                 client_get_database(cl)->database->url, record_no);
     if (!cluster)
     {