SRU 1.1 sorting for ZOOM_query_sortby2
authorAdam Dickmeiss <adam@indexdata.dk>
Tue, 6 Sep 2011 14:26:59 +0000 (16:26 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Tue, 6 Sep 2011 14:26:59 +0000 (16:26 +0200)
include/yaz/sortspec.h
src/sortspec.c
src/zoom-p.h
src/zoom-query.c
src/zoom-sru.c
test/test_sortspec.c

index eb2ccdd..dfc8d87 100644 (file)
@@ -82,6 +82,14 @@ YAZ_EXPORT int yaz_sort_spec_to_cql(Z_SortKeySpecList *sksl, WRBUF w);
 */
 YAZ_EXPORT int yaz_sort_spec_to_type7(Z_SortKeySpecList *sksl, WRBUF pqf);
 
+/* \brief converts Z39.50 SortKeySpecList to SRU 1.1 sort key
+   \param sksl SortKeySpecList
+   \param w resulting sortkey will be appended to this
+   \retval 0 successful
+   \retval -1 failure
+*/
+YAZ_EXPORT int yaz_sort_spec_to_srw_sortkeys(Z_SortKeySpecList *sksl, WRBUF w);
+
 YAZ_END_CDECL
 
 #endif
index 76e0f2f..ed795ea 100644 (file)
@@ -233,6 +233,65 @@ int yaz_sort_spec_to_type7(Z_SortKeySpecList *sksl, WRBUF pqf)
     return 0;
 }
 
+int yaz_sort_spec_to_srw_sortkeys(Z_SortKeySpecList *sksl, WRBUF w)
+{
+    int i;
+    for (i = 0; i < sksl->num_specs; i++)
+    {
+        Z_SortKeySpec *sks = sksl->specs[i];
+        Z_SortKey *sk;
+
+        if (sks->sortElement->which != Z_SortElement_generic)
+            return -1;
+
+        sk = sks->sortElement->u.generic;
+
+        if (i)
+            wrbuf_puts(w, " ");
+
+        if (sk->which == Z_SortKey_sortAttributes)
+            return -1;
+        else if (sk->which == Z_SortKey_sortField)
+        {
+            wrbuf_puts(w, sk->u.sortField);
+        }
+        wrbuf_puts(w, ",,"); /* path is absent */
+        switch (*sks->sortRelation)
+        {
+        case Z_SortKeySpec_ascending:
+            wrbuf_puts(w, "1");
+            break;
+        case Z_SortKeySpec_descending:
+            wrbuf_puts(w, "0");
+            break;
+        }
+        wrbuf_puts(w, ",");
+        switch (*sks->caseSensitivity)
+        {
+        case Z_SortKeySpec_caseSensitive:
+            wrbuf_puts(w, "1");
+            break;
+        case Z_SortKeySpec_caseInsensitive:
+            wrbuf_puts(w, "0");
+            break;
+        }
+        wrbuf_puts(w, ",");
+        switch (sks->which)
+        {
+        case Z_SortKeySpec_null:
+            wrbuf_puts(w, "highValue");
+            break;
+        case Z_SortKeySpec_abort:
+            wrbuf_puts(w, "abort");
+            break;
+        case Z_SortKeySpec_missingValueData:
+            wrbuf_write(w, (const char *) sks->u.missingValueData->buf,
+                        sks->u.missingValueData->len);
+        }
+    }
+    return 0;
+}
+
 
 /*
  * Local variables:
index b62ad3b..6daf6d1 100644 (file)
@@ -264,6 +264,7 @@ void ZOOM_record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr,
 Z_Query *ZOOM_query_get_Z_Query(ZOOM_query s);
 Z_SortKeySpecList *ZOOM_query_get_sortspec(ZOOM_query s);
 const char *ZOOM_query_get_query_string(ZOOM_query s);
+const char *ZOOM_query_get_sru11(ZOOM_query s);
 
 int ZOOM_uri_to_code(const char *uri);
 
index e80b235..0bb9616 100644 (file)
@@ -39,6 +39,7 @@ struct ZOOM_query_p {
     int query_type;
     char *query_string;
     WRBUF full_query;
+    WRBUF sru11_sort_spec;
 };
 
 static int generate(ZOOM_query s)
@@ -51,6 +52,16 @@ static int generate(ZOOM_query s)
         wrbuf_puts(s->full_query, s->query_string);
         odr_reset(s->odr_query);
 
+        if (s->sort_spec && s->sort_strategy == SORT_STRATEGY_SRU11)
+        {
+            int r;
+            wrbuf_rewind(s->sru11_sort_spec);
+
+            r = yaz_sort_spec_to_srw_sortkeys(s->sort_spec,
+                                              s->sru11_sort_spec);
+            if (r)
+                return r;
+        }
         switch (s->query_type)
         {
         case Z_Query_type_1: /* RPN */
@@ -100,6 +111,13 @@ static int generate(ZOOM_query s)
     return 0;
 }
 
+const char *ZOOM_query_get_sru11(ZOOM_query s)
+{
+    if (wrbuf_len(s->sru11_sort_spec))
+        return wrbuf_cstr(s->sru11_sort_spec);
+    return 0;
+}
+
 Z_Query *ZOOM_query_get_Z_Query(ZOOM_query s)
 {
     return s->z_query;
@@ -192,6 +210,7 @@ ZOOM_API(ZOOM_query)
     s->query_string = 0;
     s->full_query = wrbuf_alloc();
     s->sort_strategy = SORT_STRATEGY_Z3950;
+    s->sru11_sort_spec = wrbuf_alloc();
     return s;
 }
 
@@ -208,6 +227,7 @@ ZOOM_API(void)
         odr_destroy(s->odr_sort_spec);
         xfree(s->query_string);
         wrbuf_destroy(s->full_query);
+        wrbuf_destroy(s->sru11_sort_spec);
         xfree(s);
     }
 }
index d52372f..08a18a2 100644 (file)
@@ -217,6 +217,13 @@ zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
         ZOOM_set_error(c, ZOOM_ERROR_UNSUPPORTED_QUERY, 0);
         return zoom_complete;
     }
+   
+    option_val = ZOOM_query_get_sru11(resultset->query);
+    if (option_val)
+    {
+        sr->u.request->sort_type = Z_SRW_sort_type_sort;
+        sr->u.request->sort.sortKeys = odr_strdup(c->odr_out, option_val);
+    }
     sr->u.request->startRecord = odr_intdup(c->odr_out, *start + 1);
     sr->u.request->maximumRecords = odr_intdup(
         c->odr_out, (resultset->step > 0 && resultset->step < *count) ? 
index 1af0f1f..66093f8 100644 (file)
@@ -107,6 +107,52 @@ static int type7(const char *arg, const char *expected_result)
     return ret;
 }
 
+static int srw_sortkeys(const char *arg, const char *expected_result)
+{
+    ODR odr = odr_createmem(ODR_ENCODE);
+    Z_SortKeySpecList *sort_spec = yaz_sort_spec(odr, arg);
+    int ret = 0;
+
+    if (!sort_spec)
+    {
+        yaz_log(YLOG_WARN, "yaz_sort_spec : parse error: %s", arg);
+    }
+    else
+    {
+        WRBUF w = wrbuf_alloc();
+        int r = yaz_sort_spec_to_srw_sortkeys(sort_spec, w);
+
+        if (!expected_result && r)
+            ret = 1;
+        else if (expected_result && r == 0)
+        {
+            if (strcmp(wrbuf_cstr(w), expected_result) == 0)
+                ret = 1;
+            else
+            {
+                yaz_log(YLOG_WARN, "sort: diff: %s", arg);
+                yaz_log(YLOG_WARN, " expected %s", expected_result);
+                yaz_log(YLOG_WARN, " got      %s", wrbuf_cstr(w));
+            }
+        }
+        else if (r)
+        {
+            yaz_log(YLOG_WARN, "sort: diff %s", arg);
+            yaz_log(YLOG_WARN, " expected %s", expected_result);
+            yaz_log(YLOG_WARN, " got error %d", r);
+        }
+        else if (r == 0)
+        {
+            yaz_log(YLOG_WARN, "sort: diff %s", arg);
+            yaz_log(YLOG_WARN, " expected error");
+            yaz_log(YLOG_WARN, " got %s", wrbuf_cstr(w));
+        }
+        wrbuf_destroy(w);
+    }
+    odr_destroy(odr);
+    return ret;
+}
+
 static void tst(void)
 {
     YAZ_CHECK(cql("title a",
@@ -115,6 +161,8 @@ static void tst(void)
                   " SORTBY title/ascending/ignoreCase"
                   " date/descending/respectCase"));
     YAZ_CHECK(cql("1=4,2=3 a", 0));
+    YAZ_CHECK(cql("date a=1900",
+                  " SORTBY date/ascending/ignoreCase/missingValue=1900"));
 
     YAZ_CHECK(type7("title a",
                   "@or q @attr 1=title @attr 7=1 0"));
@@ -123,6 +171,17 @@ static void tst(void)
                     " @attr 1=date @attr 7=2 1"));
     YAZ_CHECK(type7("1=4,2=3 a",
                   "@or q @attr 1=4 @attr 2=3 @attr 7=1 0"));
+    YAZ_CHECK(type7("date a=1900",
+                  "@or q @attr 1=date @attr 7=1 0"));
+
+    YAZ_CHECK(srw_sortkeys("title a",
+                           "title,,1,0,highValue"));
+    YAZ_CHECK(srw_sortkeys("title a date ds",
+                           "title,,1,0,highValue "
+                           "date,,0,1,highValue"));
+    YAZ_CHECK(srw_sortkeys("1=4,2=3 a", 0));
+    YAZ_CHECK(srw_sortkeys("date a=1900",
+                           "date,,1,0,1900"));
 }
 
 int main(int argc, char **argv)