Repository: marmotta Updated Branches: refs/heads/develop 0ff22a0c3 -> 47ed3b633
support native SPARQL query evaluation for tuple queries Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/47ed3b63 Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/47ed3b63 Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/47ed3b63 Branch: refs/heads/develop Commit: 47ed3b6333c81a6235c2e920206e87799ed5edbf Parents: 0ff22a0 Author: Sebastian Schaffert <[email protected]> Authored: Sat Dec 12 18:32:43 2015 +0100 Committer: Sebastian Schaffert <[email protected]> Committed: Sat Dec 12 18:32:43 2015 +0100 ---------------------------------------------------------------------- .../ostrich/backend/sparql/rasqal_model.cc | 12 ++ .../ostrich/sail/OstrichSailConnection.java | 14 ++- .../backend/ostrich/OstrichProvider.java | 3 + .../backend/ostrich/OstrichSailRepository.java | 112 +++++++++++++++++++ .../main/resources/config-defaults.properties | 3 +- .../resources/config-descriptions.properties | 7 +- 6 files changed, 146 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/marmotta/blob/47ed3b63/libraries/ostrich/backend/sparql/rasqal_model.cc ---------------------------------------------------------------------- diff --git a/libraries/ostrich/backend/sparql/rasqal_model.cc b/libraries/ostrich/backend/sparql/rasqal_model.cc index 346b831..e7dbbf1 100644 --- a/libraries/ostrich/backend/sparql/rasqal_model.cc +++ b/libraries/ostrich/backend/sparql/rasqal_model.cc @@ -29,6 +29,10 @@ namespace rasqal { #define CPSTR(s) (const unsigned char*)strdup(s.c_str()) rdf::Resource ConvertResource(rasqal_literal *node) { + if (node == nullptr) { + return rdf::Resource(); + } + switch (node->type) { case RASQAL_LITERAL_URI: return rdf::URI(std::string((const char*)raptor_uri_as_string(node->value.uri))); @@ -42,6 +46,10 @@ rdf::Resource ConvertResource(rasqal_literal *node) { rdf::Value ConvertValue(rasqal_literal *node) { + if (node == nullptr) { + return rdf::Value(); + } + std::string label((const char*)node->string, node->string_len); rdf::Value r; char* s; @@ -99,6 +107,10 @@ rdf::Value ConvertValue(rasqal_literal *node) { rdf::URI ConvertURI(rasqal_literal *node) { + if (node == nullptr) { + return rdf::URI(); + } + switch (node->type) { case RASQAL_LITERAL_URI: return rdf::URI((const char*)raptor_uri_as_string(node->value.uri)); http://git-wip-us.apache.org/repos/asf/marmotta/blob/47ed3b63/libraries/ostrich/client/src/main/java/org/apache/marmotta/ostrich/sail/OstrichSailConnection.java ---------------------------------------------------------------------- diff --git a/libraries/ostrich/client/src/main/java/org/apache/marmotta/ostrich/sail/OstrichSailConnection.java b/libraries/ostrich/client/src/main/java/org/apache/marmotta/ostrich/sail/OstrichSailConnection.java index bb80665..93e21ac 100644 --- a/libraries/ostrich/client/src/main/java/org/apache/marmotta/ostrich/sail/OstrichSailConnection.java +++ b/libraries/ostrich/client/src/main/java/org/apache/marmotta/ostrich/sail/OstrichSailConnection.java @@ -197,18 +197,24 @@ public class OstrichSailConnection extends NotifyingSailConnectionBase { switch(b.getValue().getResource().getResourcesCase()) { case URI: v = new ProtoURI(b.getValue().getResource().getUri()); + break; case BNODE: v = new ProtoBNode(b.getValue().getResource().getBnode()); + break; } case LITERAL: switch(b.getValue().getLiteral().getLiteralsCase()) { case STRINGLITERAL: v = new ProtoStringLiteral(b.getValue().getLiteral().getStringliteral()); + break; case DATALITERAL: v = new ProtoDatatypeLiteral(b.getValue().getLiteral().getDataliteral()); + break; } } - result.addBinding(b.getVariable(), v); + if (v != null) { + result.addBinding(b.getVariable(), v); + } } return result; } @@ -305,8 +311,10 @@ public class OstrichSailConnection extends NotifyingSailConnectionBase { @Override protected void rollbackInternal() throws SailException { - updateRequestObserver.onError(new Exception("transaction rollback")); - updateRequestObserver = null; + if (updateRequestObserver != null) { + updateRequestObserver.onError(new Exception("transaction rollback")); + updateRequestObserver = null; + } } @Override http://git-wip-us.apache.org/repos/asf/marmotta/blob/47ed3b63/platform/backends/marmotta-backend-ostrich/src/main/java/org/apache/marmotta/platform/backend/ostrich/OstrichProvider.java ---------------------------------------------------------------------- diff --git a/platform/backends/marmotta-backend-ostrich/src/main/java/org/apache/marmotta/platform/backend/ostrich/OstrichProvider.java b/platform/backends/marmotta-backend-ostrich/src/main/java/org/apache/marmotta/platform/backend/ostrich/OstrichProvider.java index e62d639..9afa74b 100644 --- a/platform/backends/marmotta-backend-ostrich/src/main/java/org/apache/marmotta/platform/backend/ostrich/OstrichProvider.java +++ b/platform/backends/marmotta-backend-ostrich/src/main/java/org/apache/marmotta/platform/backend/ostrich/OstrichProvider.java @@ -68,6 +68,9 @@ public class OstrichProvider implements StoreProvider { */ @Override public SailRepository createRepository(Sail sail) { + if (configurationService.getBooleanConfiguration("ostrich.sparql.native", true)) { + return new OstrichSailRepository(sail); + } return new SailRepository(sail); } http://git-wip-us.apache.org/repos/asf/marmotta/blob/47ed3b63/platform/backends/marmotta-backend-ostrich/src/main/java/org/apache/marmotta/platform/backend/ostrich/OstrichSailRepository.java ---------------------------------------------------------------------- diff --git a/platform/backends/marmotta-backend-ostrich/src/main/java/org/apache/marmotta/platform/backend/ostrich/OstrichSailRepository.java b/platform/backends/marmotta-backend-ostrich/src/main/java/org/apache/marmotta/platform/backend/ostrich/OstrichSailRepository.java new file mode 100644 index 0000000..0dbf1e8 --- /dev/null +++ b/platform/backends/marmotta-backend-ostrich/src/main/java/org/apache/marmotta/platform/backend/ostrich/OstrichSailRepository.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.marmotta.platform.backend.ostrich; + +import info.aduna.iteration.CloseableIteration; +import org.apache.marmotta.ostrich.sail.OstrichSailConnection; +import org.openrdf.query.*; +import org.openrdf.query.impl.TupleQueryResultImpl; +import org.openrdf.query.parser.ParsedQuery; +import org.openrdf.query.parser.ParsedTupleQuery; +import org.openrdf.query.parser.QueryParserUtil; +import org.openrdf.repository.RepositoryException; +import org.openrdf.repository.sail.SailQuery; +import org.openrdf.repository.sail.SailRepository; +import org.openrdf.repository.sail.SailRepositoryConnection; +import org.openrdf.repository.sail.SailTupleQuery; +import org.openrdf.sail.Sail; +import org.openrdf.sail.SailConnection; +import org.openrdf.sail.SailException; +import org.openrdf.sail.helpers.SailConnectionWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; + +/** + * A wrapper SailRepository for Ostrich allowing access to direct SPARQL support. + * + * @author Sebastian Schaffert ([email protected]) + */ +public class OstrichSailRepository extends SailRepository { + private static Logger log = LoggerFactory.getLogger(OstrichSailRepository.class); + + public OstrichSailRepository(Sail sail) { + super(sail); + } + + @Override + public SailRepositoryConnection getConnection() throws RepositoryException { + try { + final SailConnection con = getSail().getConnection(); + + return new SailRepositoryConnection(this, con) { + @Override + public SailTupleQuery prepareTupleQuery(final QueryLanguage ql, final String queryString, final String baseURI) throws MalformedQueryException { + if (ql == QueryLanguage.SPARQL) { + return new SailTupleQuery(null, this) { + @Override + public TupleQueryResult evaluate() throws QueryEvaluationException { + try { + log.info("Running native SPARQL query: {}", queryString); + CloseableIteration<? extends BindingSet, QueryEvaluationException> bindingsIter; + + // Let Sesame still parse the query for better error messages and for the binding names. + ParsedTupleQuery parsedQuery = QueryParserUtil.parseTupleQuery(ql, queryString, baseURI); + OstrichSailConnection sailCon = findConnection(getConnection().getSailConnection()); + bindingsIter = sailCon.directTupleQuery(queryString); + bindingsIter = enforceMaxQueryTime(bindingsIter); + + return new TupleQueryResultImpl(new ArrayList<String>(parsedQuery.getTupleExpr().getBindingNames()), bindingsIter); + } catch (SailException e) { + throw new QueryEvaluationException(e.getMessage(), e); + } catch (MalformedQueryException e) { + throw new QueryEvaluationException(e.getMessage(), e); + } + } + }; + } else { + return super.prepareTupleQuery(ql, queryString, baseURI); + } + } + + @Override + public SailQuery prepareQuery(QueryLanguage ql, String queryString, String baseURI) throws MalformedQueryException { + ParsedQuery parsedQuery = QueryParserUtil.parseQuery(ql, queryString, baseURI); + + if (parsedQuery instanceof ParsedTupleQuery) { + return prepareTupleQuery(ql, queryString, baseURI); + } else { + return super.prepareQuery(ql, queryString, baseURI); + } + } + }; + } catch (SailException e) { + throw new RepositoryException("could not create repository connection",e); + } + } + + private static OstrichSailConnection findConnection(SailConnection current) { + if (current instanceof OstrichSailConnection) { + return (OstrichSailConnection)current; + } else if (current instanceof SailConnectionWrapper) { + return findConnection(((SailConnectionWrapper) current).getWrappedConnection()); + } + return null; + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/47ed3b63/platform/backends/marmotta-backend-ostrich/src/main/resources/config-defaults.properties ---------------------------------------------------------------------- diff --git a/platform/backends/marmotta-backend-ostrich/src/main/resources/config-defaults.properties b/platform/backends/marmotta-backend-ostrich/src/main/resources/config-defaults.properties index 0bad4d9..c374747 100644 --- a/platform/backends/marmotta-backend-ostrich/src/main/resources/config-defaults.properties +++ b/platform/backends/marmotta-backend-ostrich/src/main/resources/config-defaults.properties @@ -21,4 +21,5 @@ ############################################################################### ostrich.host = localhost -ostrich.port = 10000 \ No newline at end of file +ostrich.port = 10000 +ostrich.sparql.native = true \ No newline at end of file http://git-wip-us.apache.org/repos/asf/marmotta/blob/47ed3b63/platform/backends/marmotta-backend-ostrich/src/main/resources/config-descriptions.properties ---------------------------------------------------------------------- diff --git a/platform/backends/marmotta-backend-ostrich/src/main/resources/config-descriptions.properties b/platform/backends/marmotta-backend-ostrich/src/main/resources/config-descriptions.properties index 378d664..6fbab48 100644 --- a/platform/backends/marmotta-backend-ostrich/src/main/resources/config-descriptions.properties +++ b/platform/backends/marmotta-backend-ostrich/src/main/resources/config-descriptions.properties @@ -22,5 +22,10 @@ ostrich.host.description = Host name of the server running the LevelDB/Ostrich backend server, ostrich.host.type = java.lang.String -ostrich.portt.description = Port of the server running the LevelDB/Ostrich backend server. +ostrich.port.description = Port of the server running the LevelDB/Ostrich backend server. ostrich.port.type = java.lang.Integer + +ostrich.sparql.native.description = Use faster native SPARQL support where possible instead of \ + interpreted client side support. +ostrich.sparql.native.type = java.lang.Booleanr +
