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");
154 yaz_sparql_add_pattern(s, "present.brief", "SELECT %u");
156 YAZ_CHECK(test_uri(s, "http://x/y", "full",
157 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
158 "PREFIX bf: <http://bibframe.org/vocab/>\n"
159 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
160 "SELECT ?sub ?rel WHERE ?work = <http://x/y>\n"));
163 YAZ_CHECK(test_uri(s, "http://x/z", "brief",
164 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
165 "PREFIX bf: <http://bibframe.org/vocab/>\n"
166 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
167 "SELECT <http://x/z>\n"));
169 YAZ_CHECK(test_query(
170 s, "@attr 1=bf.title computer",
171 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
172 "PREFIX bf: <http://bibframe.org/vocab/>\n"
173 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
174 "SELECT ?title ?author ?description ?ititle\n"
176 " ?work a bf:Work .\n"
177 " ?work bf:workTitle/bf:titleValue ?title .\n"
178 " ?work bf:creator/bf:label ?author .\n"
179 " ?work bf:note ?description .\n"
180 " ?inst bf:instanceOf ?work .\n"
181 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
182 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
183 " ?work bf:workTitle/bf:titleValue ?o1 "
184 "FILTER(contains(?o1, \"computer\"))\n"
188 YAZ_CHECK(test_query(
189 s, "@attr 1=bf.creator london",
190 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
191 "PREFIX bf: <http://bibframe.org/vocab/>\n"
192 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
193 "SELECT ?title ?author ?description ?ititle\n"
195 " ?work a bf:Work .\n"
196 " ?work bf:workTitle/bf:titleValue ?title .\n"
197 " ?work bf:creator/bf:label ?author .\n"
198 " ?work bf:note ?description .\n"
199 " ?inst bf:instanceOf ?work .\n"
200 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
201 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
202 " ?work bf:creator/bf:label ?o2 "
203 "FILTER(contains(?o2, \"london\"))\n"
207 YAZ_CHECK(test_query(
208 s, "@and @attr 1=bf.creator london @attr 1=bf.title computer",
209 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
210 "PREFIX bf: <http://bibframe.org/vocab/>\n"
211 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
212 "SELECT ?title ?author ?description ?ititle\n"
214 " ?work a bf:Work .\n"
215 " ?work bf:workTitle/bf:titleValue ?title .\n"
216 " ?work bf:creator/bf:label ?author .\n"
217 " ?work bf:note ?description .\n"
218 " ?inst bf:instanceOf ?work .\n"
219 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
220 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
221 " ?work bf:creator/bf:label ?o2 "
222 "FILTER(contains(?o2, \"london\")) .\n"
223 " ?work bf:workTitle/bf:titleValue ?o1 "
224 "FILTER(contains(?o1, \"computer\"))\n"
227 YAZ_CHECK(test_query(
228 s, "@or @attr 1=bf.creator london @attr 1=bf.title computer",
229 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
230 "PREFIX bf: <http://bibframe.org/vocab/>\n"
231 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
232 "SELECT ?title ?author ?description ?ititle\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"
242 " ?work bf:creator/bf:label ?o2 "
243 "FILTER(contains(?o2, \"london\"))\n"
245 " ?work bf:workTitle/bf:titleValue ?o1 "
246 "FILTER(contains(?o1, \"computer\"))\n"
251 YAZ_CHECK(test_query(
252 s, "@or @or @attr 1=bf.creator a @attr 1=bf.title b @attr 1=bf.title c",
253 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
254 "PREFIX bf: <http://bibframe.org/vocab/>\n"
255 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
256 "SELECT ?title ?author ?description ?ititle\n"
258 " ?work a bf:Work .\n"
259 " ?work bf:workTitle/bf:titleValue ?title .\n"
260 " ?work bf:creator/bf:label ?author .\n"
261 " ?work bf:note ?description .\n"
262 " ?inst bf:instanceOf ?work .\n"
263 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
264 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
267 " ?work bf:creator/bf:label ?o2 "
268 "FILTER(contains(?o2, \"a\"))\n"
270 " ?work bf:workTitle/bf:titleValue ?o1 "
271 "FILTER(contains(?o1, \"b\"))\n"
274 " ?work bf:workTitle/bf:titleValue ?o1 "
275 "FILTER(contains(?o1, \"c\"))\n"
280 YAZ_CHECK(test_query(
281 s, "@or @and @attr 1=bf.creator a @attr 1=bf.title b @attr 1=bf.title c",
282 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
283 "PREFIX bf: <http://bibframe.org/vocab/>\n"
284 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
285 "SELECT ?title ?author ?description ?ititle\n"
287 " ?work a bf:Work .\n"
288 " ?work bf:workTitle/bf:titleValue ?title .\n"
289 " ?work bf:creator/bf:label ?author .\n"
290 " ?work bf:note ?description .\n"
291 " ?inst bf:instanceOf ?work .\n"
292 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
293 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
295 " ?work bf:creator/bf:label ?o2 "
296 "FILTER(contains(?o2, \"a\")) .\n"
297 " ?work bf:workTitle/bf:titleValue ?o1 "
298 "FILTER(contains(?o1, \"b\"))\n"
300 " ?work bf:workTitle/bf:titleValue ?o1 "
301 "FILTER(contains(?o1, \"c\"))\n"
306 YAZ_CHECK(test_query(
307 s, "@and @and @attr 1=bf.creator a @attr 1=bf.title b @attr 1=bf.title c",
308 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
309 "PREFIX bf: <http://bibframe.org/vocab/>\n"
310 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
311 "SELECT ?title ?author ?description ?ititle\n"
313 " ?work a bf:Work .\n"
314 " ?work bf:workTitle/bf:titleValue ?title .\n"
315 " ?work bf:creator/bf:label ?author .\n"
316 " ?work bf:note ?description .\n"
317 " ?inst bf:instanceOf ?work .\n"
318 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
319 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
320 " ?work bf:creator/bf:label ?o2 "
321 "FILTER(contains(?o2, \"a\")) .\n"
322 " ?work bf:workTitle/bf:titleValue ?o1 "
323 "FILTER(contains(?o1, \"b\")) .\n"
324 " ?work bf:workTitle/bf:titleValue ?o1 "
325 "FILTER(contains(?o1, \"c\"))\n"
329 YAZ_CHECK(test_query(
330 s, "@and @attr 1=bf.title \"Phantom Tollbooth\" "
331 "@attr 1=bf.nearby \"40.1583 83.0742 30\"",
332 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
333 "PREFIX bf: <http://bibframe.org/vocab/>\n"
334 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
335 "SELECT ?title ?author ?description ?ititle\n"
337 " ?work a bf:Work .\n"
338 " ?work bf:workTitle/bf:titleValue ?title .\n"
339 " ?work bf:creator/bf:label ?author .\n"
340 " ?work bf:note ?description .\n"
341 " ?inst bf:instanceOf ?work .\n"
342 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
343 " ?inst bf:heldBy ?lib .\n"
344 " ?work bf:workTitle/bf:titleValue ?o1 "
345 "FILTER(contains(?o1, \"Phantom Tollbooth\")) .\n"
346 " ?lib gs:nearby (40.1583 83.0742 30)\n"
350 YAZ_CHECK(test_query(
351 s, "@attr 1=bf.isbn 9780316154697",
352 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
353 "PREFIX bf: <http://bibframe.org/vocab/>\n"
354 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
355 "SELECT ?title ?author ?description ?ititle\n"
357 " ?work a bf:Work .\n"
358 " ?work bf:workTitle/bf:titleValue ?title .\n"
359 " ?work bf:creator/bf:label ?author .\n"
360 " ?work bf:note ?description .\n"
361 " ?inst bf:instanceOf ?work .\n"
362 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
363 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
364 " ?inst bf:ISBN \"9780316154697\"\n"
369 yaz_sparql_destroy(s);
372 static void tst2(void)
374 yaz_sparql_t s = yaz_sparql_create();
375 yaz_sparql_t s2 = yaz_sparql_create();
377 yaz_sparql_add_pattern(s, "prefix",
378 "rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns");
379 yaz_sparql_add_pattern(s, "prefix",
380 "bf: <http://bibframe.org/vocab/>");
381 yaz_sparql_add_pattern(s, "prefix",
382 "gs: http://gs.com/panorama/domain-model");
383 yaz_sparql_add_pattern(s, "form", "SELECT ?title ?author ?description ?ititle");
384 yaz_sparql_add_pattern(s, "criteria", "?work a bf:Work");
385 yaz_sparql_add_pattern(s, "criteria", "?work bf:workTitle/bf:titleValue ?title");
386 yaz_sparql_add_pattern(s, "criteria", "?work bf:creator/bf:label ?author");
387 yaz_sparql_add_pattern(s, "criteria", "?work bf:note ?description");
388 yaz_sparql_add_pattern(s, "criteria", "?inst bf:instanceOf ?work");
389 yaz_sparql_add_pattern(s, "criteria", "?inst bf:instanceTitle/bf:titleValue ?ititle");
390 yaz_sparql_add_pattern(s, "criteria.optional", "?inst bf:heldBy ?lib");
392 yaz_sparql_add_pattern(s, "index.bf.title",
393 "?work bf:workTitle/bf:titleValue %v "
394 "FILTER(contains(%v, %s))");
395 yaz_sparql_add_pattern(s, "index.bf.creator",
396 "?work bf:creator/bf:label %v "
397 "FILTER(contains(%v, %s))");
398 yaz_sparql_add_pattern(s, "index.bf.authorityCreator",
399 "?work bf:author %s");
400 yaz_sparql_add_pattern(s, "index.bf.type", "?inst rdf:type %s");
401 yaz_sparql_add_pattern(s, "index.bf.format",
402 "?inst bf:format %v FILTER(contains(%v, %s))");
403 yaz_sparql_add_pattern(s, "index.bf.nearby", "?lib gs:nearby (%d)");
404 yaz_sparql_add_pattern(s, "index.bf.baseTitle",
405 "?work bf:derivativeOf/bf:workTitle/bf:titleValue "
406 "%v FILTER(contains(%v, %s))");
407 yaz_sparql_add_pattern(s, "index.bf.baseCreator",
408 "?work bf:derivativeOf/bf:creator/bf:label "
409 "%v FILTER(contains(%v, %s))");
410 yaz_sparql_add_pattern(s, "index.bf.targetAudience",
411 "?work bf:targetAudience %s");
412 yaz_sparql_add_pattern(s, "index.bf.isbn", "?inst bf:ISBN %s");
414 YAZ_CHECK(test_query(
415 s, "@attr 1=bf.title computer",
416 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
417 "PREFIX bf: <http://bibframe.org/vocab/>\n"
418 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
419 "SELECT ?title ?author ?description ?ititle\n"
421 " ?work a bf:Work .\n"
422 " ?work bf:workTitle/bf:titleValue ?title .\n"
423 " ?work bf:creator/bf:label ?author .\n"
424 " ?work bf:note ?description .\n"
425 " ?inst bf:instanceOf ?work .\n"
426 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
427 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
428 " ?work bf:workTitle/bf:titleValue ?v0 "
429 "FILTER(contains(?v0, \"computer\"))\n"
433 YAZ_CHECK(test_query(
434 s, "@attr 1=bf.creator london",
435 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
436 "PREFIX bf: <http://bibframe.org/vocab/>\n"
437 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
438 "SELECT ?title ?author ?description ?ititle\n"
440 " ?work a bf:Work .\n"
441 " ?work bf:workTitle/bf:titleValue ?title .\n"
442 " ?work bf:creator/bf:label ?author .\n"
443 " ?work bf:note ?description .\n"
444 " ?inst bf:instanceOf ?work .\n"
445 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
446 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
447 " ?work bf:creator/bf:label ?v0 "
448 "FILTER(contains(?v0, \"london\"))\n"
453 yaz_sparql_include(s2, s);
455 YAZ_CHECK(test_query(
456 s2, "@or @and @attr 1=bf.creator a @attr 1=bf.title b @attr 1=bf.title c",
457 "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>\n"
458 "PREFIX bf: <http://bibframe.org/vocab/>\n"
459 "PREFIX gs: <http://gs.com/panorama/domain-model>\n"
460 "SELECT ?title ?author ?description ?ititle\n"
462 " ?work a bf:Work .\n"
463 " ?work bf:workTitle/bf:titleValue ?title .\n"
464 " ?work bf:creator/bf:label ?author .\n"
465 " ?work bf:note ?description .\n"
466 " ?inst bf:instanceOf ?work .\n"
467 " ?inst bf:instanceTitle/bf:titleValue ?ititle .\n"
468 " OPTIONAL { ?inst bf:heldBy ?lib } .\n"
470 " ?work bf:creator/bf:label ?v0 "
471 "FILTER(contains(?v0, \"a\")) .\n"
472 " ?work bf:workTitle/bf:titleValue ?v1 "
473 "FILTER(contains(?v1, \"b\"))\n"
475 " ?work bf:workTitle/bf:titleValue ?v2 "
476 "FILTER(contains(?v2, \"c\"))\n"
481 yaz_sparql_destroy(s2);
482 yaz_sparql_destroy(s);
485 int main(int argc, char **argv)
487 YAZ_CHECK_INIT(argc, argv);
496 * c-file-style: "Stroustrup"
497 * indent-tabs-mode: nil
499 * vim: shiftwidth=4 tabstop=8 expandtab