Work
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 6 Nov 2014 14:05:52 +0000 (15:05 +0100)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 6 Nov 2014 14:05:52 +0000 (15:05 +0100)
src/sparql.c
test/test_sparql.c

index a62a80d..768b692 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <assert.h>
 #include <yaz/sparql.h>
+#include <yaz/diagbib1.h>
 #include <yaz/tokenizer.h>
 
 struct sparql_entry {
@@ -64,6 +65,64 @@ int yaz_sparql_from_rpn_wrbuf(yaz_sparql_t s, WRBUF addinfo, WRBUF w,
     return yaz_sparql_from_rpn_stream(s, addinfo, wrbuf_vp_puts, w, q);
 }
 
+
+static int apt(yaz_sparql_t s,
+               WRBUF addinfo,
+               void (*pr)(const char *buf, void *client_data),
+               void *client_data,
+               Z_AttributesPlusTerm *q)
+{
+    return 0;
+}
+
+
+static int rpn_structure(yaz_sparql_t s,
+                         WRBUF addinfo,
+                         void (*pr)(const char *buf,
+                                    void *client_data),
+                         void *client_data,
+                         Z_RPNStructure *q)
+{
+    if (q->which == Z_RPNStructure_complex)
+    {
+        int r;
+        Z_Complex *c = q->u.complex;
+        Z_Operator *op = c->roperator;
+        if (op->which == Z_Operator_and)
+        {
+            r = rpn_structure(s, addinfo, pr, client_data, c->s1);
+            if (r)
+                return r;
+            pr(" .\n", client_data);
+            return rpn_structure(s, addinfo, pr, client_data, c->s2);
+        }
+        else if (op->which == Z_Operator_or)
+        {
+            pr("{\n", client_data);
+            r = rpn_structure(s, addinfo, pr, client_data, c->s1);
+            if (r)
+                return r;
+            pr("} UNION {\n", client_data);
+            r = rpn_structure(s, addinfo, pr, client_data, c->s1);
+            pr("}\n", client_data);
+            return r;
+        }
+        else
+        {
+            return YAZ_BIB1_OPERATOR_UNSUPP;
+        }
+    }
+    else
+    {
+        Z_Operand *op = q->u.simple;
+        if (op->which == Z_Operand_APT)
+            return apt(s, addinfo, pr, client_data, op->u.attributesPlusTerm);
+        else
+            return YAZ_BIB1_RESULT_SET_UNSUPP_AS_A_SEARCH_TERM;
+    }
+    return 0;
+}
+
 int yaz_sparql_from_rpn_stream(yaz_sparql_t s,
                                WRBUF addinfo,
                                void (*pr)(const char *buf,
@@ -80,37 +139,72 @@ int yaz_sparql_from_rpn_stream(yaz_sparql_t s,
         if (!strcmp(e->pattern, "prefix"))
         {
             yaz_tok_parse_t p = yaz_tok_parse_buf(cfg, e->value);
-            int token;
+            int no = 0;
 
-            token = yaz_tok_move(p);
-            if (token != YAZ_TOK_STRING)
-                errors++;
-            else
+            pr("PREFIX", client_data);
+            while (1)
             {
-                const char *tok_str = yaz_tok_parse_string(p);
-                pr("PREFIX ", client_data);
-                pr(tok_str, client_data);
+                const char *tok_str;
+                int token = yaz_tok_move(p);
+                if (token != YAZ_TOK_STRING)
+                    break;
                 pr(" ", client_data);
 
-                token = yaz_tok_move(p);
-                if (token != YAZ_TOK_STRING)
-                    errors++;
-                else
+                tok_str = yaz_tok_parse_string(p);
+                if (tok_str[0])
                 {
-                    tok_str = yaz_tok_parse_string(p);
-                    if (*tok_str == '<')
-                        pr(tok_str, client_data);
-                    else
-                    {
+                    if (no > 0 && tok_str[0] != '<')
                         pr("<", client_data);
-                        pr(tok_str, client_data);
+                    pr(tok_str, client_data);
+                    if (no > 0 && tok_str[strlen(tok_str)-1] != '>')
                         pr(">", client_data);
-                    }
                 }
-                pr("\n", client_data);
+                no++;
             }
+            pr("\n", client_data);
+            yaz_tok_parse_destroy(p);
+        }
+        else if (!strcmp(e->pattern, "criteria"))
+        {
+            ;
+        }
+        else if (!strncmp(e->pattern, "index", 5))
+        {
+            ;
+        }
+        else if (!strncmp(e->pattern, "field", 5))
+        {
+            ;
+        }
+        else
+        {
+            errors++;
+        }
+    }
+    pr("\n", client_data);
+    pr("SELECT", client_data);
+    for (e = s->conf; e; e = e->next)
+    {
+        if (!strncmp(e->pattern, "field", 5))
+        {
+            pr(" ", client_data);
+            pr(e->value, client_data);
+        }
+    }
+    pr("\n", client_data);
+    pr("WHERE {\n", client_data);
+    for (e = s->conf; e; e = e->next)
+    {
+        if (!strcmp(e->pattern, "criteria"))
+        {
+            pr("  ", client_data);
+            pr(e->value, client_data);
+            pr(" .\n", client_data);
         }
     }
+    rpn_structure(s, addinfo, pr, client_data, q->RPNStructure);
+
+    pr("}\n", client_data);
     yaz_tok_cfg_destroy(cfg);
 
     return errors ? -1 : 0;
index 75c1c21..b25792a 100644 (file)
@@ -71,10 +71,31 @@ static void tst1(void)
                            "rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns");
     yaz_sparql_add_pattern(s, "prefix",
                            "bf: <http://bibframe.org/vocab/>");
+    yaz_sparql_add_pattern(s, "field.title", "?title");
+    yaz_sparql_add_pattern(s, "field.author", "?author");
+    yaz_sparql_add_pattern(s, "field.description", "?description");
+    yaz_sparql_add_pattern(s, "field.instanceTitle", "?ititle");
+    yaz_sparql_add_pattern(s, "criteria", "?work a bf:Work");
+    yaz_sparql_add_pattern(s, "criteria", "?work bf:workTitle/bf:titleValue ?title");
+    yaz_sparql_add_pattern(s, "criteria", "?work bf:creator/bf:label ?author");
+    yaz_sparql_add_pattern(s, "criteria", "?work bf:note ?description");
+    yaz_sparql_add_pattern(s, "criteria", "?inst bf:instanceOf ?work");
+    yaz_sparql_add_pattern(s, "criteria", "?inst bf:instanceTitle/bf:titleValue ?ititle");
     YAZ_CHECK(test_query(
                   s, "computer",
                   "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
-                  "PREFIX bf: <http://bibframe.org/vocab/>\n"));
+                  "PREFIX bf: <http://bibframe.org/vocab/>\n"
+                  "\n"
+                  "SELECT ?title ?author ?description ?ititle\n"
+                  "WHERE {\n"
+                  "  ?work a bf:Work .\n"
+                  "  ?work bf:workTitle/bf:titleValue ?title .\n"
+                  "  ?work bf:creator/bf:label ?author .\n"
+                  "  ?work bf:note ?description .\n"
+                  "  ?inst bf:instanceOf ?work .\n"
+                  "  ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
+                  "}\n"
+));
 
     yaz_sparql_destroy(s);
 }