pz:limitmap now in use
authorAdam Dickmeiss <adam@indexdata.dk>
Fri, 9 Sep 2011 13:01:39 +0000 (15:01 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Fri, 9 Sep 2011 13:01:39 +0000 (15:01 +0200)
pz:limitmap[name] is used as query translation when applying
limit parameter for search. Previously, pz:facetmap was used.
pz:limitmap[name] can have one of two forms (types). The leading
type is followed immedately by colon then by form specific name.
For type "ccl:" the value is an existing cclmap.  Example:
limitmap[author]="ccl:au", which could work for many existing Z39.50
targets. For type "rpn:" the value is PQF verbatim. Example:
limitmap[author]="rpn:@attr 1=1003 @attr 6=3" (author, complete field).

13 files changed:
src/client.c
src/session.c
src/session.h
src/settings.c
src/settings.h
test/test_http.urls
test/test_http_58.res [new file with mode: 0644]
test/test_http_59.res [new file with mode: 0644]
test/test_http_60.res [new file with mode: 0644]
test/test_http_61.res [new file with mode: 0644]
test/test_http_62.res [new file with mode: 0644]
test/test_http_63.res [new file with mode: 0644]
test/z3950_indexdata_com_marc.xml

index 9367153..c8945f8 100644 (file)
@@ -947,7 +947,7 @@ static char *make_solrquery(struct client *cl)
 
 static void apply_limit(struct session_database *sdb,
                         facet_limits_t facet_limits,
-                        WRBUF w)
+                        WRBUF w_pqf, WRBUF w_ccl)
 {
     int i = 0;
     const char *name;
@@ -956,22 +956,34 @@ static void apply_limit(struct session_database *sdb,
     {
         struct setting *s = 0;
         
-        for (s = sdb->settings[PZ_FACETMAP]; s; s = s->next)
+        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 && s->value[0])
+            if (p && !strcmp(p + 1, name) && s->value)
             {
-                wrbuf_insert(w, 0, "@and ", 5);
-                wrbuf_puts(w, " @attr 1=");
-                yaz_encode_pqf_term(w, s->value, strlen(s->value));
-                wrbuf_puts(w, " ");
-                yaz_encode_pqf_term(w, value, strlen(value));
+                if (!strncmp(s->value, "rpn:", 4))
+                {
+                    const char *pqf = s->value + 4;
+                    wrbuf_puts(w_pqf, "@and ");
+                    wrbuf_puts(w_pqf, pqf);
+                    wrbuf_puts(w_pqf, " ");
+                    yaz_encode_pqf_term(w_pqf, value, strlen(value));
+                }
+                else if (!strncmp(s->value, "ccl:", 4))
+                {
+                    const char *ccl = s->value + 4;
+                    wrbuf_puts(w_ccl, " and ");
+                    wrbuf_puts(w_ccl, ccl);
+                    wrbuf_puts(w_ccl, "=\"");
+                    wrbuf_puts(w_ccl, value);
+                    wrbuf_puts(w_ccl, "\"");
+                }
                 break;
             }
         }
         if (!s)
         {
-            yaz_log(YLOG_WARN, "facet %s used, but no facetmap defined",
+            yaz_log(YLOG_WARN, "limit %s used, but no limitmap defined",
                     name);
         }
     }
@@ -990,32 +1002,39 @@ int client_parse_query(struct client *cl, const char *query,
     const char *pqf_prefix = session_setting_oneval(sdb, PZ_PQF_PREFIX);
     const char *pqf_strftime = session_setting_oneval(sdb, PZ_PQF_STRFTIME);
     const char *query_syntax = session_setting_oneval(sdb, PZ_QUERY_SYNTAX);
-    const char *record_filter = session_setting_oneval(sdb, PZ_RECORDFILTER);
+    WRBUF w_ccl, w_pqf;
     if (!ccl_map)
         return -1;
 
-    yaz_log(YLOG_DEBUG, "query: %s", query);
-    cn = ccl_find_str(ccl_map, query, &cerror, &cpos);
+    w_ccl = wrbuf_alloc();
+    wrbuf_puts(w_ccl, query);
+
+    w_pqf = wrbuf_alloc();
+    if (*pqf_prefix)
+    {
+        wrbuf_puts(w_pqf, pqf_prefix);
+        wrbuf_puts(w_pqf, " ");
+    }
+
+    apply_limit(sdb, facet_limits, w_pqf, w_ccl);
+
+    yaz_log(YLOG_LOG, "CCL query: %s", wrbuf_cstr(w_ccl));
+    cn = ccl_find_str(ccl_map, wrbuf_cstr(w_ccl), &cerror, &cpos);
     ccl_qual_rm(&ccl_map);
     if (!cn)
     {
         client_set_state(cl, Client_Error);
         session_log(se, YLOG_WARN, "Failed to parse CCL query '%s' for %s",
-                query,
-                client_get_database(cl)->database->url);
+                    wrbuf_cstr(w_ccl),
+                    client_get_database(cl)->database->url);
+        wrbuf_destroy(w_ccl);
+        wrbuf_destroy(w_pqf);
         return -1;
     }
-    wrbuf_rewind(se->wrbuf);
-    if (*pqf_prefix)
-    {
-        wrbuf_puts(se->wrbuf, pqf_prefix);
-        wrbuf_puts(se->wrbuf, " ");
-    }
-
-    apply_limit(sdb, facet_limits, se->wrbuf);
+    wrbuf_destroy(w_ccl);
 
     if (!pqf_strftime || !*pqf_strftime)
-        ccl_pquery(se->wrbuf, cn);
+        ccl_pquery(w_pqf, cn);
     else
     {
         time_t cur_time = time(0);
@@ -1029,15 +1048,16 @@ int client_parse_query(struct client *cl, const char *query,
         for (; *cp; cp++)
         {
             if (cp[0] == '%')
-                ccl_pquery(se->wrbuf, cn);
+                ccl_pquery(w_pqf, cn);
             else
-                wrbuf_putc(se->wrbuf, cp[0]);
+                wrbuf_putc(w_pqf, cp[0]);
         }
     }
     xfree(cl->pquery);
-    cl->pquery = xstrdup(wrbuf_cstr(se->wrbuf));
+    cl->pquery = xstrdup(wrbuf_cstr(w_pqf));
+    wrbuf_destroy(w_pqf);
 
-    yaz_log(YLOG_DEBUG, "PQF query: %s", cl->pquery);
+    yaz_log(YLOG_LOG, "PQF query: %s", cl->pquery);
 
     xfree(cl->cqlquery);
 
index 373dd49..2adb1eb 100644 (file)
@@ -782,7 +782,6 @@ void session_destroy(struct session *se) {
     nmem_destroy(se->nmem);
     service_destroy(se->service);
     yaz_mutex_destroy(&se->session_mutex);
-    wrbuf_destroy(se->wrbuf);
 }
 
 /* Depreciated: use session_destroy */
@@ -825,7 +824,6 @@ struct session *new_session(NMEM nmem, struct conf_service *service,
     session->clients = 0;
     session->session_nmem = nmem;
     session->nmem = nmem_create();
-    session->wrbuf = wrbuf_alloc();
     session->databases = 0;
     for (i = 0; i <= SESSION_WATCH_MAX; i++)
     {
index ec699ee..2c943d9 100644 (file)
@@ -107,7 +107,6 @@ struct session {
     struct client_list *clients;   // Clients connected for current search
     NMEM session_nmem;  // Nmem for session-permanent storage
     NMEM nmem;          // Nmem for each operation (i.e. search, result set, etc)
-    WRBUF wrbuf;        // Wrbuf for scratch(i.e. search)
     int num_termlists;
     struct named_termlist termlists[SESSION_MAX_TERMLISTS];
     struct relevance *relevance;
index b8c1d0a..3455344 100644 (file)
@@ -77,6 +77,7 @@ static char *hard_settings[] = {
     "pz:query_syntax",          /* PZ_QUERY_SYNTAX        */
     "pz:option_recordfilter",   /* PZ_OPTION_RECORDFILTER */
     "pz:facetmap:",             /* PZ_FACETMAP */
+    "pz:limitmap:",             /* PZ_LIMITMAP */
     0
 };
 
index 5862b9e..e6e70f4 100644 (file)
@@ -50,7 +50,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #define PZ_QUERY_SYNTAX         27
 #define PZ_OPTION_RECORDFILTER  28
 #define PZ_FACETMAP             29
-#define PZ_MAX_EOF              30
+#define PZ_LIMITMAP             30
+#define PZ_MAX_EOF              31
 
 struct setting
 {
index e94d528..945d805 100644 (file)
@@ -55,3 +55,9 @@ http://localhost:9763/search.pz2?session=8&command=search&query=xyzzyz
 2 http://localhost:9763/search.pz2?session=8&command=show&block=1
 http://localhost:9763/search.pz2?session=8&command=search&query=a+and
 1 http://localhost:9763/search.pz2?session=8&command=show&block=1
+http://localhost:9763/search.pz2?command=init&pz:limitmap:author%5Bz3950.indexdata.com%2Fmarc%5D=ccl:author_phrase
+1 http://localhost:9763/search.pz2?session=9&command=search&query=greece&limit=author%3dadam\,+james
+1 http://localhost:9763/search.pz2?session=9&command=show&block=1
+http://localhost:9763/search.pz2?session=9&command=settings&pz:limitmap:author%5Bz3950.indexdata.com%2Fmarc%5D=rpn:%40attr+1%3d1003+%40attr+6%3d3
+1 http://localhost:9763/search.pz2?session=9&command=search&query=greece&limit=author%3dadam\,+james
+1 http://localhost:9763/search.pz2?session=9&command=show&block=1
diff --git a/test/test_http_58.res b/test/test_http_58.res
new file mode 100644 (file)
index 0000000..b36de12
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<init><status>OK</status><session>9</session><protocol>1</protocol></init>
\ No newline at end of file
diff --git a/test/test_http_59.res b/test/test_http_59.res
new file mode 100644 (file)
index 0000000..ab63fe6
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<search><status>OK</status></search>
\ No newline at end of file
diff --git a/test/test_http_60.res b/test/test_http_60.res
new file mode 100644 (file)
index 0000000..f6ca445
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<show>
+<status>OK</status>
+<activeclients>0</activeclients>
+<merged>1</merged>
+<total>1</total>
+<start>0</start>
+<num>1</num>
+<hit>
+
+<md-title>The religious teachers of Greece</md-title>
+<md-date>1972</md-date>
+<md-author>Adam, James</md-author>
+<md-description>Reprint of the 1909 ed., which was issued as the 1904-1906 Gifford lectures</md-description><location id="z3950.indexdata.com/marc" name="Index Data MARC test server">
+<md-title>The religious teachers of Greece</md-title>
+<md-date>1972</md-date>
+<md-author>Adam, James</md-author>
+<md-description tag="500">Reprint of the 1909 ed., which was issued as the 1904-1906 Gifford lectures</md-description>
+<md-description tag="504">Includes bibliographical references</md-description>
+<md-test-usersetting>XXXXXXXXXX</md-test-usersetting>
+<md-test-usersetting-2>test-usersetting-2 data: 
+        YYYYYYYYY</md-test-usersetting-2></location>
+<relevance>320000</relevance>
+<recid>title the religious teachers of greece author adam james medium book</recid>
+</hit>
+</show>
diff --git a/test/test_http_61.res b/test/test_http_61.res
new file mode 100644 (file)
index 0000000..42534e3
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<settings><status>OK</status></settings>
\ No newline at end of file
diff --git a/test/test_http_62.res b/test/test_http_62.res
new file mode 100644 (file)
index 0000000..ab63fe6
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<search><status>OK</status></search>
\ No newline at end of file
diff --git a/test/test_http_63.res b/test/test_http_63.res
new file mode 100644 (file)
index 0000000..43fcf8b
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<show>
+<status>OK</status>
+<activeclients>0</activeclients>
+<merged>1</merged>
+<total>1</total>
+<start>0</start>
+<num>1</num>
+<hit>
+
+<md-title>The religious teachers of Greece</md-title>
+<md-date>1972</md-date>
+<md-author>Adam, James</md-author>
+<md-description>Reprint of the 1909 ed., which was issued as the 1904-1906 Gifford lectures</md-description><location id="z3950.indexdata.com/marc" name="Index Data MARC test server">
+<md-title>The religious teachers of Greece</md-title>
+<md-date>1972</md-date>
+<md-author>Adam, James</md-author>
+<md-description tag="500">Reprint of the 1909 ed., which was issued as the 1904-1906 Gifford lectures</md-description>
+<md-description tag="504">Includes bibliographical references</md-description>
+<md-test-usersetting>XXXXXXXXXX</md-test-usersetting>
+<md-test-usersetting-2>test-usersetting-2 data: 
+        YYYYYYYYY</md-test-usersetting-2></location>
+<relevance>120000</relevance>
+<recid>title the religious teachers of greece author adam james medium book</recid>
+</hit>
+</show>
index 7792ece..a362da1 100644 (file)
@@ -10,6 +10,7 @@
   <set name="pz:cclmap:isbn" value="u=7"/>
   <set name="pz:cclmap:issn" value="u=8"/>
   <set name="pz:cclmap:date" value="u=30 r=r"/>
+  <set name="pz:cclmap:author_phrase" value="u=1003 6=3"/>
 
   <!-- Retrieval settings -->