From f2974f80186a59222190ad335575b564f27b5222 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 4 Nov 2014 15:02:49 +0100 Subject: [PATCH] First work on SPARQL stuff --- include/yaz/Makefile.am | 2 +- include/yaz/sparql.h | 77 ++++++++++++++++++++++++++++ src/Makefile.am | 2 +- src/sparql.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++ test/.gitignore | 3 +- test/Makefile.am | 3 +- test/test_sparql.c | 97 ++++++++++++++++++++++++++++++++++++ win/makefile | 1 + 8 files changed, 308 insertions(+), 4 deletions(-) create mode 100644 include/yaz/sparql.h create mode 100644 src/sparql.c create mode 100644 test/test_sparql.c diff --git a/include/yaz/Makefile.am b/include/yaz/Makefile.am index 0c5ab8a..c5ac591 100644 --- a/include/yaz/Makefile.am +++ b/include/yaz/Makefile.am @@ -24,7 +24,7 @@ pkginclude_HEADERS= backend.h base64.h \ zes-psched.h zes-admin.h zes-pset.h zes-update.h zes-update0.h \ zoom.h z-charneg.h charneg.h soap.h srw.h zgdu.h matchstr.h json.h \ file_glob.h dirent.h thread_id.h gettimeofday.h shptr.h thread_create.h \ - spipe.h stemmer.h url.h + spipe.h stemmer.h url.h sparql.h EXTRA_DIST = yaz-version.h.in diff --git a/include/yaz/sparql.h b/include/yaz/sparql.h new file mode 100644 index 0000000..755909a --- /dev/null +++ b/include/yaz/sparql.h @@ -0,0 +1,77 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) Index Data. + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Index Data nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** \file + \brief Header for RPN to CQL tranform +*/ + +#ifndef SPARQL_H_INCLUDED +#define SPARQL_H_INCLUDED + +#include +#include +#include + +YAZ_BEGIN_CDECL + +typedef struct yaz_sparql_s *yaz_sparql_t; + +YAZ_EXPORT +yaz_sparql_t yaz_sparql_create(void); + +YAZ_EXPORT +void yaz_sparql_destroy(yaz_sparql_t s); + +YAZ_EXPORT +int yaz_sparql_add_pattern(yaz_sparql_t s, const char *pattern, + const char *value); + +YAZ_EXPORT +int yaz_sparql_from_rpn_stream(yaz_sparql_t s, + WRBUF addinfo, + void (*pr)(const char *buf, + void *client_data), + void *client_data, + Z_RPNQuery *q); + +YAZ_EXPORT +int yaz_sparql_from_rpn_wrbuf(yaz_sparql_t s, WRBUF addinfo, WRBUF w, + Z_RPNQuery *q); + +YAZ_END_CDECL + +#endif +/* CQL_H_INCLUDED */ +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/Makefile.am b/src/Makefile.am index 3f431f0..5b7fc5f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -111,7 +111,7 @@ libyaz_la_SOURCES= $(GEN_FILES) \ iconv_encode_marc8.c iconv_encode_iso_8859_1.c iconv_encode_wchar.c \ iconv_decode_marc8.c iconv_decode_iso5426.c iconv_decode_danmarc.c sc.c \ json.c xml_include.c file_glob.c dirent.c mutex-p.h mutex.c condvar.c \ - thread_id.c gettimeofday.c thread_create.c spipe.c url.c + thread_id.c gettimeofday.c thread_create.c spipe.c url.c sparql.c libyaz_la_LDFLAGS=-version-info $(YAZ_VERSION_INFO) diff --git a/src/sparql.c b/src/sparql.c new file mode 100644 index 0000000..a62a80d --- /dev/null +++ b/src/sparql.c @@ -0,0 +1,127 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) Index Data + * See the file LICENSE for details. + */ +/** + * \file sparql.c + * \brief SPARQL + */ +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +struct sparql_entry { + char *pattern; + char *value; + struct sparql_entry *next; +}; + +struct yaz_sparql_s { + NMEM nmem; + struct sparql_entry *conf; + struct sparql_entry **last; +}; + +yaz_sparql_t yaz_sparql_create(void) +{ + NMEM nmem = nmem_create(); + yaz_sparql_t s = (yaz_sparql_t) nmem_malloc(nmem, sizeof *s); + + s->nmem = nmem; + s->conf = 0; + s->last = &s->conf; + return s; +} + +void yaz_sparql_destroy(yaz_sparql_t s) +{ + if (s) + nmem_destroy(s->nmem); +} + +int yaz_sparql_add_pattern(yaz_sparql_t s, const char *pattern, + const char *value) +{ + struct sparql_entry *e; + assert(s); + + e = (struct sparql_entry *) nmem_malloc(s->nmem, sizeof(*e)); + e->pattern = nmem_strdup(s->nmem, pattern); + e->value = nmem_strdup(s->nmem, value); + e->next = 0; + *s->last = e; + s->last = &e->next; + return 0; +} + +int yaz_sparql_from_rpn_wrbuf(yaz_sparql_t s, WRBUF addinfo, WRBUF w, + Z_RPNQuery *q) +{ + return yaz_sparql_from_rpn_stream(s, addinfo, wrbuf_vp_puts, w, q); +} + +int yaz_sparql_from_rpn_stream(yaz_sparql_t s, + WRBUF addinfo, + void (*pr)(const char *buf, + void *client_data), + void *client_data, + Z_RPNQuery *q) +{ + struct sparql_entry *e; + yaz_tok_cfg_t cfg = yaz_tok_cfg_create(); + int errors = 0; + + for (e = s->conf; e; e = e->next) + { + if (!strcmp(e->pattern, "prefix")) + { + yaz_tok_parse_t p = yaz_tok_parse_buf(cfg, e->value); + int token; + + token = yaz_tok_move(p); + if (token != YAZ_TOK_STRING) + errors++; + else + { + const char *tok_str = yaz_tok_parse_string(p); + pr("PREFIX ", client_data); + pr(tok_str, client_data); + 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 == '<') + pr(tok_str, client_data); + else + { + pr("<", client_data); + pr(tok_str, client_data); + pr(">", client_data); + } + } + pr("\n", client_data); + } + } + } + yaz_tok_cfg_destroy(cfg); + + return errors ? -1 : 0; +} + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/test/.gitignore b/test/.gitignore index 7f2149a..9b28c92 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -15,6 +15,7 @@ test_wrbuf test_log test_soap1 test_soap2 +test_sparql test_odrstack test_logthread test_xmlquery @@ -49,4 +50,4 @@ test_zgdu *.diff *.hex* *.revert* -*.trs \ No newline at end of file +*.trs diff --git a/test/Makefile.am b/test/Makefile.am index 905526d..d009b4f 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -11,7 +11,7 @@ check_PROGRAMS = test_ccl test_comstack test_cql2ccl \ test_record_conv test_rpn2cql test_rpn2solr test_retrieval \ test_shared_ptr test_soap1 test_soap2 test_solr test_sortspec \ test_timing test_tpath test_wrbuf \ - test_xmalloc test_xml_include test_xmlquery test_zgdu + test_xmalloc test_xml_include test_xmlquery test_zgdu test_sparql check_SCRIPTS = test_marc.sh test_marccol.sh test_cql2xcql.sh \ test_cql2pqf.sh test_icu.sh @@ -100,4 +100,5 @@ test_file_glob_SOURCES = test_file_glob.c test_shared_ptr_SOURCES = test_shared_ptr.c test_libstemmer_SOURCES = test_libstemmer.c test_embed_record_SOURCES = test_embed_record.c +test_sparql_SOURCES = test_sparql.c test_zgdu_SOURCES = test_zgdu.c diff --git a/test/test_sparql.c b/test/test_sparql.c new file mode 100644 index 0000000..75c1c21 --- /dev/null +++ b/test/test_sparql.c @@ -0,0 +1,97 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) Index Data + * See the file LICENSE for details. + */ +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +static int test_query(yaz_sparql_t s, const char *pqf, const char *expect) +{ + YAZ_PQF_Parser parser = yaz_pqf_create(); + ODR odr = odr_createmem(ODR_ENCODE); + Z_RPNQuery *rpn = yaz_pqf_parse(parser, odr, pqf); + int ret = 0; + WRBUF addinfo = wrbuf_alloc(); + WRBUF w = wrbuf_alloc(); + + if (rpn) + { + int r = yaz_sparql_from_rpn_wrbuf(s, addinfo, w, rpn); + if (expect) + { + if (!r) + { + if (!strcmp(expect, wrbuf_cstr(w))) + ret = 1; + else + { + yaz_log(YLOG_WARN, "test_sparql: pqf=%s", pqf); + yaz_log(YLOG_WARN, " expect: %s", expect); + yaz_log(YLOG_WARN, " got: %s", wrbuf_cstr(w)); + } + } + else + { + yaz_log(YLOG_WARN, "test_sparql: pqf=%s", pqf); + yaz_log(YLOG_WARN, " expect: %s", expect); + yaz_log(YLOG_WARN, " got error: %d:%s", r, wrbuf_cstr(addinfo)); + } + } + else + { + if (r) + ret = 1; + else + { + yaz_log(YLOG_WARN, "test_sparql: pqf=%s", pqf); + yaz_log(YLOG_WARN, " expect error"); + yaz_log(YLOG_WARN, " got: %s", wrbuf_cstr(w)); + } + } + } + wrbuf_destroy(w); + wrbuf_destroy(addinfo); + odr_destroy(odr); + yaz_pqf_destroy(parser); + return ret; +} + +static void tst1(void) +{ + yaz_sparql_t s = yaz_sparql_create(); + + yaz_sparql_add_pattern(s, "prefix", + "rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns"); + yaz_sparql_add_pattern(s, "prefix", + "bf: "); + YAZ_CHECK(test_query( + s, "computer", + "PREFIX rdf: \n" + "PREFIX bf: \n")); + + yaz_sparql_destroy(s); +} + +int main(int argc, char **argv) +{ + YAZ_CHECK_INIT(argc, argv); + YAZ_CHECK_LOG(); + tst1(); + YAZ_CHECK_TERM; +} +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/win/makefile b/win/makefile index 9d9395d..9e8fc88 100644 --- a/win/makefile +++ b/win/makefile @@ -555,6 +555,7 @@ MISC_OBJS= \ $(OBJDIR)\file_glob.obj \ $(OBJDIR)\thread_id.obj \ $(OBJDIR)\dirent.obj \ + $(OBJDIR)\sparql.obj \ $(OBJDIR)\url.obj Z3950_OBJS= \ -- 1.7.10.4