You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ss...@apache.org on 2013/11/06 17:09:06 UTC
git commit: SPARQL fulltext support
Updated Branches:
refs/heads/develop 90bd64034 -> c0e5d9daf
SPARQL fulltext support
Project: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/commit/c0e5d9da
Tree: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/tree/c0e5d9da
Diff: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/diff/c0e5d9da
Branch: refs/heads/develop
Commit: c0e5d9dafc88b99734afbcdc4837e46aef86f7a0
Parents: 90bd640
Author: Sebastian Schaffert <ss...@apache.org>
Authored: Wed Nov 6 17:09:01 2013 +0100
Committer: Sebastian Schaffert <ss...@apache.org>
Committed: Wed Nov 6 17:09:01 2013 +0100
----------------------------------------------------------------------
.../sparql/function/FulltextQueryFunction.java | 47 ++++++++++++
.../sparql/function/FulltextSearchFunction.java | 46 ++++++++++++
.../kiwi/sparql/sail/KiWiSparqlSail.java | 79 +++++++++++++++++++-
...f.query.algebra.evaluation.function.Function | 2 +
.../persistence/h2/create_fulltext_index.sql | 21 ++++++
.../persistence/mysql/create_fulltext_index.sql | 20 +++++
.../persistence/pgsql/create_fulltext_index.sql | 20 +++++
.../pgsql/create_fulltext_index_generic.sql | 20 +++++
.../pgsql/create_fulltext_langlookup.sql | 42 +++++++++++
.../kiwi/sparql/test/KiWiSparqlJoinTest.java | 63 ++++++++++++++++
.../marmotta/kiwi/sparql/test/query22.sparql | 27 +++++++
.../marmotta/kiwi/sparql/test/query23.sparql | 27 +++++++
.../marmotta/kiwi/config/KiWiConfiguration.java | 42 +++++++++++
.../kiwi/persistence/KiWiConnection.java | 75 ++++++++++++++++++-
.../kiwi/persistence/mysql/MySQLDialect.java | 18 +++++
.../persistence/pgsql/PostgreSQLDialect.java | 19 +++++
.../marmotta/kiwi/vocabulary/FN_MARMOTTA.java | 41 ++++++++++
.../kiwi/persistence/h2/statements.properties | 3 +
.../persistence/mysql/create_base_tables.sql | 2 +-
.../persistence/mysql/statements.properties | 3 +
.../persistence/pgsql/statements.properties | 3 +
21 files changed, 615 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/FulltextQueryFunction.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/FulltextQueryFunction.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/FulltextQueryFunction.java
new file mode 100644
index 0000000..222487b
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/FulltextQueryFunction.java
@@ -0,0 +1,47 @@
+package org.apache.marmotta.kiwi.sparql.function;
+
+import org.apache.marmotta.kiwi.vocabulary.FN_MARMOTTA;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException;
+import org.openrdf.query.algebra.evaluation.function.Function;
+import org.openrdf.query.algebra.evaluation.function.FunctionRegistry;
+
+/**
+ * A SPARQL function for doing a full-text search on the content of a string using a query language with boolean operators.
+ * The query syntax is the syntax of PostgreSQL (see http://www.postgresql.org/docs/9.1/static/datatype-textsearch.html)
+ * Should be implemented directly in the database, as the in-memory implementation is non-functional.
+ * <p/>
+ * The function can be called either as:
+ * <ul>
+ * <li>fn:fulltext-query(?var, 'query') - using a generic stemmer and dictionary</li>
+ * <li>
+ * fn:fulltext-query(?var, 'query', 'language') - using a language-specific stemmer and dictionary
+ * (currently only supported by PostgreSQL with the language values 'english', 'german', 'french', 'italian', 'spanish'
+ * and some other languages as supported by PostgreSQL).
+ * </li>*
+ * </ul>
+ * Note that for performance reasons it might be preferrable to create a full-text index for your database. Please
+ * consult your database documentation on how to do this.
+ *
+ * @author Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class FulltextQueryFunction implements Function {
+
+ // auto-register for SPARQL environment
+ static {
+ if(!FunctionRegistry.getInstance().has(FN_MARMOTTA.QUERY_FULLTEXT.toString())) {
+ FunctionRegistry.getInstance().add(new FulltextQueryFunction());
+ }
+ }
+
+ @Override
+ public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException {
+ throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database");
+ }
+
+ @Override
+ public String getURI() {
+ return FN_MARMOTTA.QUERY_FULLTEXT.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/FulltextSearchFunction.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/FulltextSearchFunction.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/FulltextSearchFunction.java
new file mode 100644
index 0000000..9ce47e8
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/function/FulltextSearchFunction.java
@@ -0,0 +1,46 @@
+package org.apache.marmotta.kiwi.sparql.function;
+
+import org.apache.marmotta.kiwi.vocabulary.FN_MARMOTTA;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException;
+import org.openrdf.query.algebra.evaluation.function.Function;
+import org.openrdf.query.algebra.evaluation.function.FunctionRegistry;
+
+/**
+ * A SPARQL function for doing a full-text search on the content of a string. Should be implemented directly in
+ * the database, as the in-memory implementation is non-functional.
+ * <p/>
+ * The function can be called either as:
+ * <ul>
+ * <li>fn:fulltext-search(?var, 'query') - using a generic stemmer and dictionary</li>
+ * <li>
+ * fn:fulltext-search(?var, 'query', 'language') - using a language-specific stemmer and dictionary
+ * (currently only supported by PostgreSQL with the language values 'english', 'german', 'french', 'italian', 'spanish'
+ * and some other languages as supported by PostgreSQL).
+ * </li>*
+ * </ul>
+ * Note that for performance reasons it might be preferrable to create a full-text index for your database. Please
+ * consult your database documentation on how to do this.
+ *
+ * @author Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class FulltextSearchFunction implements Function {
+
+ // auto-register for SPARQL environment
+ static {
+ if(!FunctionRegistry.getInstance().has(FN_MARMOTTA.SEARCH_FULLTEXT.toString())) {
+ FunctionRegistry.getInstance().add(new FulltextSearchFunction());
+ }
+ }
+
+ @Override
+ public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException {
+ throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database");
+ }
+
+ @Override
+ public String getURI() {
+ return FN_MARMOTTA.SEARCH_FULLTEXT.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSail.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSail.java b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSail.java
index eb1b810..e8a6cb5 100644
--- a/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSail.java
+++ b/libraries/kiwi/kiwi-sparql/src/main/java/org/apache/marmotta/kiwi/sparql/sail/KiWiSparqlSail.java
@@ -17,14 +17,28 @@
package org.apache.marmotta.kiwi.sparql.sail;
+import org.apache.commons.io.IOUtils;
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.persistence.KiWiConnection;
+import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
+import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
+import org.apache.marmotta.kiwi.persistence.util.ScriptRunner;
import org.apache.marmotta.kiwi.sail.KiWiSailConnection;
import org.apache.marmotta.kiwi.sail.KiWiStore;
import org.apache.marmotta.kiwi.sparql.persistence.KiWiSparqlConnection;
-import org.openrdf.sail.*;
+import org.openrdf.sail.NotifyingSail;
+import org.openrdf.sail.NotifyingSailConnection;
+import org.openrdf.sail.Sail;
+import org.openrdf.sail.SailConnection;
+import org.openrdf.sail.SailException;
import org.openrdf.sail.helpers.NotifyingSailWrapper;
import org.openrdf.sail.helpers.SailConnectionWrapper;
import org.openrdf.sail.helpers.SailWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.io.IOException;
+import java.io.StringReader;
import java.sql.SQLException;
/**
@@ -34,13 +48,21 @@ import java.sql.SQLException;
*/
public class KiWiSparqlSail extends NotifyingSailWrapper {
+ private static Logger log = LoggerFactory.getLogger(KiWiSparqlSail.class);
+
+
private KiWiStore parent;
public KiWiSparqlSail(NotifyingSail baseSail) {
super(baseSail);
this.parent = getRootSail(baseSail);
+ }
+ @Override
+ public void initialize() throws SailException {
+ super.initialize();
+ prepareFulltext(this.parent.getPersistence().getConfiguration());
}
/**
@@ -58,6 +80,61 @@ public class KiWiSparqlSail extends NotifyingSailWrapper {
}
}
+
+ private void prepareFulltext(KiWiConfiguration configuration) {
+ try {
+ if(configuration.isFulltextEnabled()) {
+ KiWiConnection connection = parent.getPersistence().getConnection();
+ try {
+ if(configuration.getDialect() instanceof PostgreSQLDialect) {
+
+ // for postgres, we need to create
+ // - a stored procedure for mapping ISO language codes to PostgreSQL fulltext configuration names
+ // - if languages are not null, for each configured language as well as for the generic configuration
+ // an index over nodes.svalue
+
+ ScriptRunner runner = new ScriptRunner(connection.getJDBCConnection(), false, false);
+ if(connection.getMetadata("fulltext.langlookup") == null) {
+ runner.runScript(new StringReader(IOUtils.toString(PostgreSQLDialect.class.getResourceAsStream("create_fulltext_langlookup.sql")).replaceAll("\\n"," ")));
+ }
+
+ if(configuration.getFulltextLanguages() != null) {
+ String script = IOUtils.toString(PostgreSQLDialect.class.getResourceAsStream("create_fulltext_index.sql")).replaceAll("\\n"," ");
+ for(String lang : configuration.getFulltextLanguages()) {
+ if(connection.getMetadata("fulltext.index."+lang) == null) {
+ String script_lang = script.replaceAll("@LANGUAGE@", lang);
+ runner.runScript(new StringReader(script_lang));
+ }
+ }
+ }
+ } else if(configuration.getDialect() instanceof MySQLDialect) {
+
+ // for MySQL, just create a fulltext index (no language support)
+ if(connection.getMetadata("fulltext.index") == null) {
+ ScriptRunner runner = new ScriptRunner(connection.getJDBCConnection(), false, false);
+ String script = IOUtils.toString(MySQLDialect.class.getResourceAsStream("create_fulltext_index.sql"));
+ runner.runScript(new StringReader(script));
+ }
+ /*
+ } else if(configuration.getDialect() instanceof H2Dialect) {
+
+ // for H2, just create a fulltext index (no language support)
+ if(connection.getMetadata("fulltext.index") == null) {
+ ScriptRunner runner = new ScriptRunner(connection.getJDBCConnection(), false, false);
+ String script = IOUtils.toString(H2Dialect.class.getResourceAsStream("create_fulltext_index.sql"));
+ runner.runScript(new StringReader(script));
+ }
+ */
+ }
+ } finally {
+ connection.close();
+ }
+ }
+ } catch (IOException | SQLException ex) {
+ log.error("error while preparing fulltext support",ex);
+ }
+ }
+
/**
* Get the root connection in a wrapped sail connection stack
* @param connection
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-sparql/src/main/resources/META-INF/services/org.openrdf.query.algebra.evaluation.function.Function
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/resources/META-INF/services/org.openrdf.query.algebra.evaluation.function.Function b/libraries/kiwi/kiwi-sparql/src/main/resources/META-INF/services/org.openrdf.query.algebra.evaluation.function.Function
new file mode 100644
index 0000000..2686bd2
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/main/resources/META-INF/services/org.openrdf.query.algebra.evaluation.function.Function
@@ -0,0 +1,2 @@
+org.apache.marmotta.kiwi.sparql.function.FulltextSearchFunction
+org.apache.marmotta.kiwi.sparql.function.FulltextQueryFunction
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/create_fulltext_index.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/create_fulltext_index.sql b/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/create_fulltext_index.sql
new file mode 100644
index 0000000..82fcfd2
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/create_fulltext_index.sql
@@ -0,0 +1,21 @@
+-- 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.
+
+CALL FT_INIT();
+CALL FT_DROP_INDEX('PUBLIC','nodes');
+CALL FT_CREATE_INDEX('PUBLIC','nodes','svalue');
+
+INSERT INTO metadata(mkey,mvalue) VALUES ('fulltext.index','true');
+
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_fulltext_index.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_fulltext_index.sql b/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_fulltext_index.sql
new file mode 100644
index 0000000..c61ab91
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_fulltext_index.sql
@@ -0,0 +1,20 @@
+-- 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.
+
+DROP INDEX IF EXISTS kiwi_ft_idx;
+CREATE FULLTEXT INDEX kiwi_ft_idx ON nodes(svalue);
+
+INSERT INTO metadata(mkey,mvalue) VALUES ('fulltext.index','true');
+
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_fulltext_index.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_fulltext_index.sql b/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_fulltext_index.sql
new file mode 100644
index 0000000..40cf7fa
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_fulltext_index.sql
@@ -0,0 +1,20 @@
+-- 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.
+
+DROP INDEX IF EXISTS kiwi_ft_idx_@LANGUAGE@;
+CREATE INDEX kiwi_ft_idx_@LANGUAGE@ ON nodes USING gin(to_tsvector(kiwi_ft_lang('@LANGUAGE@'),svalue));
+
+INSERT INTO metadata(mkey,mvalue) VALUES ('fulltext.index.@LANGUAGE@','true');
+
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_fulltext_index_generic.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_fulltext_index_generic.sql b/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_fulltext_index_generic.sql
new file mode 100644
index 0000000..a4edf19
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_fulltext_index_generic.sql
@@ -0,0 +1,20 @@
+-- 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.
+
+DROP INDEX IF EXISTS kiwi_ft_idx_generic;
+CREATE INDEX kiwi_ft_idx_generic ON nodes USING gin(to_tsvector('simple',svalue));
+
+INSERT INTO metadata(mkey,mvalue) VALUES ('fulltext.index.generic,'true');
+
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_fulltext_langlookup.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_fulltext_langlookup.sql b/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_fulltext_langlookup.sql
new file mode 100644
index 0000000..561a1d0
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_fulltext_langlookup.sql
@@ -0,0 +1,42 @@
+-- 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.
+
+CREATE OR REPLACE FUNCTION kiwi_ft_lang(lang_iso TEXT) RETURNS regconfig AS $$
+DECLARE
+ lang2 TEXT;
+BEGIN
+ lang2 := lower(left(lang_iso,2));
+ CASE lang2
+ WHEN 'en' THEN RETURN 'english';
+ WHEN 'de' THEN RETURN 'german';
+ WHEN 'fr' THEN RETURN 'french';
+ WHEN 'it' THEN RETURN 'italian';
+ WHEN 'es' THEN RETURN 'spanish';
+ WHEN 'pt' THEN RETURN 'portuguese';
+ WHEN 'sv' THEN RETURN 'swedish';
+ WHEN 'no' THEN RETURN 'norwegian';
+ WHEN 'dk' THEN RETURN 'danish';
+ WHEN 'nl' THEN RETURN 'dutch';
+ WHEN 'ru' THEN RETURN 'russian';
+ WHEN 'tr' THEN RETURN 'turkish';
+ WHEN 'hu' THEN RETURN 'hungarian';
+ WHEN 'fi' THEN RETURN 'finnish';
+ ELSE RETURN 'simple';
+ END CASE;
+END
+$$ LANGUAGE plpgsql;
+
+INSERT INTO metadata(mkey,mvalue) VALUES ('fulltext.langlookup','true');
+
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-sparql/src/test/java/org/apache/marmotta/kiwi/sparql/test/KiWiSparqlJoinTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/test/java/org/apache/marmotta/kiwi/sparql/test/KiWiSparqlJoinTest.java b/libraries/kiwi/kiwi-sparql/src/test/java/org/apache/marmotta/kiwi/sparql/test/KiWiSparqlJoinTest.java
index fc94ffd..7ffcad1 100644
--- a/libraries/kiwi/kiwi-sparql/src/test/java/org/apache/marmotta/kiwi/sparql/test/KiWiSparqlJoinTest.java
+++ b/libraries/kiwi/kiwi-sparql/src/test/java/org/apache/marmotta/kiwi/sparql/test/KiWiSparqlJoinTest.java
@@ -26,6 +26,8 @@ import org.apache.marmotta.kiwi.config.KiWiConfiguration;
import org.apache.marmotta.kiwi.sail.KiWiStore;
import org.apache.marmotta.kiwi.sparql.sail.KiWiSparqlSail;
import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
+import org.apache.marmotta.kiwi.vocabulary.FN_MARMOTTA;
+import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
@@ -78,6 +80,8 @@ public class KiWiSparqlJoinTest {
public KiWiSparqlJoinTest(KiWiConfiguration dbConfig) {
this.dbConfig = dbConfig;
+ dbConfig.setFulltextEnabled(true);
+ dbConfig.setFulltextLanguages(new String[] {"en"});
}
@@ -263,6 +267,65 @@ public class KiWiSparqlJoinTest {
testQuery("query21.sparql");
}
+ // fulltext search filter
+ @Test
+ public void testQuery22() throws Exception {
+ Assume.assumeTrue(dbConfig.getDialect().isFunctionSupported(FN_MARMOTTA.SEARCH_FULLTEXT));
+ String queryString = IOUtils.toString(this.getClass().getResourceAsStream("query22.sparql"), "UTF-8");
+
+ RepositoryConnection con1 = repository.getConnection();
+ try {
+ con1.begin();
+
+ TupleQuery query1 = con1.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ TupleQueryResult result1 = query1.evaluate();
+
+ con1.commit();
+
+ Assert.assertTrue(result1.hasNext());
+
+ BindingSet next = result1.next();
+
+ Assert.assertEquals("http://localhost:8080/LMF/resource/hans_meier", next.getValue("p1").stringValue());
+
+ } catch(RepositoryException ex) {
+ con1.rollback();
+ } finally {
+ con1.close();
+ }
+
+ }
+
+ // fulltext query filter
+ @Test
+ public void testQuery23() throws Exception {
+ Assume.assumeTrue(dbConfig.getDialect().isFunctionSupported(FN_MARMOTTA.SEARCH_FULLTEXT));
+ String queryString = IOUtils.toString(this.getClass().getResourceAsStream("query23.sparql"), "UTF-8");
+
+ RepositoryConnection con1 = repository.getConnection();
+ try {
+ con1.begin();
+
+ TupleQuery query1 = con1.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ TupleQueryResult result1 = query1.evaluate();
+
+ con1.commit();
+
+ Assert.assertTrue(result1.hasNext());
+
+ while (result1.hasNext()) {
+ BindingSet next = result1.next();
+ Assert.assertThat(next.getValue("p1").stringValue(), Matchers.isOneOf("http://localhost:8080/LMF/resource/hans_meier", "http://localhost:8080/LMF/resource/sepp_huber"));
+ }
+
+ } catch(RepositoryException ex) {
+ con1.rollback();
+ } finally {
+ con1.close();
+ }
+
+ }
+
private void testQuery(String filename) throws Exception {
String queryString = IOUtils.toString(this.getClass().getResourceAsStream(filename), "UTF-8");
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query22.sparql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query22.sparql b/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query22.sparql
new file mode 100644
index 0000000..1ffbf14
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query22.sparql
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+PREFIX foaf: <http://xmlns.com/foaf/0.1/>
+PREFIX dc: <http://purl.org/dc/elements/1.1/>
+PREFIX mm: <http://marmotta.apache.org/vocabulary/sparql-functions#>
+
+SELECT ?p1 ?fn ?age WHERE {
+ ?p1 foaf:name ?fn .
+ ?p1 foaf:age ?age .
+ ?p1 dc:description ?desc .
+ FILTER( mm:fulltext-search(str(?desc), "software", lang(?desc)) )
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query23.sparql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query23.sparql b/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query23.sparql
new file mode 100644
index 0000000..1d8e533
--- /dev/null
+++ b/libraries/kiwi/kiwi-sparql/src/test/resources/org/apache/marmotta/kiwi/sparql/test/query23.sparql
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+PREFIX foaf: <http://xmlns.com/foaf/0.1/>
+PREFIX dc: <http://purl.org/dc/elements/1.1/>
+PREFIX mm: <http://marmotta.apache.org/vocabulary/sparql-functions#>
+
+SELECT ?p1 ?fn ?age WHERE {
+ ?p1 foaf:name ?fn .
+ ?p1 foaf:age ?age .
+ ?p1 dc:description ?desc .
+ FILTER( mm:fulltext-query(str(?desc), "software | climber", lang(?desc)) )
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/config/KiWiConfiguration.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/config/KiWiConfiguration.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/config/KiWiConfiguration.java
index 7b044e6..aaa13a2 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/config/KiWiConfiguration.java
+++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/config/KiWiConfiguration.java
@@ -97,6 +97,9 @@ public class KiWiConfiguration {
*/
private int cursorSize = 1000;
+ private boolean fulltextEnabled = false;
+ private String[] fulltextLanguages;
+
/**
* The method to use for generating row IDs. Starting with Marmotta 3.2, the default is to use the Twitter Snowflake
* algorithm.
@@ -258,4 +261,43 @@ public class KiWiConfiguration {
public void setIdGeneratorType(IDGeneratorType idGeneratorType) {
this.idGeneratorType = idGeneratorType;
}
+
+ /**
+ * Return true in case fulltext support is enabled in this configuration. If this is the case, the SPARQL module
+ * will prepare the database with appropriate fulltext index support. Since this adds additional overhead, it is
+ * not enabled by default.
+ *
+ * @return
+ */
+ public boolean isFulltextEnabled() {
+ return fulltextEnabled;
+ }
+
+ /**
+ * Set to true in case fulltext support is enabled in this configuration. If this is the case, the SPARQL module
+ * will prepare the database with appropriate fulltext index support. Since this adds additional overhead, it is
+ * not enabled by default.
+ */
+ public void setFulltextEnabled(boolean fulltextEnabled) {
+ this.fulltextEnabled = fulltextEnabled;
+ }
+
+ /**
+ * Return the languages (ISO codes) for which to add specific fulltext search support. The SPARQL module will add a
+ * separate fulltext index for each supported language, adding additional overhead. In case you only want generic
+ * fulltext support, use the empty array.
+ */
+ public String[] getFulltextLanguages() {
+ return fulltextLanguages;
+ }
+
+ /**
+ * Set the languages (ISO codes) for which to add specific fulltext search support. The SPARQL module will add a
+ * separate fulltext index for each supported language, adding additional overhead. In case you only want generic
+ * fulltext support, use the empty array.
+ */
+ public void setFulltextLanguages(String[] fulltextLanguages) {
+ this.fulltextLanguages = fulltextLanguages;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java
index c33b157..d0f0172 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java
+++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java
@@ -18,7 +18,15 @@
package org.apache.marmotta.kiwi.persistence;
import com.google.common.base.Preconditions;
-import info.aduna.iteration.*;
+import info.aduna.iteration.CloseableIteration;
+import info.aduna.iteration.ConvertingIteration;
+import info.aduna.iteration.DelayedIteration;
+import info.aduna.iteration.DistinctIteration;
+import info.aduna.iteration.EmptyIteration;
+import info.aduna.iteration.ExceptionConvertingIteration;
+import info.aduna.iteration.Iteration;
+import info.aduna.iteration.IteratorIteration;
+import info.aduna.iteration.UnionIteration;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import org.apache.marmotta.commons.sesame.model.LiteralCommons;
@@ -38,9 +46,14 @@ import org.openrdf.repository.RepositoryResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.sql.*;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Savepoint;
+import java.sql.Timestamp;
+import java.sql.Types;
import java.util.*;
-import java.util.Date;
import java.util.concurrent.locks.ReentrantLock;
/**
@@ -1841,6 +1854,62 @@ public class KiWiConnection {
}
}
+ /**
+ * Return the metadata value with the given key; can be used by KiWi modules to retrieve module-specific metadata.
+ *
+ * @param key
+ * @return
+ * @throws SQLException
+ */
+ public String getMetadata(String key) throws SQLException {
+ requireJDBCConnection();
+
+ PreparedStatement statement = getPreparedStatement("meta.get");
+ statement.setString(1,key);
+ ResultSet result = statement.executeQuery();
+ try {
+ if(result.next()) {
+ return result.getString(1);
+ } else {
+ return null;
+ }
+ } finally {
+ result.close();
+ }
+ }
+
+
+ /**
+ * Update the metadata value for the given key; can be used by KiWi modules to set module-specific metadata.
+ *
+ * @param key
+ * @return
+ * @throws SQLException
+ */
+ public void setMetadata(String key, String value) throws SQLException {
+ requireJDBCConnection();
+
+ PreparedStatement statement = getPreparedStatement("meta.get");
+ ResultSet result = statement.executeQuery();
+ try {
+ if(result.next()) {
+ PreparedStatement update = getPreparedStatement("meta.update");
+ update.clearParameters();
+ update.setString(1, value);
+ update.setString(2, key);
+ update.executeUpdate();
+ } else {
+ PreparedStatement insert = getPreparedStatement("meta.insert");
+ insert.clearParameters();
+ insert.setString(1, key);
+ insert.setString(2, value);
+ insert.executeUpdate();
+ }
+ } finally {
+ result.close();
+ }
+ }
+
/**
* Return the KiWi version of the database this connection is operating on. This query is necessary for
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/mysql/MySQLDialect.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/mysql/MySQLDialect.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/mysql/MySQLDialect.java
index fcd731f..db49b8a 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/mysql/MySQLDialect.java
+++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/mysql/MySQLDialect.java
@@ -21,6 +21,7 @@ import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils;
import org.apache.marmotta.kiwi.exception.DriverNotFoundException;
import org.apache.marmotta.kiwi.persistence.KiWiDialect;
+import org.apache.marmotta.kiwi.vocabulary.FN_MARMOTTA;
import org.openrdf.model.URI;
import org.openrdf.model.vocabulary.FN;
@@ -58,6 +59,8 @@ public class MySQLDialect extends KiWiDialect {
supportedFunctions.add(FN.STRING_LENGTH);
supportedFunctions.add(FN.STARTS_WITH);
supportedFunctions.add(FN.ENDS_WITH);
+ supportedFunctions.add(FN_MARMOTTA.SEARCH_FULLTEXT);
+ supportedFunctions.add(FN_MARMOTTA.QUERY_FULLTEXT);
}
/**
@@ -163,6 +166,21 @@ public class MySQLDialect extends KiWiDialect {
} else if(FN.ENDS_WITH.equals(fnUri)) {
Preconditions.checkArgument(args.length == 2);
return String.format("(POSITION(reverse(%2$s) IN reverse(%1$s)) = 1)", args[0], args[1]);
+ } else if(FN_MARMOTTA.SEARCH_FULLTEXT.equals(fnUri)) {
+ Preconditions.checkArgument(args.length == 2 || args.length == 3); // no specific language support in MySQL
+ return String.format("(MATCH (%1$s) AGAINST (%2$s))", args[0], args[1]);
+ } else if(FN_MARMOTTA.QUERY_FULLTEXT.equals(fnUri)) {
+ Preconditions.checkArgument(args.length == 2 || args.length == 3); // no specific language support in MySQL
+
+ // basic transformation from postgres to mysql syntax, assuming the argument is a constant query
+ String query;
+ if(args[1].startsWith("'")) {
+ query = args[1].replaceAll("&","+").replaceAll("\\|", " ").replaceAll("!"," -");
+ } else {
+ query = args[1];
+ }
+
+ return String.format("(MATCH (%1$s) AGAINST (%2$s IN BOOLEAN MODE))", args[0], query);
}
throw new UnsupportedOperationException("operation "+fnUri+" not supported");
}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/pgsql/PostgreSQLDialect.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/pgsql/PostgreSQLDialect.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/pgsql/PostgreSQLDialect.java
index c0f681a..8e780f0 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/pgsql/PostgreSQLDialect.java
+++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/pgsql/PostgreSQLDialect.java
@@ -21,6 +21,7 @@ import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils;
import org.apache.marmotta.kiwi.exception.DriverNotFoundException;
import org.apache.marmotta.kiwi.persistence.KiWiDialect;
+import org.apache.marmotta.kiwi.vocabulary.FN_MARMOTTA;
import org.openrdf.model.URI;
import org.openrdf.model.vocabulary.FN;
@@ -49,6 +50,8 @@ public class PostgreSQLDialect extends KiWiDialect {
supportedFunctions.add(FN.STRING_LENGTH);
supportedFunctions.add(FN.STARTS_WITH);
supportedFunctions.add(FN.ENDS_WITH);
+ supportedFunctions.add(FN_MARMOTTA.SEARCH_FULLTEXT);
+ supportedFunctions.add(FN_MARMOTTA.QUERY_FULLTEXT);
}
/**
@@ -183,6 +186,22 @@ public class PostgreSQLDialect extends KiWiDialect {
} else if(FN.ENDS_WITH.equals(fnUri)) {
Preconditions.checkArgument(args.length == 2);
return String.format("(POSITION(reverse(%2$s) IN reverse(%1$s)) = 1)", args[0], args[1]);
+ } else if(FN_MARMOTTA.SEARCH_FULLTEXT.equals(fnUri)) {
+ if(args.length == 2) {
+ return String.format("(to_tsvector('simple' :: regconfig,%1$s) @@ plainto_tsquery('simple' :: regconfig,%2$s))", args[0], args[1]);
+ } else if(args.length == 3) {
+ return String.format("(to_tsvector(kiwi_ft_lang(%3$s) :: regconfig, %1$s) @@ plainto_tsquery(kiwi_ft_lang(%3$s) :: regconfig, %2$s))", args[0], args[1], args[2]);
+ } else {
+ throw new IllegalArgumentException("invalid number of arguments");
+ }
+ } else if(FN_MARMOTTA.QUERY_FULLTEXT.equals(fnUri)) {
+ if(args.length == 2) {
+ return String.format("(to_tsvector('simple' :: regconfig,%1$s) @@ to_tsquery('simple' :: regconfig,%2$s))", args[0], args[1]);
+ } else if(args.length == 3) {
+ return String.format("(to_tsvector(kiwi_ft_lang(%3$s) :: regconfig, %1$s) @@ to_tsquery(kiwi_ft_lang(%3$s) :: regconfig, %2$s))", args[0], args[1], args[2]);
+ } else {
+ throw new IllegalArgumentException("invalid number of arguments");
+ }
}
throw new UnsupportedOperationException("operation "+fnUri+" not supported");
}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/vocabulary/FN_MARMOTTA.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/vocabulary/FN_MARMOTTA.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/vocabulary/FN_MARMOTTA.java
new file mode 100644
index 0000000..c788bb0
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/vocabulary/FN_MARMOTTA.java
@@ -0,0 +1,41 @@
+package org.apache.marmotta.kiwi.vocabulary;
+
+import org.openrdf.model.Namespace;
+import org.openrdf.model.URI;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.NamespaceImpl;
+import org.openrdf.model.impl.ValueFactoryImpl;
+
+/**
+ * Add file description here!
+ *
+ * @author Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class FN_MARMOTTA {
+
+ public static final String NAMESPACE = "http://marmotta.apache.org/vocabulary/sparql-functions#";
+
+ /**
+ * Recommended prefix for the XPath Functions namespace: "fn"
+ */
+ public static final String PREFIX = "mm";
+
+ /**
+ * An immutable {@link org.openrdf.model.Namespace} constant that represents the XPath
+ * Functions namespace.
+ */
+ public static final Namespace NS = new NamespaceImpl(PREFIX, NAMESPACE);
+
+
+
+ public static final URI SEARCH_FULLTEXT;
+
+ public static final URI QUERY_FULLTEXT;
+
+ static {
+ ValueFactory f = new ValueFactoryImpl();
+
+ SEARCH_FULLTEXT = f.createURI(NAMESPACE,"fulltext-search");
+ QUERY_FULLTEXT = f.createURI(NAMESPACE,"fulltext-query");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties
index cdebd9e..4977ba6 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties
+++ b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties
@@ -19,6 +19,9 @@
# get metainformation
meta.tables = SHOW TABLES;
meta.version = SELECT mvalue FROM metadata WHERE mkey = 'version';
+meta.insert = INSERT INTO metadata(mkey,mvalue) VALUES(?,?);
+meta.update = UPDATE metadata SET mvalue = ? WHERE mkey = ?;
+meta.get = SELECT mvalue FROM metadata WHERE mkey = ?;
# get sequence numbers
seq.nodes = SELECT nextval('seq_nodes')
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_base_tables.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_base_tables.sql b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_base_tables.sql
index 67425ac..b4f3611 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_base_tables.sql
+++ b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/create_base_tables.sql
@@ -38,7 +38,7 @@ CREATE TABLE nodes (
lang varchar(5),
createdAt timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(id)
-) CHARACTER SET utf8 COLLATE utf8_bin ENGINE=InnoDB;
+) CHARACTER SET utf8 COLLATE utf8_bin ENGINE=MyISAM;
CREATE TABLE triples (
id bigint NOT NULL,
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties
index a94272a..277311b 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties
+++ b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties
@@ -19,6 +19,9 @@
# get metainformation
meta.tables = SHOW TABLES;
meta.version = SELECT mvalue FROM metadata WHERE mkey = 'version';
+meta.insert = INSERT INTO metadata(mkey,mvalue) VALUES(?,?);
+meta.update = UPDATE metadata SET mvalue = ? WHERE mkey = ?;
+meta.get = SELECT mvalue FROM metadata WHERE mkey = ?;
# get sequence numbers
seq.nodes.prep = UPDATE seq_nodes SET id=LAST_INSERT_ID(id+1);
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c0e5d9da/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties
index 2ae6fa6..1007c03 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties
+++ b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties
@@ -18,6 +18,9 @@
# get metainformation
meta.tables = select tablename from pg_tables where schemaname='public';
+meta.insert = INSERT INTO metadata(mkey,mvalue) VALUES(?,?);
+meta.update = UPDATE metadata SET mvalue = ? WHERE mkey = ?;
+meta.get = SELECT mvalue FROM metadata WHERE mkey = ?;
meta.version = SELECT mvalue FROM metadata WHERE mkey = 'version';
# get sequence numbers