3590f9b8499af528d052e555fef70b18e5c11803
[mp-sparql-moved-to-github.git] / src / test_sparql.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5 #if HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8
9 #include <string.h>
10 #include "sparql.h"
11 #include <yaz/log.h>
12 #include <yaz/test.h>
13 #include <yaz/pquery.h>
14
15 static int test_query(yaz_sparql_t s, const char *pqf, const char *expect)
16 {
17     YAZ_PQF_Parser parser = yaz_pqf_create();
18     ODR odr = odr_createmem(ODR_ENCODE);
19     Z_RPNQuery *rpn = yaz_pqf_parse(parser, odr, pqf);
20     int ret = 0;
21     WRBUF addinfo = wrbuf_alloc();
22     WRBUF w = wrbuf_alloc();
23
24     if (rpn)
25     {
26         int r = yaz_sparql_from_rpn_wrbuf(s, addinfo, w, rpn);
27         if (expect)
28         {
29             if (!r)
30             {
31                 if (!strcmp(expect, wrbuf_cstr(w)))
32                     ret = 1;
33                 else
34                 {
35                     yaz_log(YLOG_WARN, "test_sparql: pqf=%s", pqf);
36                     yaz_log(YLOG_WARN, " expect: %s", expect);
37                     yaz_log(YLOG_WARN, " got:    %s", wrbuf_cstr(w));
38                 }
39             }
40             else
41             {
42                 yaz_log(YLOG_WARN, "test_sparql: pqf=%s", pqf);
43                 yaz_log(YLOG_WARN, " expect: %s", expect);
44                 yaz_log(YLOG_WARN, " got error: %d:%s", r, wrbuf_cstr(addinfo));
45             }
46         }
47         else
48         {
49             if (r)
50                 ret = 1;
51             else
52             {
53                 yaz_log(YLOG_WARN, "test_sparql: pqf=%s", pqf);
54                 yaz_log(YLOG_WARN, " expect error");
55                 yaz_log(YLOG_WARN, " got:    %s", wrbuf_cstr(w));
56             }
57         }
58     }
59     wrbuf_destroy(w);
60     wrbuf_destroy(addinfo);
61     odr_destroy(odr);
62     yaz_pqf_destroy(parser);
63     return ret;
64 }
65
66 static void tst1(void)
67 {
68     yaz_sparql_t s = yaz_sparql_create();
69
70     yaz_sparql_add_pattern(s, "prefix",
71                            "rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns");
72     yaz_sparql_add_pattern(s, "prefix",
73                            "bf: <http://bibframe.org/vocab/>");
74     yaz_sparql_add_pattern(s, "prefix",
75                            "gs: http://gs.com/panorama/domain-model");
76     yaz_sparql_add_pattern(s, "field.title", "?title");
77     yaz_sparql_add_pattern(s, "field.author", "?author");
78     yaz_sparql_add_pattern(s, "field.description", "?description");
79     yaz_sparql_add_pattern(s, "field.instanceTitle", "?ititle");
80     yaz_sparql_add_pattern(s, "criteria", "?work a bf:Work");
81     yaz_sparql_add_pattern(s, "criteria", "?work bf:workTitle/bf:titleValue ?title");
82     yaz_sparql_add_pattern(s, "criteria", "?work bf:creator/bf:label ?author");
83     yaz_sparql_add_pattern(s, "criteria", "?work bf:note ?description");
84     yaz_sparql_add_pattern(s, "criteria", "?inst bf:instanceOf ?work");
85     yaz_sparql_add_pattern(s, "criteria", "?inst bf:instanceTitle/bf:titleValue ?ititle");
86     yaz_sparql_add_pattern(s, "criteria.optional", "?inst bf:heldBy ?lib");
87
88     yaz_sparql_add_pattern(s, "index.bf.title",
89                            "?work bf:workTitle/bf:titleValue ?o1 "
90                            "FILTER(contains(?o1, %s))");
91     yaz_sparql_add_pattern(s, "index.bf.creator",
92                            "?work bf:creator/bf:label ?o2 "
93                            "FILTER(contains(?o2, %s))");
94     yaz_sparql_add_pattern(s, "index.bf.authorityCreator",
95                            "?work bf:author %s");
96     yaz_sparql_add_pattern(s, "index.bf.type",
97                            "?inst rdf:type %s");
98     yaz_sparql_add_pattern(s, "index.bf.format",
99                            "?inst bf:format ?o5 FILTER(contains(?o5, %s))");
100     yaz_sparql_add_pattern(s, "index.bf.nearby", "?lib gs:nearby (%d)");
101     yaz_sparql_add_pattern(s, "index.bf.baseTitle",
102                            "?work bf:derivativeOf/bf:workTitle/bf:titleValue "
103                            "?o6 FILTER(contains(?o6, %s))");
104     yaz_sparql_add_pattern(s, "index.bf.baseCreator",
105                            "?work bf:derivativeOf/bf:creator/bf:label "
106                            "?o7 FILTER(contains(?o7, %s))");
107     yaz_sparql_add_pattern(s, "index.bf.targetAudience",
108                            "?work bf:targetAudience %s");
109     yaz_sparql_add_pattern(s, "index.bf.isbn", "?inst bf:ISBN %s");
110     YAZ_CHECK(test_query(
111                   s, "@attr 1=bf.title computer",
112                   "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
113                   "PREFIX bf: <http://bibframe.org/vocab/>\n"
114                   "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
115                   "\n"
116                   "SELECT ?title ?author ?description ?ititle\n"
117                   "WHERE {\n"
118                   "  ?work a bf:Work .\n"
119                   "  ?work bf:workTitle/bf:titleValue ?title .\n"
120                   "  ?work bf:creator/bf:label ?author .\n"
121                   "  ?work bf:note ?description .\n"
122                   "  ?inst bf:instanceOf ?work .\n"
123                   "  ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
124                   "  OPTIONAL { ?inst bf:heldBy ?lib } .\n"
125                   "  ?work bf:workTitle/bf:titleValue ?o1 "
126                   "FILTER(contains(?o1, \"computer\"))\n"
127                   "}\n"
128                   ));
129
130     YAZ_CHECK(test_query(
131                   s, "@attr 1=bf.creator london",
132                   "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
133                   "PREFIX bf: <http://bibframe.org/vocab/>\n"
134                   "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
135                   "\n"
136                   "SELECT ?title ?author ?description ?ititle\n"
137                   "WHERE {\n"
138                   "  ?work a bf:Work .\n"
139                   "  ?work bf:workTitle/bf:titleValue ?title .\n"
140                   "  ?work bf:creator/bf:label ?author .\n"
141                   "  ?work bf:note ?description .\n"
142                   "  ?inst bf:instanceOf ?work .\n"
143                   "  ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
144                   "  OPTIONAL { ?inst bf:heldBy ?lib } .\n"
145                   "  ?work bf:creator/bf:label ?o2 "
146                   "FILTER(contains(?o2, \"london\"))\n"
147                   "}\n"));
148
149
150     YAZ_CHECK(test_query(
151                   s, "@and @attr 1=bf.creator london @attr 1=bf.title computer",
152                   "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
153                   "PREFIX bf: <http://bibframe.org/vocab/>\n"
154                   "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
155                   "\n"
156                   "SELECT ?title ?author ?description ?ititle\n"
157                   "WHERE {\n"
158                   "  ?work a bf:Work .\n"
159                   "  ?work bf:workTitle/bf:titleValue ?title .\n"
160                   "  ?work bf:creator/bf:label ?author .\n"
161                   "  ?work bf:note ?description .\n"
162                   "  ?inst bf:instanceOf ?work .\n"
163                   "  ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
164                   "  OPTIONAL { ?inst bf:heldBy ?lib } .\n"
165                   "  ?work bf:creator/bf:label ?o2 "
166                   "FILTER(contains(?o2, \"london\")) .\n"
167                   "  ?work bf:workTitle/bf:titleValue ?o1 "
168                   "FILTER(contains(?o1, \"computer\"))\n"
169                   "}\n"));
170
171     YAZ_CHECK(test_query(
172                   s, "@or @attr 1=bf.creator london @attr 1=bf.title computer",
173                   "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
174                   "PREFIX bf: <http://bibframe.org/vocab/>\n"
175                   "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
176                   "\n"
177                   "SELECT ?title ?author ?description ?ititle\n"
178                   "WHERE {\n"
179                   "  ?work a bf:Work .\n"
180                   "  ?work bf:workTitle/bf:titleValue ?title .\n"
181                   "  ?work bf:creator/bf:label ?author .\n"
182                   "  ?work bf:note ?description .\n"
183                   "  ?inst bf:instanceOf ?work .\n"
184                   "  ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
185                   "  OPTIONAL { ?inst bf:heldBy ?lib } .\n"
186                   "  {\n"
187                   "   ?work bf:creator/bf:label ?o2 "
188                   "FILTER(contains(?o2, \"london\"))\n"
189                   "  } UNION {\n"
190                   "   ?work bf:workTitle/bf:titleValue ?o1 "
191                   "FILTER(contains(?o1, \"computer\"))\n"
192                   "  }\n"
193                   "}\n"
194                   ));
195
196     YAZ_CHECK(test_query(
197                   s, "@or @or @attr 1=bf.creator a @attr 1=bf.title b @attr 1=bf.title c",
198                   "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
199                   "PREFIX bf: <http://bibframe.org/vocab/>\n"
200                   "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
201                   "\n"
202                   "SELECT ?title ?author ?description ?ititle\n"
203                   "WHERE {\n"
204                   "  ?work a bf:Work .\n"
205                   "  ?work bf:workTitle/bf:titleValue ?title .\n"
206                   "  ?work bf:creator/bf:label ?author .\n"
207                   "  ?work bf:note ?description .\n"
208                   "  ?inst bf:instanceOf ?work .\n"
209                   "  ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
210                   "  OPTIONAL { ?inst bf:heldBy ?lib } .\n"
211                   "  {\n"
212                   "   {\n"
213                   "    ?work bf:creator/bf:label ?o2 "
214                   "FILTER(contains(?o2, \"a\"))\n"
215                   "   } UNION {\n"
216                   "    ?work bf:workTitle/bf:titleValue ?o1 "
217                   "FILTER(contains(?o1, \"b\"))\n"
218                   "   }\n"
219                   "  } UNION {\n"
220                   "   ?work bf:workTitle/bf:titleValue ?o1 "
221                   "FILTER(contains(?o1, \"c\"))\n"
222                   "  }\n"
223                   "}\n"
224                   ));
225
226     YAZ_CHECK(test_query(
227                   s, "@or @and @attr 1=bf.creator a @attr 1=bf.title b @attr 1=bf.title c",
228                   "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
229                   "PREFIX bf: <http://bibframe.org/vocab/>\n"
230                   "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
231                   "\n"
232                   "SELECT ?title ?author ?description ?ititle\n"
233                   "WHERE {\n"
234                   "  ?work a bf:Work .\n"
235                   "  ?work bf:workTitle/bf:titleValue ?title .\n"
236                   "  ?work bf:creator/bf:label ?author .\n"
237                   "  ?work bf:note ?description .\n"
238                   "  ?inst bf:instanceOf ?work .\n"
239                   "  ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
240                   "  OPTIONAL { ?inst bf:heldBy ?lib } .\n"
241                   "  {\n"
242                   "   ?work bf:creator/bf:label ?o2 "
243                   "FILTER(contains(?o2, \"a\")) .\n"
244                   "   ?work bf:workTitle/bf:titleValue ?o1 "
245                   "FILTER(contains(?o1, \"b\"))\n"
246                   "  } UNION {\n"
247                   "   ?work bf:workTitle/bf:titleValue ?o1 "
248                   "FILTER(contains(?o1, \"c\"))\n"
249                   "  }\n"
250                   "}\n"
251                   ));
252
253     YAZ_CHECK(test_query(
254                   s, "@and @and @attr 1=bf.creator a @attr 1=bf.title b @attr 1=bf.title c",
255                   "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
256                   "PREFIX bf: <http://bibframe.org/vocab/>\n"
257                   "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
258                   "\n"
259                   "SELECT ?title ?author ?description ?ititle\n"
260                   "WHERE {\n"
261                   "  ?work a bf:Work .\n"
262                   "  ?work bf:workTitle/bf:titleValue ?title .\n"
263                   "  ?work bf:creator/bf:label ?author .\n"
264                   "  ?work bf:note ?description .\n"
265                   "  ?inst bf:instanceOf ?work .\n"
266                   "  ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
267                   "  OPTIONAL { ?inst bf:heldBy ?lib } .\n"
268                   "  ?work bf:creator/bf:label ?o2 "
269                   "FILTER(contains(?o2, \"a\")) .\n"
270                   "  ?work bf:workTitle/bf:titleValue ?o1 "
271                   "FILTER(contains(?o1, \"b\")) .\n"
272                   "  ?work bf:workTitle/bf:titleValue ?o1 "
273                   "FILTER(contains(?o1, \"c\"))\n"
274                   "}\n"
275                   ));
276
277     YAZ_CHECK(test_query(
278                   s, "@and @attr 1=bf.title \"Phantom Tollbooth\" "
279                   "@attr 1=bf.nearby \"40.1583 83.0742 30\"",
280                   "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
281                   "PREFIX bf: <http://bibframe.org/vocab/>\n"
282                   "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
283                   "\n"
284                   "SELECT ?title ?author ?description ?ititle\n"
285                   "WHERE {\n"
286                   "  ?work a bf:Work .\n"
287                   "  ?work bf:workTitle/bf:titleValue ?title .\n"
288                   "  ?work bf:creator/bf:label ?author .\n"
289                   "  ?work bf:note ?description .\n"
290                   "  ?inst bf:instanceOf ?work .\n"
291                   "  ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
292                   "  ?inst bf:heldBy ?lib .\n"
293                   "  ?work bf:workTitle/bf:titleValue ?o1 "
294                   "FILTER(contains(?o1, \"Phantom Tollbooth\")) .\n"
295                   "  ?lib gs:nearby (40.1583 83.0742 30)\n"
296                   "}\n"
297                   ));
298
299     YAZ_CHECK(test_query(
300                   s, "@attr 1=bf.isbn 9780316154697",
301                   "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
302                   "PREFIX bf: <http://bibframe.org/vocab/>\n"
303                   "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
304                   "\n"
305                   "SELECT ?title ?author ?description ?ititle\n"
306                   "WHERE {\n"
307                   "  ?work a bf:Work .\n"
308                   "  ?work bf:workTitle/bf:titleValue ?title .\n"
309                   "  ?work bf:creator/bf:label ?author .\n"
310                   "  ?work bf:note ?description .\n"
311                   "  ?inst bf:instanceOf ?work .\n"
312                   "  ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
313                   "  OPTIONAL { ?inst bf:heldBy ?lib } .\n"
314                   "  ?inst bf:ISBN \"9780316154697\"\n"
315                   "}\n"
316                  ));
317
318
319     yaz_sparql_destroy(s);
320 }
321
322 static void tst2(void)
323 {
324     yaz_sparql_t s = yaz_sparql_create();
325
326     yaz_sparql_add_pattern(s, "prefix",
327                            "rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns");
328     yaz_sparql_add_pattern(s, "prefix",
329                            "bf: <http://bibframe.org/vocab/>");
330     yaz_sparql_add_pattern(s, "prefix",
331                            "gs: http://gs.com/panorama/domain-model");
332     yaz_sparql_add_pattern(s, "field.title", "?title");
333     yaz_sparql_add_pattern(s, "field.author", "?author");
334     yaz_sparql_add_pattern(s, "field.description", "?description");
335     yaz_sparql_add_pattern(s, "field.instanceTitle", "?ititle");
336     yaz_sparql_add_pattern(s, "criteria", "?work a bf:Work");
337     yaz_sparql_add_pattern(s, "criteria", "?work bf:workTitle/bf:titleValue ?title");
338     yaz_sparql_add_pattern(s, "criteria", "?work bf:creator/bf:label ?author");
339     yaz_sparql_add_pattern(s, "criteria", "?work bf:note ?description");
340     yaz_sparql_add_pattern(s, "criteria", "?inst bf:instanceOf ?work");
341     yaz_sparql_add_pattern(s, "criteria", "?inst bf:instanceTitle/bf:titleValue ?ititle");
342     yaz_sparql_add_pattern(s, "criteria.optional", "?inst bf:heldBy ?lib");
343
344     yaz_sparql_add_pattern(s, "index.bf.title",
345                            "?work bf:workTitle/bf:titleValue %v "
346                            "FILTER(contains(%v, %s))");
347     yaz_sparql_add_pattern(s, "index.bf.creator",
348                            "?work bf:creator/bf:label %v "
349                            "FILTER(contains(%v, %s))");
350     yaz_sparql_add_pattern(s, "index.bf.authorityCreator",
351                            "?work bf:author %s");
352     yaz_sparql_add_pattern(s, "index.bf.type", "?inst rdf:type %s");
353     yaz_sparql_add_pattern(s, "index.bf.format",
354                            "?inst bf:format %v FILTER(contains(%v, %s))");
355     yaz_sparql_add_pattern(s, "index.bf.nearby", "?lib gs:nearby (%d)");
356     yaz_sparql_add_pattern(s, "index.bf.baseTitle",
357                            "?work bf:derivativeOf/bf:workTitle/bf:titleValue "
358                            "%v FILTER(contains(%v, %s))");
359     yaz_sparql_add_pattern(s, "index.bf.baseCreator",
360                            "?work bf:derivativeOf/bf:creator/bf:label "
361                            "%v FILTER(contains(%v, %s))");
362     yaz_sparql_add_pattern(s, "index.bf.targetAudience",
363                            "?work bf:targetAudience %s");
364     yaz_sparql_add_pattern(s, "index.bf.isbn", "?inst bf:ISBN %s");
365
366     YAZ_CHECK(test_query(
367                   s, "@attr 1=bf.title computer",
368                   "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
369                   "PREFIX bf: <http://bibframe.org/vocab/>\n"
370                   "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
371                   "\n"
372                   "SELECT ?title ?author ?description ?ititle\n"
373                   "WHERE {\n"
374                   "  ?work a bf:Work .\n"
375                   "  ?work bf:workTitle/bf:titleValue ?title .\n"
376                   "  ?work bf:creator/bf:label ?author .\n"
377                   "  ?work bf:note ?description .\n"
378                   "  ?inst bf:instanceOf ?work .\n"
379                   "  ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
380                   "  OPTIONAL { ?inst bf:heldBy ?lib } .\n"
381                   "  ?work bf:workTitle/bf:titleValue ?v0 "
382                   "FILTER(contains(?v0, \"computer\"))\n"
383                   "}\n"
384                   ));
385
386     YAZ_CHECK(test_query(
387                   s, "@attr 1=bf.creator london",
388                   "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
389                   "PREFIX bf: <http://bibframe.org/vocab/>\n"
390                   "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
391                   "\n"
392                   "SELECT ?title ?author ?description ?ititle\n"
393                   "WHERE {\n"
394                   "  ?work a bf:Work .\n"
395                   "  ?work bf:workTitle/bf:titleValue ?title .\n"
396                   "  ?work bf:creator/bf:label ?author .\n"
397                   "  ?work bf:note ?description .\n"
398                   "  ?inst bf:instanceOf ?work .\n"
399                   "  ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
400                   "  OPTIONAL { ?inst bf:heldBy ?lib } .\n"
401                   "  ?work bf:creator/bf:label ?v0 "
402                   "FILTER(contains(?v0, \"london\"))\n"
403                   "}\n"));
404
405     YAZ_CHECK(test_query(
406                   s, "@or @and @attr 1=bf.creator a @attr 1=bf.title b @attr 1=bf.title c",
407                   "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
408                   "PREFIX bf: <http://bibframe.org/vocab/>\n"
409                   "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
410                   "\n"
411                   "SELECT ?title ?author ?description ?ititle\n"
412                   "WHERE {\n"
413                   "  ?work a bf:Work .\n"
414                   "  ?work bf:workTitle/bf:titleValue ?title .\n"
415                   "  ?work bf:creator/bf:label ?author .\n"
416                   "  ?work bf:note ?description .\n"
417                   "  ?inst bf:instanceOf ?work .\n"
418                   "  ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
419                   "  OPTIONAL { ?inst bf:heldBy ?lib } .\n"
420                   "  {\n"
421                   "   ?work bf:creator/bf:label ?v0 "
422                   "FILTER(contains(?v0, \"a\")) .\n"
423                   "   ?work bf:workTitle/bf:titleValue ?v1 "
424                   "FILTER(contains(?v1, \"b\"))\n"
425                   "  } UNION {\n"
426                   "   ?work bf:workTitle/bf:titleValue ?v2 "
427                   "FILTER(contains(?v2, \"c\"))\n"
428                   "  }\n"
429                   "}\n"
430                   ));
431
432     yaz_sparql_destroy(s);
433 }
434
435 int main(int argc, char **argv)
436 {
437     YAZ_CHECK_INIT(argc, argv);
438     YAZ_CHECK_LOG();
439     tst1();
440     tst2();
441     YAZ_CHECK_TERM;
442 }
443 /*
444  * Local variables:
445  * c-basic-offset: 4
446  * c-file-style: "Stroustrup"
447  * indent-tabs-mode: nil
448  * End:
449  * vim: shiftwidth=4 tabstop=8 expandtab
450  */
451