1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
13 #include <yaz/pquery.h>
15 static int test_query(yaz_sparql_t s, const char *pqf, const char *expect)
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);
21 WRBUF addinfo = wrbuf_alloc();
22 WRBUF w = wrbuf_alloc();
26 int r = yaz_sparql_from_rpn_wrbuf(s, addinfo, w, rpn);
31 if (!strcmp(expect, wrbuf_cstr(w)))
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));
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));
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));
60 wrbuf_destroy(addinfo);
62 yaz_pqf_destroy(parser);
66 static int test_uri(yaz_sparql_t s, const char *uri, const char *schema,
70 WRBUF addinfo = wrbuf_alloc();
71 WRBUF w = wrbuf_alloc();
73 int r = yaz_sparql_from_uri_wrbuf(s, addinfo, w, uri, schema);
78 if (!strcmp(expect, wrbuf_cstr(w)))
82 yaz_log(YLOG_WARN, "test_sparql: uri=%s", uri);
83 yaz_log(YLOG_WARN, " expect: %s", expect);
84 yaz_log(YLOG_WARN, " got: %s", wrbuf_cstr(w));
89 yaz_log(YLOG_WARN, "test_sparql: uri=%s", uri);
90 yaz_log(YLOG_WARN, " expect: %s", expect);
91 yaz_log(YLOG_WARN, " got error: %d:%s", r, wrbuf_cstr(addinfo));
100 yaz_log(YLOG_WARN, "test_sparql: uri=%s", uri);
101 yaz_log(YLOG_WARN, " expect error");
102 yaz_log(YLOG_WARN, " got: %s", wrbuf_cstr(w));
106 wrbuf_destroy(addinfo);
111 static void tst1(void)
113 yaz_sparql_t s = yaz_sparql_create();
115 yaz_sparql_add_pattern(s, "prefix",
116 "rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns");
117 yaz_sparql_add_pattern(s, "prefix",
118 "bf: <http://bibframe.org/vocab/>");
119 yaz_sparql_add_pattern(s, "prefix",
120 "gs: http://gs.com/panorama/domain-model");
121 yaz_sparql_add_pattern(s, "form", "SELECT ?title ?author ?description ?ititle");
122 yaz_sparql_add_pattern(s, "criteria", "?work a bf:Work");
123 yaz_sparql_add_pattern(s, "criteria", "?work bf:workTitle/bf:titleValue ?title");
124 yaz_sparql_add_pattern(s, "criteria", "?work bf:creator/bf:label ?author");
125 yaz_sparql_add_pattern(s, "criteria", "?work bf:note ?description");
126 yaz_sparql_add_pattern(s, "criteria", "?inst bf:instanceOf ?work");
127 yaz_sparql_add_pattern(s, "criteria", "?inst bf:instanceTitle/bf:titleValue ?ititle");
128 yaz_sparql_add_pattern(s, "criteria.optional", "?inst bf:heldBy ?lib");
130 yaz_sparql_add_pattern(s, "index.bf.title",
131 "?work bf:workTitle/bf:titleValue ?o1 "
132 "FILTER(contains(?o1, %s))");
133 yaz_sparql_add_pattern(s, "index.bf.creator",
134 "?work bf:creator/bf:label ?o2 "
135 "FILTER(contains(?o2, %s))");
136 yaz_sparql_add_pattern(s, "index.bf.authorityCreator",
137 "?work bf:author %s");
138 yaz_sparql_add_pattern(s, "index.bf.type",
139 "?inst rdf:type %s");
140 yaz_sparql_add_pattern(s, "index.bf.format",
141 "?inst bf:format ?o5 FILTER(contains(?o5, %s))");
142 yaz_sparql_add_pattern(s, "index.bf.nearby", "?lib gs:nearby (%d)");
143 yaz_sparql_add_pattern(s, "index.bf.baseTitle",
144 "?work bf:derivativeOf/bf:workTitle/bf:titleValue "
145 "?o6 FILTER(contains(?o6, %s))");
146 yaz_sparql_add_pattern(s, "index.bf.baseCreator",
147 "?work bf:derivativeOf/bf:creator/bf:label "
148 "?o7 FILTER(contains(?o7, %s))");
149 yaz_sparql_add_pattern(s, "index.bf.targetAudience",
150 "?work bf:targetAudience %s");
151 yaz_sparql_add_pattern(s, "index.bf.isbn", "?inst bf:ISBN %s");
153 yaz_sparql_add_pattern(s, "uri.full", "SELECT ?sub ?rel WHERE ?work = %u");
155 YAZ_CHECK(test_uri(s, "http://x/y", "full",
156 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
157 "PREFIX bf: <http://bibframe.org/vocab/>\n"
158 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
159 "SELECT ?sub ?rel WHERE ?work = <http://x/y>\n"));
161 YAZ_CHECK(test_query(
162 s, "@attr 1=bf.title computer",
163 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
164 "PREFIX bf: <http://bibframe.org/vocab/>\n"
165 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
166 "SELECT ?title ?author ?description ?ititle\n"
168 " ?work a bf:Work .\n"
169 " ?work bf:workTitle/bf:titleValue ?title .\n"
170 " ?work bf:creator/bf:label ?author .\n"
171 " ?work bf:note ?description .\n"
172 " ?inst bf:instanceOf ?work .\n"
173 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
174 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
175 " ?work bf:workTitle/bf:titleValue ?o1 "
176 "FILTER(contains(?o1, \"computer\"))\n"
180 YAZ_CHECK(test_query(
181 s, "@attr 1=bf.creator london",
182 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
183 "PREFIX bf: <http://bibframe.org/vocab/>\n"
184 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
185 "SELECT ?title ?author ?description ?ititle\n"
187 " ?work a bf:Work .\n"
188 " ?work bf:workTitle/bf:titleValue ?title .\n"
189 " ?work bf:creator/bf:label ?author .\n"
190 " ?work bf:note ?description .\n"
191 " ?inst bf:instanceOf ?work .\n"
192 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
193 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
194 " ?work bf:creator/bf:label ?o2 "
195 "FILTER(contains(?o2, \"london\"))\n"
199 YAZ_CHECK(test_query(
200 s, "@and @attr 1=bf.creator london @attr 1=bf.title computer",
201 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
202 "PREFIX bf: <http://bibframe.org/vocab/>\n"
203 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
204 "SELECT ?title ?author ?description ?ititle\n"
206 " ?work a bf:Work .\n"
207 " ?work bf:workTitle/bf:titleValue ?title .\n"
208 " ?work bf:creator/bf:label ?author .\n"
209 " ?work bf:note ?description .\n"
210 " ?inst bf:instanceOf ?work .\n"
211 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
212 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
213 " ?work bf:creator/bf:label ?o2 "
214 "FILTER(contains(?o2, \"london\")) .\n"
215 " ?work bf:workTitle/bf:titleValue ?o1 "
216 "FILTER(contains(?o1, \"computer\"))\n"
219 YAZ_CHECK(test_query(
220 s, "@or @attr 1=bf.creator london @attr 1=bf.title computer",
221 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
222 "PREFIX bf: <http://bibframe.org/vocab/>\n"
223 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
224 "SELECT ?title ?author ?description ?ititle\n"
226 " ?work a bf:Work .\n"
227 " ?work bf:workTitle/bf:titleValue ?title .\n"
228 " ?work bf:creator/bf:label ?author .\n"
229 " ?work bf:note ?description .\n"
230 " ?inst bf:instanceOf ?work .\n"
231 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
232 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
234 " ?work bf:creator/bf:label ?o2 "
235 "FILTER(contains(?o2, \"london\"))\n"
237 " ?work bf:workTitle/bf:titleValue ?o1 "
238 "FILTER(contains(?o1, \"computer\"))\n"
243 YAZ_CHECK(test_query(
244 s, "@or @or @attr 1=bf.creator a @attr 1=bf.title b @attr 1=bf.title c",
245 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
246 "PREFIX bf: <http://bibframe.org/vocab/>\n"
247 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
248 "SELECT ?title ?author ?description ?ititle\n"
250 " ?work a bf:Work .\n"
251 " ?work bf:workTitle/bf:titleValue ?title .\n"
252 " ?work bf:creator/bf:label ?author .\n"
253 " ?work bf:note ?description .\n"
254 " ?inst bf:instanceOf ?work .\n"
255 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
256 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
259 " ?work bf:creator/bf:label ?o2 "
260 "FILTER(contains(?o2, \"a\"))\n"
262 " ?work bf:workTitle/bf:titleValue ?o1 "
263 "FILTER(contains(?o1, \"b\"))\n"
266 " ?work bf:workTitle/bf:titleValue ?o1 "
267 "FILTER(contains(?o1, \"c\"))\n"
272 YAZ_CHECK(test_query(
273 s, "@or @and @attr 1=bf.creator a @attr 1=bf.title b @attr 1=bf.title c",
274 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
275 "PREFIX bf: <http://bibframe.org/vocab/>\n"
276 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
277 "SELECT ?title ?author ?description ?ititle\n"
279 " ?work a bf:Work .\n"
280 " ?work bf:workTitle/bf:titleValue ?title .\n"
281 " ?work bf:creator/bf:label ?author .\n"
282 " ?work bf:note ?description .\n"
283 " ?inst bf:instanceOf ?work .\n"
284 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
285 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
287 " ?work bf:creator/bf:label ?o2 "
288 "FILTER(contains(?o2, \"a\")) .\n"
289 " ?work bf:workTitle/bf:titleValue ?o1 "
290 "FILTER(contains(?o1, \"b\"))\n"
292 " ?work bf:workTitle/bf:titleValue ?o1 "
293 "FILTER(contains(?o1, \"c\"))\n"
298 YAZ_CHECK(test_query(
299 s, "@and @and @attr 1=bf.creator a @attr 1=bf.title b @attr 1=bf.title c",
300 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
301 "PREFIX bf: <http://bibframe.org/vocab/>\n"
302 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
303 "SELECT ?title ?author ?description ?ititle\n"
305 " ?work a bf:Work .\n"
306 " ?work bf:workTitle/bf:titleValue ?title .\n"
307 " ?work bf:creator/bf:label ?author .\n"
308 " ?work bf:note ?description .\n"
309 " ?inst bf:instanceOf ?work .\n"
310 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
311 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
312 " ?work bf:creator/bf:label ?o2 "
313 "FILTER(contains(?o2, \"a\")) .\n"
314 " ?work bf:workTitle/bf:titleValue ?o1 "
315 "FILTER(contains(?o1, \"b\")) .\n"
316 " ?work bf:workTitle/bf:titleValue ?o1 "
317 "FILTER(contains(?o1, \"c\"))\n"
321 YAZ_CHECK(test_query(
322 s, "@and @attr 1=bf.title \"Phantom Tollbooth\" "
323 "@attr 1=bf.nearby \"40.1583 83.0742 30\"",
324 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
325 "PREFIX bf: <http://bibframe.org/vocab/>\n"
326 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
327 "SELECT ?title ?author ?description ?ititle\n"
329 " ?work a bf:Work .\n"
330 " ?work bf:workTitle/bf:titleValue ?title .\n"
331 " ?work bf:creator/bf:label ?author .\n"
332 " ?work bf:note ?description .\n"
333 " ?inst bf:instanceOf ?work .\n"
334 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
335 " ?inst bf:heldBy ?lib .\n"
336 " ?work bf:workTitle/bf:titleValue ?o1 "
337 "FILTER(contains(?o1, \"Phantom Tollbooth\")) .\n"
338 " ?lib gs:nearby (40.1583 83.0742 30)\n"
342 YAZ_CHECK(test_query(
343 s, "@attr 1=bf.isbn 9780316154697",
344 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
345 "PREFIX bf: <http://bibframe.org/vocab/>\n"
346 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
347 "SELECT ?title ?author ?description ?ititle\n"
349 " ?work a bf:Work .\n"
350 " ?work bf:workTitle/bf:titleValue ?title .\n"
351 " ?work bf:creator/bf:label ?author .\n"
352 " ?work bf:note ?description .\n"
353 " ?inst bf:instanceOf ?work .\n"
354 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
355 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
356 " ?inst bf:ISBN \"9780316154697\"\n"
361 yaz_sparql_destroy(s);
364 static void tst2(void)
366 yaz_sparql_t s = yaz_sparql_create();
368 yaz_sparql_add_pattern(s, "prefix",
369 "rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns");
370 yaz_sparql_add_pattern(s, "prefix",
371 "bf: <http://bibframe.org/vocab/>");
372 yaz_sparql_add_pattern(s, "prefix",
373 "gs: http://gs.com/panorama/domain-model");
374 yaz_sparql_add_pattern(s, "form", "SELECT ?title ?author ?description ?ititle");
375 yaz_sparql_add_pattern(s, "criteria", "?work a bf:Work");
376 yaz_sparql_add_pattern(s, "criteria", "?work bf:workTitle/bf:titleValue ?title");
377 yaz_sparql_add_pattern(s, "criteria", "?work bf:creator/bf:label ?author");
378 yaz_sparql_add_pattern(s, "criteria", "?work bf:note ?description");
379 yaz_sparql_add_pattern(s, "criteria", "?inst bf:instanceOf ?work");
380 yaz_sparql_add_pattern(s, "criteria", "?inst bf:instanceTitle/bf:titleValue ?ititle");
381 yaz_sparql_add_pattern(s, "criteria.optional", "?inst bf:heldBy ?lib");
383 yaz_sparql_add_pattern(s, "index.bf.title",
384 "?work bf:workTitle/bf:titleValue %v "
385 "FILTER(contains(%v, %s))");
386 yaz_sparql_add_pattern(s, "index.bf.creator",
387 "?work bf:creator/bf:label %v "
388 "FILTER(contains(%v, %s))");
389 yaz_sparql_add_pattern(s, "index.bf.authorityCreator",
390 "?work bf:author %s");
391 yaz_sparql_add_pattern(s, "index.bf.type", "?inst rdf:type %s");
392 yaz_sparql_add_pattern(s, "index.bf.format",
393 "?inst bf:format %v FILTER(contains(%v, %s))");
394 yaz_sparql_add_pattern(s, "index.bf.nearby", "?lib gs:nearby (%d)");
395 yaz_sparql_add_pattern(s, "index.bf.baseTitle",
396 "?work bf:derivativeOf/bf:workTitle/bf:titleValue "
397 "%v FILTER(contains(%v, %s))");
398 yaz_sparql_add_pattern(s, "index.bf.baseCreator",
399 "?work bf:derivativeOf/bf:creator/bf:label "
400 "%v FILTER(contains(%v, %s))");
401 yaz_sparql_add_pattern(s, "index.bf.targetAudience",
402 "?work bf:targetAudience %s");
403 yaz_sparql_add_pattern(s, "index.bf.isbn", "?inst bf:ISBN %s");
405 YAZ_CHECK(test_query(
406 s, "@attr 1=bf.title computer",
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 "SELECT ?title ?author ?description ?ititle\n"
412 " ?work a bf:Work .\n"
413 " ?work bf:workTitle/bf:titleValue ?title .\n"
414 " ?work bf:creator/bf:label ?author .\n"
415 " ?work bf:note ?description .\n"
416 " ?inst bf:instanceOf ?work .\n"
417 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
418 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
419 " ?work bf:workTitle/bf:titleValue ?v0 "
420 "FILTER(contains(?v0, \"computer\"))\n"
424 YAZ_CHECK(test_query(
425 s, "@attr 1=bf.creator london",
426 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
427 "PREFIX bf: <http://bibframe.org/vocab/>\n"
428 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
429 "SELECT ?title ?author ?description ?ititle\n"
431 " ?work a bf:Work .\n"
432 " ?work bf:workTitle/bf:titleValue ?title .\n"
433 " ?work bf:creator/bf:label ?author .\n"
434 " ?work bf:note ?description .\n"
435 " ?inst bf:instanceOf ?work .\n"
436 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
437 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
438 " ?work bf:creator/bf:label ?v0 "
439 "FILTER(contains(?v0, \"london\"))\n"
442 YAZ_CHECK(test_query(
443 s, "@or @and @attr 1=bf.creator a @attr 1=bf.title b @attr 1=bf.title c",
444 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
445 "PREFIX bf: <http://bibframe.org/vocab/>\n"
446 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
447 "SELECT ?title ?author ?description ?ititle\n"
449 " ?work a bf:Work .\n"
450 " ?work bf:workTitle/bf:titleValue ?title .\n"
451 " ?work bf:creator/bf:label ?author .\n"
452 " ?work bf:note ?description .\n"
453 " ?inst bf:instanceOf ?work .\n"
454 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
455 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
457 " ?work bf:creator/bf:label ?v0 "
458 "FILTER(contains(?v0, \"a\")) .\n"
459 " ?work bf:workTitle/bf:titleValue ?v1 "
460 "FILTER(contains(?v1, \"b\"))\n"
462 " ?work bf:workTitle/bf:titleValue ?v2 "
463 "FILTER(contains(?v2, \"c\"))\n"
468 yaz_sparql_destroy(s);
471 int main(int argc, char **argv)
473 YAZ_CHECK_INIT(argc, argv);
482 * c-file-style: "Stroustrup"
483 * indent-tabs-mode: nil
485 * vim: shiftwidth=4 tabstop=8 expandtab