New merge attribute type: 'first'
authorAdam Dickmeiss <adam@indexdata.dk>
Fri, 18 Jan 2013 12:39:40 +0000 (13:39 +0100)
committerAdam Dickmeiss <adam@indexdata.dk>
Fri, 18 Jan 2013 12:39:57 +0000 (13:39 +0100)
which takes all metadata fields from first target that
returns the particular field.

doc/pazpar2_conf.xml
src/pazpar2_config.c
src/pazpar2_config.h
src/session.c

index a45d77d..fbd39fb 100644 (file)
             all elements), or 'no' (don't merge; this is the
             default);
            </para>
+           <para>
+            Pazpar 1.6.24 also offers a new value for merge, 'first', which
+            is like 'all' but only takes all from first database that returns
+            the particular metadata field.
+           </para>
           </listitem>
          </varlistentry>
          
index fa06db7..22e047d 100644 (file)
@@ -385,6 +385,8 @@ static int parse_metadata(struct conf_service *service, xmlNode *n,
             merge = Metadata_merge_range;
         else if (!strcmp((const char *) xml_merge, "all"))
             merge = Metadata_merge_all;
+        else if (!strcmp((const char *) xml_merge, "first"))
+            merge = Metadata_merge_first;
         else
         {
             yaz_log(YLOG_FATAL,
index 3487e36..c20bae6 100644 (file)
@@ -41,7 +41,8 @@ enum conf_metadata_merge {
     Metadata_merge_unique,    // Include unique elements in merged block
     Metadata_merge_longest,   // Include the longest (strlen) value
     Metadata_merge_range,     // Store value as a range of lowest-highest
-    Metadata_merge_all        // Just include all elements found
+    Metadata_merge_all,       // Just include all elements found
+    Metadata_merge_first      // All from first target
 };
 
 enum conf_sortkey_type {
index 6071726..ec2f270 100644 (file)
@@ -1781,6 +1781,7 @@ static int ingest_to_cluster(struct client *cl,
     struct conf_service *service = se->service;
     int term_factor = 1;
     struct record_cluster *cluster;
+    struct record_metadata **metadata0;
     struct session_database *sdb = client_get_database(cl);
     struct record *record = record_create(se->nmem,
                                           service->num_metadata,
@@ -1876,6 +1877,11 @@ static int ingest_to_cluster(struct client *cl,
 
     relevance_newrec(se->relevance, cluster);
 
+    // original metadata, to check if first existence of a field
+    metadata0 = xmalloc(sizeof(*metadata0) * service->num_metadata);
+    memcpy(metadata0, cluster->metadata,
+           sizeof(*metadata0) * service->num_metadata);
+
     // now parsing XML record and adding data to cluster or record metadata
     for (n = root->children; n; n = n->next)
     {
@@ -1921,6 +1927,9 @@ static int ingest_to_cluster(struct client *cl,
             // merged metadata
             rec_md = record_metadata_init(se->nmem, (const char *) value,
                                           ser_md->type, 0);
+
+            // see if the field was not in cluster already (from beginning)
+
             if (!rec_md)
                 continue;
 
@@ -1929,9 +1938,16 @@ static int ingest_to_cluster(struct client *cl,
 
             wheretoput = &cluster->metadata[md_field_id];
 
-            // and polulate with data:
-            // assign cluster or record based on merge action
-            if (ser_md->merge == Metadata_merge_unique)
+            if (ser_md->merge == Metadata_merge_first)
+            {
+                if (!metadata0[md_field_id])
+                {
+                    while (*wheretoput)
+                        wheretoput = &(*wheretoput)->next;
+                    *wheretoput = rec_md;
+                }
+            }
+            else if (ser_md->merge == Metadata_merge_unique)
             {
                 while (*wheretoput)
                 {
@@ -2057,6 +2073,7 @@ static int ingest_to_cluster(struct client *cl,
     if (value)
         xmlFree(value);
 
+    xfree(metadata0);
     relevance_donerecord(se->relevance, cluster);
     se->total_records++;