Allow repeated list in limitmap spec
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 6 Dec 2012 16:06:50 +0000 (17:06 +0100)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 6 Dec 2012 16:09:04 +0000 (17:09 +0100)
Separated by comma. For example: value="local:title,rpn:@attr 1=4".

doc/pazpar2_conf.xml
src/client.c

index df8bd6a..60cd710 100644 (file)
        by a field a metadata field (default is to use the name of the 
        limitmap itself).
       </para>
+      <para>
+       For Pazpar2 version 1.6.23 and later the limitmap may include multiple
+       specifications, separated by <literal>,</literal> (comma).
+       For example:
+       <literal>ccl:title,local:ltitle,rpn:@attr 1=4</literal>.
+      </para>
       <note>
        <para>
        The limitmap facility is supported for Pazpar2 version 1.6.0.
index a194a7e..0618d3a 100644 (file)
@@ -1144,17 +1144,28 @@ const char *client_get_facet_limit_local(struct client *cl,
         for (s = sdb->settings[PZ_LIMITMAP]; s; s = s->next)
         {
             const char *p = strchr(s->name + 3, ':');
-            if (p && !strcmp(p + 1, name) && s->value &&
-                !strncmp(s->value, "local:", 6))
+            if (p && !strcmp(p + 1, name) && s->value)
             {
-                const char *cp = s->value + 6;
-                while (*cp == ' ')
-                    cp++;
-
-                nmem_strsplit_escape2(nmem, "|", value, values,
-                                      num, 1, '\\', 1);
-                (*l)++;
-                return *cp ? cp : name;
+                int j, cnum;
+                char **cvalues;
+                nmem_strsplit_escape2(nmem, ",", s->value, &cvalues,
+                                      &cnum, 1, '\\', 1);
+                for (j = 0; j < cnum; j++)
+                {
+                    const char *cvalue = cvalues[j];
+                    while (*cvalue == ' ')
+                        cvalue++;
+                    if (!strncmp(cvalue, "local:", 6))
+                    {
+                        const char *cp = cvalue + 6;
+                        while (*cp == ' ')
+                            cp++;
+                        nmem_strsplit_escape2(nmem, "|", value, values,
+                                              num, 1, '\\', 1);
+                        (*l)++;
+                        return *cp ? cp : name;
+                    }
+                }
             }
         }
     }
@@ -1175,6 +1186,7 @@ static int apply_limit(struct session_database *sdb,
     {
         struct setting *s = 0;
         nmem_reset(nmem_tmp);
+        /* name="pz:limitmap:author" value="rpn:@attr 1=4|local:other" */
         for (s = sdb->settings[PZ_LIMITMAP]; s; s = s->next)
         {
             const char *p = strchr(s->name + 3, ':');
@@ -1182,66 +1194,76 @@ static int apply_limit(struct session_database *sdb,
             {
                 char **values = 0;
                 int i, num = 0;
+                char **cvalues = 0;
+                int j, cnum = 0;
                 nmem_strsplit_escape2(nmem_tmp, "|", value, &values,
                                       &num, 1, '\\', 1);
 
-                if (!strncmp(s->value, "rpn:", 4))
-                {
-                    const char *pqf = s->value + 4;
+                nmem_strsplit_escape2(nmem_tmp, ",", s->value, &cvalues,
+                                      &cnum, 1, '\\', 1);
 
-                    wrbuf_puts(w_pqf, "@and ");
-                    wrbuf_puts(w_pqf, pqf);
-                    wrbuf_puts(w_pqf, " ");
-                    for (i = 0; i < num; i++)
-                    {
-                        if (i < num - 1)
-                            wrbuf_puts(w_pqf, "@or ");
-                        yaz_encode_pqf_term(w_pqf, values[i],
-                                            strlen(values[i]));
-                    }
-                }
-                else if (!strncmp(s->value, "ccl:", 4))
+                for (j = 0; ret == 0 && j < cnum; j++)
                 {
-                    const char *ccl = s->value + 4;
-                    WRBUF ccl_w = wrbuf_alloc();
-                    for (i = 0; i < num; i++)
+                    const char *cvalue = cvalues[j];
+                    while (*cvalue == ' ')
+                        cvalue++;
+                    if (!strncmp(cvalue, "rpn:", 4))
                     {
-                        int cerror, cpos;
-                        struct ccl_rpn_node *cn;
-
-                        wrbuf_rewind(ccl_w);
-                        wrbuf_puts(ccl_w, ccl);
-                        wrbuf_puts(ccl_w, "=\"");
-                        wrbuf_puts(ccl_w, values[i]);
-                        wrbuf_puts(ccl_w, "\"");
-
-                        cn = ccl_find_str(ccl_map, wrbuf_cstr(ccl_w),
-                                          &cerror, &cpos);
-                        if (cn)
+                        const char *pqf = cvalue + 4;
+                        wrbuf_puts(w_pqf, "@and ");
+                        wrbuf_puts(w_pqf, pqf);
+                        wrbuf_puts(w_pqf, " ");
+                        for (i = 0; i < num; i++)
                         {
-                            if (i == 0)
-                                wrbuf_printf(w_pqf, "@and ");
-
-                            /* or multiple values.. could be bad if last CCL
-                               parse fails, but this is unlikely to happen */
                             if (i < num - 1)
-                                wrbuf_printf(w_pqf, "@or ");
-                            ccl_pquery(w_pqf, cn);
-                            ccl_rpn_delete(cn);
+                                wrbuf_puts(w_pqf, "@or ");
+                            yaz_encode_pqf_term(w_pqf, values[i],
+                                                strlen(values[i]));
                         }
                     }
-                    wrbuf_destroy(ccl_w);
-                }
-                else if (!strncmp(s->value, "local:", 6)) {
-                    /* no operation */
-                }
-                else
-                {
-                    yaz_log(YLOG_WARN, "Target %s: Bad limitmap '%s'",
-                            sdb->database->id, s->value);
-                    ret = -1; /* bad limitmap */
+                    else if (!strncmp(cvalue, "ccl:", 4))
+                    {
+                        const char *ccl = cvalue + 4;
+                        WRBUF ccl_w = wrbuf_alloc();
+                        for (i = 0; i < num; i++)
+                        {
+                            int cerror, cpos;
+                            struct ccl_rpn_node *cn;
+                            wrbuf_rewind(ccl_w);
+                            wrbuf_puts(ccl_w, ccl);
+                            wrbuf_puts(ccl_w, "=\"");
+                            wrbuf_puts(ccl_w, values[i]);
+                            wrbuf_puts(ccl_w, "\"");
+
+                            cn = ccl_find_str(ccl_map, wrbuf_cstr(ccl_w),
+                                              &cerror, &cpos);
+                            if (cn)
+                            {
+                                if (i == 0)
+                                    wrbuf_printf(w_pqf, "@and ");
+
+                                /* or multiple values.. could be bad if last
+                                   CCL parse fails, but this is unlikely to
+                                   happen */
+                                if (i < num - 1)
+                                    wrbuf_printf(w_pqf, "@or ");
+                                ccl_pquery(w_pqf, cn);
+                                ccl_rpn_delete(cn);
+                            }
+                        }
+                        wrbuf_destroy(ccl_w);
+                    }
+                    else if (!strncmp(cvalue, "local:", 6)) {
+                        /* no operation */
+                    }
+                    else
+                    {
+                        yaz_log(YLOG_WARN, "Target %s: Bad limitmap '%s'",
+                                sdb->database->id, cvalue);
+                        ret = -1; /* bad limitmap */
+                    }
+                    break;
                 }
-                break;
             }
         }
         if (!s)