Mergekey changes - order + required/optional.
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 7 Oct 2009 10:27:10 +0000 (12:27 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 7 Oct 2009 10:27:10 +0000 (12:27 +0200)
The metadata attribute 'mergekey' now takes one of three values 'no',
'required', 'optional' .  And the resulting mergekey from metadata
is now ordered in the same way as metadata in the service definition.
Older Pazpar2 version use the order in which metadata appeared in a
record instance.

NEWS
doc/pazpar2_conf.xml
src/logic.c
src/pazpar2_config.c
src/pazpar2_config.h

diff --git a/NEWS b/NEWS
index 055ce8a..c4eacb3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+The metadata attribute 'mergekey' now takes one of three values 'no',
+'required', 'optional' .  And the resulting mergekey from metadata
+is now ordered in the same way as metadata in the service definition.
+Older Pazpar2 version use the order in which metadata appeared in a
+record instance.
+
 Pazpar2 allows YAZ log level to be set (option -v).
 
 --- 1.2.1 2009/10/05
index d425733..6dca610 100644 (file)
          <varlistentry><term>mergekey</term>
           <listitem>
            <para>
-            If set to <literal>yes</literal>, the value of this
-            metadata element is appended to the resulting mergekey.
-            By default metadata is not part of a mergekey.
+            If set to '<literal>required</literal>', the value of this
+            metadata element is appended to the resulting mergekey if
+            the metadata is present in a record instance.
+            If the metadata element is not present, the a unique mergekey
+            will be generated instead.
+           </para>
+           <para>
+            If set to '<literal>optional</literal>', the value of this
+            metadata element is appended to the resulting mergekey if the
+            the metadata is present in a record instance. If the metadata
+            is not present, it will be empty.
+           </para>
+           <para>
+            If set to '<literal>no</literal>' or the mergekey attribute is
+            omitted, the metadata will not be used in the creation of a
+            mergekey.
            </para>
           </listitem>
          </varlistentry>
index 3a442e1..09fb3fd 100644 (file)
@@ -949,13 +949,58 @@ static struct record_metadata *record_metadata_init(
     return rec_md;
 }
 
+static int get_mergekey_from_doc(xmlDoc *doc, xmlNode *root, const char *name,
+                                 struct conf_service *service, WRBUF norm_wr)
+{
+    xmlNode *n;
+    int no_found = 0;
+    for (n = root->children; n; n = n->next)
+    {
+        if (n->type != XML_ELEMENT_NODE)
+            continue;
+        if (!strcmp((const char *) n->name, "metadata"))
+        {
+            xmlChar *type = xmlGetProp(n, (xmlChar *) "type");
+            if (!strcmp(name, (const char *) type))
+            {
+                xmlChar *value = xmlNodeListGetString(doc, n->children, 1);
+                if (value)
+                {
+                    const char *norm_str;
+                    pp2_relevance_token_t prt =
+                        pp2_relevance_tokenize(
+                            service->mergekey_pct,
+                            (const char *) value);
+                    
+                    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, norm_str);
+                        }
+                    }
+                    xmlFree(value);
+                    pp2_relevance_token_destroy(prt);
+                    no_found++;
+                }
+            }
+            xmlFree(type);
+        }
+    }
+    return no_found;
+}
+
 static const char *get_mergekey(xmlDoc *doc, struct client *cl, int record_no,
                                 struct conf_service *service, NMEM nmem)
 {
     char *mergekey_norm = 0;
     xmlNode *root = xmlDocGetRootElement(doc);
     WRBUF norm_wr = wrbuf_alloc();
-    xmlNode *n;
 
     /* consider mergekey from XSL first */
     xmlChar *mergekey = xmlGetProp(root, (xmlChar *) "mergekey");
@@ -982,52 +1027,21 @@ static const char *get_mergekey(xmlDoc *doc, struct client *cl, int record_no,
     else
     {
         /* no mergekey defined in XSL. Look for mergekey metadata instead */
-        for (n = root->children; n; n = n->next)
+        int field_id;
+        for (field_id = 0; field_id < service->num_metadata; field_id++)
         {
-            if (n->type != XML_ELEMENT_NODE)
-                continue;
-            if (!strcmp((const char *) n->name, "metadata"))
+            struct conf_metadata *ser_md = &service->metadata[field_id];
+            if (ser_md->mergekey != Metadata_mergekey_no)
             {
-                struct conf_metadata *ser_md = 0;
-                int md_field_id = -1;
-                
-                xmlChar *type = xmlGetProp(n, (xmlChar *) "type");
-                
-                if (!type)
-                    continue;
-                
-                md_field_id 
-                    = conf_service_metadata_field_id(service, 
-                                                     (const char *) type);
-                if (md_field_id >= 0)
+                int r = get_mergekey_from_doc(doc, root, ser_md->name,
+                                              service, norm_wr);
+                if (r == 0 && ser_md->mergekey == Metadata_mergekey_required)
                 {
-                    ser_md = &service->metadata[md_field_id];
-                    if (ser_md->mergekey == Metadata_mergekey_yes)
-                    {
-                        xmlChar *value = xmlNodeListGetString(doc, n->children, 1);
-                        if (value)
-                        {
-                            const char *norm_str;
-                            pp2_relevance_token_t prt =
-                                pp2_relevance_tokenize(
-                                    service->mergekey_pct,
-                                    (const char *) value);
-                            
-                            while ((norm_str = pp2_relevance_token_next(prt)))
-                            {
-                                if (*norm_str)
-                                {
-                                    if (wrbuf_len(norm_wr))
-                                        wrbuf_puts(norm_wr, " ");
-                                    wrbuf_puts(norm_wr, norm_str);
-                                }
-                            }
-                            xmlFree(value);
-                            pp2_relevance_token_destroy(prt);
-                        }
-                    }
+                    /* no mergekey on this one and it is required.. 
+                       Generate unique key instead */
+                    wrbuf_rewind(norm_wr);
+                    break;
                 }
-                xmlFree(type);
             }
         }
     }
index 60f1585..a350786 100644 (file)
@@ -409,9 +409,19 @@ static int parse_metadata(struct conf_service *service, xmlNode *n,
     else
         sortkey_offset = -1;
     
-    if (xml_mergekey && strcmp((const char *) xml_mergekey, "no"))
+    if (xml_mergekey)
     {
-        mergekey_type = Metadata_mergekey_yes;
+        if (!strcmp((const char *) xml_mergekey, "required"))
+            mergekey_type = Metadata_mergekey_required;
+        else if (!strcmp((const char *) xml_mergekey, "optional"))
+            mergekey_type = Metadata_mergekey_optional;
+        else if (!strcmp((const char *) xml_mergekey, "no"))
+            mergekey_type = Metadata_mergekey_no;
+        else
+        {
+            yaz_log(YLOG_FATAL, "Unknown value for mergekey: %s", xml_mergekey);
+            return -1;
+        }
     }
     
     
@@ -430,6 +440,7 @@ static int parse_metadata(struct conf_service *service, xmlNode *n,
     xmlFree(xml_termlist);
     xmlFree(xml_rank);
     xmlFree(xml_setting);
+    xmlFree(xml_mergekey);
     (*md_node)++;
     return 0;
 }
index ab0c46a..044eff7 100644 (file)
@@ -57,7 +57,8 @@ enum conf_setting_type {
 
 enum conf_metadata_mergekey {
     Metadata_mergekey_no,
-    Metadata_mergekey_yes
+    Metadata_mergekey_optional,
+    Metadata_mergekey_required
 };
 
 // Describes known metadata elements and how they are to be manipulated