Conf pz:limitmap may perform local filtering
[pazpar2-moved-to-github.git] / src / client.c
index c9ac78f..9e0f903 100644 (file)
@@ -121,6 +121,7 @@ struct client {
     YAZ_MUTEX mutex;
     int ref_count;
     char *id;
+    facet_limits_t facet_limits;
 };
 
 struct suggestions {
@@ -827,6 +828,7 @@ struct client *client_create(const char *id)
     pazpar2_mutex_create(&cl->mutex, "client");
     cl->preferred = 0;
     cl->ref_count = 1;
+    cl->facet_limits = 0;
     assert(id);
     cl->id = xstrdup(id);
     client_use(1);
@@ -865,6 +867,7 @@ int client_destroy(struct client *c)
             c->cqlquery = 0;
             xfree(c->id);
             assert(!c->connection);
+            facet_limits_destroy(c->facet_limits);
 
             if (c->resultset)
             {
@@ -988,10 +991,38 @@ static char *make_solrquery(struct client *cl)
     return r;
 }
 
-static void apply_limit(struct session_database *sdb,
-                        facet_limits_t facet_limits,
-                        WRBUF w_pqf, WRBUF w_ccl)
+const char *client_get_facet_limit_local(struct client *cl,
+                                         struct session_database *sdb,
+                                         int *l,
+                                         NMEM nmem, int *num, char ***values)
 {
+    const char *name = 0;
+    const char *value = 0;
+    for (; (name = facet_limits_get(cl->facet_limits, *l, &value)); (*l)++)
+    {
+        struct setting *s = 0;
+        
+        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))
+            {
+                nmem_strsplit_escape2(nmem, "|", value, values,
+                                      num, 1, '\\', 1);
+                (*l)++;
+                return name;
+            }
+        }
+    }
+    return 0;
+}
+
+static int apply_limit(struct session_database *sdb,
+                       facet_limits_t facet_limits,
+                       WRBUF w_pqf, WRBUF w_ccl)
+{
+    int ret = 0;
     int i = 0;
     const char *name;
     const char *value;
@@ -1043,6 +1074,14 @@ static void apply_limit(struct session_database *sdb,
                     wrbuf_puts(w_ccl, ")");
 
                 }
+                else if (!strncmp(s->value, "local:", 6))
+                    ;
+                else
+                {
+                    yaz_log(YLOG_WARN, "Target %s: Bad limitmap '%s'",
+                            sdb->database->id, s->value);
+                    ret = -1; /* bad limitmap */
+                }
                 break;
             }
         }
@@ -1054,6 +1093,7 @@ static void apply_limit(struct session_database *sdb,
         }
     }
     nmem_destroy(nmem_tmp);
+    return ret;
 }
                         
 // Parse the query given the settings specific to this client
@@ -1099,7 +1139,11 @@ int client_parse_query(struct client *cl, const char *query,
         wrbuf_puts(w_pqf, " ");
     }
 
-    apply_limit(sdb, facet_limits, w_pqf, w_ccl);
+    if (apply_limit(sdb, facet_limits, w_pqf, w_ccl))
+        return -2;
+
+    facet_limits_destroy(cl->facet_limits);
+    cl->facet_limits = facet_limits_dup(facet_limits);
 
     yaz_log(YLOG_LOG, "CCL query: %s", wrbuf_cstr(w_ccl));
     cn = ccl_find_str(ccl_map, wrbuf_cstr(w_ccl), &cerror, &cpos);