You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by wi...@apache.org on 2014/06/13 10:57:36 UTC

[016/100] [abbrv] [partial] Reverting the erroneous merge by Sebastian according to the instructions in INFRA-6876

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/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 2fc9afc..092cfcb 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
@@ -36,10 +36,10 @@ load.literal_by_v     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,
 load.literal_by_vl    = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE svalue = ? AND lang = ?
 load.literal_by_vt    = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE svalue = ? AND ltype = ?
 
-load.literal_by_iv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE ivalue = ? AND lang IS NULL AND ltype = ?
-load.literal_by_dv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE dvalue = ? AND lang IS NULL AND ltype = ?
-load.literal_by_tv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE tvalue = ? AND lang IS NULL AND ltype = ?
-load.literal_by_bv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE bvalue = ? AND lang IS NULL AND ltype = ?
+load.literal_by_iv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,ltype,createdAt FROM nodes WHERE ivalue = ? AND lang IS NULL AND ltype = ?
+load.literal_by_dv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,ltype,createdAt FROM nodes WHERE dvalue = ? AND lang IS NULL AND ltype = ?
+load.literal_by_tv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,ltype,createdAt FROM nodes WHERE tvalue = ? AND lang IS NULL AND ltype = ?
+load.literal_by_bv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,ltype,createdAt FROM nodes WHERE bvalue = ? AND lang IS NULL AND ltype = ?
 
 
 load.namespace_prefix  = SELECT id,prefix,uri,createdAt FROM namespaces WHERE prefix = ?;
@@ -60,16 +60,22 @@ store.tliteral       = INSERT INTO nodes (id,ntype,svalue,tvalue,ltype,createdAt
 
 store.namespace      = INSERT INTO namespaces (id,prefix,uri,createdAt) VALUES (?,?,?,?)
 
-store.triple         = INSERT INTO triples (id,subject,predicate,object,context,inferred,createdAt) VALUES (?,?,?,?,?,?,?)
+#store.triple         = INSERT INTO triples (id,subject,predicate,object,context,inferred,createdAt) VALUES (?,?,?,?,?,?,?)
+store.triple         = MERGE INTO triples (id,subject,predicate,object,context,inferred,createdAt) KEY(id) VALUES (?,?,?,?,?,?,?)
+load.triple          = SELECT id FROM triples WHERE subject = ? AND predicate = ? AND object = ? AND context = ? AND deleted = false AND inferred = true
 
 
-query.size           = SELECT count(*) FROM triples WHERE deleted = false
-query.size_ctx       = SELECT count(*) FROM triples WHERE context = ? AND deleted = false
+query.size           = SELECT count(*) FROM triples WHERE deleted = false AND inferred = false
+query.size_ctx       = SELECT count(*) FROM triples WHERE context = ? AND deleted = false AND inferred = false
 query.contexts       = SELECT DISTINCT context FROM triples WHERE deleted = false
 query.namespaces     = SELECT id,prefix,uri,createdAt FROM namespaces
-
+query.resources        = SELECT id,ntype,svalue,createdAt FROM nodes WHERE ntype = 'uri' OR ntype = 'bnode'
+query.resources_prefix = SELECT id,ntype,svalue,createdAt FROM nodes WHERE ntype = 'uri' AND svalue LIKE ?
 
 # delete entities
 delete.triple        = UPDATE triples SET deleted = true, deletedAt = now() WHERE id = ?
 undelete.triple      = UPDATE triples SET deleted = false, deletedAt = NULL WHERE id = ?
 delete.namespace     = DELETE FROM namespaces WHERE id = ?
+
+gc.check_consistency = SELECT svalue, ntype, count(id), max(id) FROM nodes group by svalue, ntype having count(id) > 1
+gc.list_node_ids     = SELECT id FROM nodes WHERE svalue = ? AND ntype = ? AND id != ?

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/upgrade_base_001_002.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/upgrade_base_001_002.sql b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/upgrade_base_001_002.sql
new file mode 100644
index 0000000..3143ac3
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/upgrade_base_001_002.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.
+
+UPDATE METADATA SET mvalue = '2' WHERE mkey = 'version';
+
+-- drop not null on triples.context
+ALTER TABLE triples ALTER COLUMN context bigint;
+ALTER TABLE nodes ALTER COLUMN svalue varchar(2147483647) NOT NULL;

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/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 9cc39d3..67425ac 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
@@ -12,13 +12,13 @@
 -- 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 TABLE seq_nodes (id BIGINT NOT NULL);
+CREATE TABLE seq_nodes (id BIGINT NOT NULL) ENGINE=InnoDB;
 INSERT INTO seq_nodes(id) VALUES (0);
 
-CREATE TABLE seq_triples (id BIGINT NOT NULL);
+CREATE TABLE seq_triples (id BIGINT NOT NULL) ENGINE=InnoDB;
 INSERT INTO seq_triples VALUES (0);
 
-CREATE TABLE seq_namespaces (id BIGINT NOT NULL);
+CREATE TABLE seq_namespaces (id BIGINT NOT NULL) ENGINE=InnoDB;
 INSERT INTO seq_namespaces(id) VALUES (0);
 
 -- Sequences in MySQL:
@@ -29,7 +29,7 @@ INSERT INTO seq_namespaces(id) VALUES (0);
 CREATE TABLE nodes (
   id        bigint     NOT NULL,
   ntype     char(8)    NOT NULL,
-  svalue    text       NOT NULL,
+  svalue    longtext   NOT NULL,
   dvalue    double precision,
   ivalue    bigint,
   tvalue    datetime   DEFAULT NULL,
@@ -38,21 +38,21 @@ CREATE TABLE nodes (
   lang      varchar(5),
   createdAt timestamp  NOT NULL DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY(id)
-) CHARACTER SET utf8 COLLATE utf8_bin;
+) CHARACTER SET utf8 COLLATE utf8_bin  ENGINE=InnoDB;
 
 CREATE TABLE triples (
   id        bigint     NOT NULL,
   subject   bigint     NOT NULL REFERENCES nodes(id),
   predicate bigint     NOT NULL REFERENCES nodes(id),
   object    bigint     NOT NULL REFERENCES nodes(id),
-  context   bigint     NOT NULL REFERENCES nodes(id),
+  context   bigint     REFERENCES nodes(id),
   creator   bigint     REFERENCES nodes(id),
   inferred  boolean    DEFAULT false,
   deleted   boolean    DEFAULT false,
   createdAt timestamp  NOT NULL DEFAULT now(),
   deletedAt timestamp,
   PRIMARY KEY(id)
-) CHARACTER SET utf8 COLLATE utf8_bin;
+) CHARACTER SET utf8 COLLATE utf8_bin  ENGINE=InnoDB;
 
 CREATE TABLE namespaces (
   id        bigint        NOT NULL,
@@ -60,7 +60,7 @@ CREATE TABLE namespaces (
   uri       varchar(2048) NOT NULL,
   createdAt timestamp     NOT NULL DEFAULT now(),
   PRIMARY KEY(id)
-) CHARACTER SET utf8 COLLATE utf8_bin;
+) CHARACTER SET utf8 COLLATE utf8_bin  ENGINE=InnoDB;
 
 
 -- A table for storing metadata about the current database, e.g. version numbers for each table
@@ -69,24 +69,19 @@ CREATE TABLE metadata (
   mkey      varchar(16)   NOT NULL,
   mvalue    varchar(256)  NOT NULL,
   PRIMARY KEY(id)
-) CHARACTER SET utf8 COLLATE utf8_bin;
+) CHARACTER SET utf8 COLLATE utf8_bin  ENGINE=InnoDB;
 
 -- Indexes for accessing nodes and triples efficiently
 CREATE INDEX idx_node_content ON nodes(svalue(256));
 CREATE INDEX idx_literal_lang ON nodes(lang);
 
-CREATE INDEX idx_triples_s ON triples(subject);
-CREATE INDEX idx_triples_o ON triples(object);
-CREATE INDEX idx_triples_sp ON triples(subject,predicate);
-CREATE INDEX idx_triples_po ON triples(predicate,object);
+CREATE INDEX idx_triples_op ON triples(object,predicate);
 CREATE INDEX idx_triples_spo ON triples(subject,predicate,object);
-CREATE INDEX idx_triples_cs ON triples(context,subject);
-CREATE INDEX idx_triples_csp ON triples(context,subject,predicate);
 CREATE INDEX idx_triples_cspo ON triples(context,subject,predicate,object);
 
 CREATE INDEX idx_namespaces_uri ON namespaces(uri);
 CREATE INDEX idx_namespaces_prefix ON namespaces(prefix);
 
 -- insert initial metadata
-INSERT INTO metadata(mkey,mvalue) VALUES ('version','1');
+INSERT INTO metadata(mkey,mvalue) VALUES ('version','2');
 INSERT INTO metadata(mkey,mvalue) VALUES ('created',DATE_FORMAT(now(),'%Y-%m-%d %H:%i:%s') );

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/drop_base_tables.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/drop_base_tables.sql b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/drop_base_tables.sql
index fb16fcd..5a91f23 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/drop_base_tables.sql
+++ b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/drop_base_tables.sql
@@ -16,13 +16,8 @@
 DROP INDEX idx_node_content ON nodes;
 DROP INDEX idx_literal_lang ON nodes;
 
-DROP INDEX idx_triples_s ON triples;
-DROP INDEX idx_triples_o ON triples;
-DROP INDEX idx_triples_sp ON triples;
-DROP INDEX idx_triples_po ON triples;
+DROP INDEX idx_triples_op ON triples;
 DROP INDEX idx_triples_spo ON triples;
-DROP INDEX idx_triples_cs ON triples;
-DROP INDEX idx_triples_csp ON triples;
 DROP INDEX idx_triples_cspo ON triples;
 
 DROP INDEX idx_namespaces_uri ON namespaces;

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/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 fae51bc..a94272a 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
@@ -23,12 +23,15 @@ meta.version           = SELECT mvalue FROM metadata WHERE mkey = 'version';
 # get sequence numbers
 seq.nodes.prep         = UPDATE seq_nodes SET id=LAST_INSERT_ID(id+1);
 seq.nodes              = SELECT LAST_INSERT_ID();
+seq.nodes.set          = UPDATE seq_nodes SET id=?;
 
 seq.triples.prep       = UPDATE seq_triples SET id=LAST_INSERT_ID(id+1);
 seq.triples            = SELECT LAST_INSERT_ID();
+seq.triples.set        = UPDATE seq_triples SET id=?;
 
 seq.namespaces.prep    = UPDATE seq_namespaces SET id=LAST_INSERT_ID(id+1);
 seq.namespaces         = SELECT LAST_INSERT_ID();
+seq.namespaces.set     = UPDATE seq_namespaces SET id=?;
 
 # load entities
 load.node_by_id        = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE id = ?
@@ -41,10 +44,10 @@ load.literal_by_v     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,
 load.literal_by_vl    = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE svalue = ? AND lang = ?
 load.literal_by_vt    = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE svalue = ? AND ltype = ?
 
-load.literal_by_iv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE ivalue = ? AND lang IS NULL AND ltype = ?
-load.literal_by_dv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE dvalue = ? AND lang IS NULL AND ltype = ?
-load.literal_by_tv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE tvalue = ? AND lang IS NULL AND ltype = ?
-load.literal_by_bv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE bvalue = ? AND lang IS NULL AND ltype = ?
+load.literal_by_iv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,ltype,createdAt FROM nodes WHERE ivalue = ? AND lang IS NULL AND ltype = ?
+load.literal_by_dv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,ltype,createdAt FROM nodes WHERE dvalue = ? AND lang IS NULL AND ltype = ?
+load.literal_by_tv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,ltype,createdAt FROM nodes WHERE tvalue = ? AND lang IS NULL AND ltype = ?
+load.literal_by_bv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,ltype,createdAt FROM nodes WHERE bvalue = ? AND lang IS NULL AND ltype = ?
 
 
 load.namespace_prefix  = SELECT id,prefix,uri,createdAt FROM namespaces WHERE prefix = ?;
@@ -65,15 +68,21 @@ store.tliteral       = INSERT INTO nodes (id,ntype,svalue,tvalue,ltype,createdAt
 
 store.namespace      = INSERT INTO namespaces (id,prefix,uri,createdAt) VALUES (?,?,?,?)
 
-store.triple         = INSERT INTO triples (id,subject,predicate,object,context,inferred,createdAt) VALUES (?,?,?,?,?,?,?)
+store.triple         = INSERT IGNORE INTO triples (id,subject,predicate,object,context,inferred,createdAt) VALUES (?,?,?,?,?,?,?)
+load.triple          = SELECT id FROM triples WHERE subject = ? AND predicate = ? AND object = ? AND context = ? AND deleted = false AND inferred = true
 
 
-query.size           = SELECT count(*) FROM triples WHERE deleted = false
-query.size_ctx       = SELECT count(*) FROM triples WHERE context = ? AND deleted = false
+query.size           = SELECT count(*) FROM triples WHERE deleted = false AND inferred = false
+query.size_ctx       = SELECT count(*) FROM triples WHERE context = ? AND deleted = false AND inferred = false
 query.contexts       = SELECT DISTINCT context FROM triples WHERE deleted = false
 query.namespaces     = SELECT id,prefix,uri,createdAt FROM namespaces
+query.resources      = SELECT id,ntype,svalue,createdAt FROM nodes WHERE ntype = 'uri' OR ntype = 'bnode'
+query.resources_prefix = SELECT id,ntype,svalue,createdAt FROM nodes WHERE ntype = 'uri' AND svalue LIKE ?
 
 # delete entities
 delete.triple        = UPDATE triples SET deleted = true, deletedAt = now() WHERE id = ?
 undelete.triple      = UPDATE triples SET deleted = false, deletedAt = NULL WHERE id = ?
 delete.namespace     = DELETE FROM namespaces WHERE id = ?
+
+gc.check_consistency = SELECT svalue, ntype, count(id), max(id) FROM nodes group by svalue, ntype having count(id) > 1
+gc.list_node_ids     = SELECT id FROM nodes WHERE svalue = ? AND ntype = ? AND id != ?

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/upgrade_base_001_002.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/upgrade_base_001_002.sql b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/upgrade_base_001_002.sql
new file mode 100644
index 0000000..1dc5df4
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/upgrade_base_001_002.sql
@@ -0,0 +1,24 @@
+-- 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.
+
+UPDATE metadata SET mvalue = '2' WHERE mkey = 'version';
+
+-- update nodes.svalue to longtext
+ALTER TABLE nodes MODIFY svalue LONGTEXT NOT NULL;
+
+ALTER TABLE nodes ADD CONSTRAINT nodes_unique UNIQUE (ntype,svalue);
+
+-- drop not null on triples.context
+ALTER TABLE triples MODIFY context bigint     REFERENCES nodes(id);

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
index d60fdc7..a57a297 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
+++ b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/create_base_tables.sql
@@ -37,7 +37,7 @@ CREATE TABLE triples (
   subject   bigint     NOT NULL REFERENCES nodes(id),
   predicate bigint     NOT NULL REFERENCES nodes(id),
   object    bigint     NOT NULL REFERENCES nodes(id),
-  context   bigint     NOT NULL REFERENCES nodes(id),
+  context   bigint     REFERENCES nodes(id),
   creator   bigint     REFERENCES nodes(id),
   inferred  boolean    DEFAULT false,
   deleted   boolean    DEFAULT false,
@@ -67,21 +67,27 @@ CREATE TABLE metadata (
 CREATE INDEX idx_node_content ON nodes USING hash(svalue);
 CREATE INDEX idx_literal_lang ON nodes(lang) WHERE ntype = 'string';
 
-CREATE INDEX idx_triples_s ON triples(subject) WHERE deleted = false;
-CREATE INDEX idx_triples_o ON triples(object) WHERE deleted = false;
-CREATE INDEX idx_triples_sp ON triples(subject,predicate) WHERE deleted = false;
-CREATE INDEX idx_triples_po ON triples(predicate,object) WHERE deleted = false;
+CREATE INDEX idx_triples_op ON triples(object,predicate) WHERE deleted = false;
 CREATE INDEX idx_triples_spo ON triples(subject,predicate,object) WHERE deleted = false;
-CREATE INDEX idx_triples_cs ON triples(context,subject) WHERE deleted = false;
-CREATE INDEX idx_triples_csp ON triples(context,subject,predicate) WHERE deleted = false;
 CREATE INDEX idx_triples_cspo ON triples(context,subject,predicate,object) WHERE deleted = false;
 
+
 CREATE INDEX idx_namespaces_uri ON namespaces(uri);
 CREATE INDEX idx_namespaces_prefix ON namespaces(prefix);
 
 
+-- a rule to ignore duplicate inserts into triple table
+CREATE OR REPLACE RULE "triples_ignore_duplicates" AS
+ON INSERT TO triples
+  WHERE EXISTS(
+      SELECT 1 FROM triples
+      WHERE id = NEW.id
+  )
+DO INSTEAD NOTHING;
+
+
 -- a function for cleaning up table rows without incoming references
 
 -- insert initial metadata
-INSERT INTO metadata(mkey,mvalue) VALUES ('version','1');
+INSERT INTO metadata(mkey,mvalue) VALUES ('version','2');
 INSERT INTO metadata(mkey,mvalue) VALUES ('created',to_char(now(),'yyyy-MM-DD HH:mm:ss TZ') );
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/drop_base_tables.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/drop_base_tables.sql b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/drop_base_tables.sql
index e3199b8..5a34920 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/drop_base_tables.sql
+++ b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/drop_base_tables.sql
@@ -15,13 +15,8 @@
 DROP INDEX idx_node_content;
 DROP INDEX idx_literal_lang;
 
-DROP INDEX idx_triples_s;
-DROP INDEX idx_triples_o;
-DROP INDEX idx_triples_sp;
-DROP INDEX idx_triples_po;
+DROP INDEX idx_triples_op;
 DROP INDEX idx_triples_spo;
-DROP INDEX idx_triples_cs;
-DROP INDEX idx_triples_csp;
 DROP INDEX idx_triples_cspo;
 
 DROP INDEX idx_namespaces_uri;

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/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 2b2f0c6..2ae6fa6 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
@@ -22,8 +22,11 @@ meta.version           = SELECT mvalue FROM metadata WHERE mkey = 'version';
 
 # get sequence numbers
 seq.nodes              = SELECT nextval('seq_nodes')
+seq.nodes.set          = SELECT setval('seq_nodes',?)
 seq.triples            = SELECT nextval('seq_triples')
+seq.triples.set        = SELECT setval('seq_triples',?)
 seq.namespaces         = SELECT nextval('seq_namespaces')
+seq.namespaces.set     = SELECT setval('seq_namespaces',?)
 
 # load entities
 load.node_by_id        = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE id = ?
@@ -36,10 +39,10 @@ load.literal_by_v     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,
 load.literal_by_vl    = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE svalue = ? AND lang = ?
 load.literal_by_vt    = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE svalue = ? AND ltype = ?
 
-load.literal_by_iv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE ivalue = ? AND lang IS NULL AND ltype = ?
-load.literal_by_dv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE dvalue = ? AND lang IS NULL AND ltype = ?
-load.literal_by_tv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE tvalue = ? AND lang IS NULL AND ltype = ?
-load.literal_by_bv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,lang,ltype,createdAt FROM nodes WHERE bvalue = ? AND lang IS NULL AND ltype = ?
+load.literal_by_iv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,ltype,createdAt FROM nodes WHERE ivalue = ? AND lang IS NULL AND ltype = ?
+load.literal_by_dv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,ltype,createdAt FROM nodes WHERE dvalue = ? AND lang IS NULL AND ltype = ?
+load.literal_by_tv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,ltype,createdAt FROM nodes WHERE tvalue = ? AND lang IS NULL AND ltype = ?
+load.literal_by_bv     = SELECT id,ntype,svalue,ivalue,dvalue,tvalue,bvalue,ltype,createdAt FROM nodes WHERE bvalue = ? AND lang IS NULL AND ltype = ?
 
 load.namespace_prefix  = SELECT id,prefix,uri,createdAt FROM namespaces WHERE prefix = ?;
 load.namespace_uri     = SELECT id,prefix,uri,createdAt FROM namespaces WHERE uri = ?;
@@ -59,13 +62,19 @@ store.tliteral       = INSERT INTO nodes (id,ntype,svalue,tvalue,ltype,createdAt
 store.namespace      = INSERT INTO namespaces (id,prefix,uri,createdAt) VALUES (?,?,?,?)
 
 store.triple         = INSERT INTO triples (id,subject,predicate,object,context,inferred,createdAt) VALUES (?,?,?,?,?,?,?)
+load.triple          = SELECT id FROM triples WHERE subject = ? AND predicate = ? AND object = ? AND context = ? AND deleted = false
 
-query.size           = SELECT count(*) FROM triples WHERE deleted = false
-query.size_ctx       = SELECT count(*) FROM triples WHERE context = ? AND deleted = false
+query.size           = SELECT count(*) FROM triples WHERE deleted = false AND inferred = false
+query.size_ctx       = SELECT count(*) FROM triples WHERE context = ? AND deleted = false AND inferred = false
 query.contexts       = SELECT DISTINCT context FROM triples WHERE deleted = false
 query.namespaces     = SELECT id,prefix,uri,createdAt FROM namespaces
+query.resources      = SELECT id,ntype,svalue,createdAt FROM nodes WHERE ntype = 'uri' OR ntype = 'bnode'
+query.resources_prefix = SELECT id,ntype,svalue,createdAt FROM nodes WHERE ntype = 'uri' AND svalue LIKE ?
 
 # delete entities
 delete.triple        = UPDATE triples SET deleted = true, deletedAt = now() WHERE id = ?
 undelete.triple      = UPDATE triples SET deleted = false, deletedAt = NULL WHERE id = ?
 delete.namespace     = DELETE FROM namespaces WHERE id = ?
+
+gc.check_consistency = SELECT svalue, ntype, count(id), max(id) FROM nodes group by svalue, ntype having count(id) > 1
+gc.list_node_ids     = SELECT id FROM nodes WHERE svalue = ? AND ntype = CAST(? AS nodetype) AND id != ?

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/upgrade_base_001_002.sql
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/upgrade_base_001_002.sql b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/upgrade_base_001_002.sql
new file mode 100644
index 0000000..eb794e8
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/upgrade_base_001_002.sql
@@ -0,0 +1,19 @@
+-- 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.
+
+UPDATE METADATA SET mvalue = '2' WHERE mkey = 'version';
+
+-- drop not null on triples.context
+ALTER TABLE triples ALTER COLUMN context DROP NOT NULL;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/ConcurrencyTestBase.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/ConcurrencyTestBase.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/ConcurrencyTestBase.java
new file mode 100644
index 0000000..517efe9
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/ConcurrencyTestBase.java
@@ -0,0 +1,189 @@
+/*
+ * 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.kiwi.test;
+
+import com.google.code.tempusfugit.concurrency.ConcurrentRule;
+import com.google.code.tempusfugit.concurrency.RepeatingRule;
+import com.google.code.tempusfugit.concurrency.annotations.Concurrent;
+import com.google.code.tempusfugit.concurrency.annotations.Repeating;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.repository.Repository;
+import org.openrdf.repository.RepositoryConnection;
+import org.slf4j.Logger;
+
+import java.util.*;
+
+/**
+ * Add file description here!
+ *
+ * @author Sebastian Schaffert (sschaffert@apache.org)
+ */
+public abstract class ConcurrencyTestBase {
+
+    protected static Repository repository;
+
+    protected static Random rnd;
+
+    private static long runs = 0;
+
+    protected static Logger logger;
+
+    private List<URI> resources = new ArrayList<>();
+
+    private List<Value> objects = new ArrayList<>();
+
+    private Set<Statement> allAddedTriples = new HashSet<>();
+
+    @Rule
+    public ConcurrentRule concurrently = new ConcurrentRule();
+
+    @Rule
+    public RepeatingRule repeatedly = new RepeatingRule();
+
+    @Rule
+    public TestWatcher watchman = new TestWatcher() {
+        /**
+         * Invoked when a test is about to start
+         */
+        @Override
+        protected void starting(Description description) {
+            logger.info("{} being run...", description.getMethodName());
+        }
+
+        /**
+         * Invoked when a test method finishes (whether passing or failing)
+         */
+        @Override
+        protected void finished(Description description) {
+            logger.info("{}: {} added triples, {} removed triples, {} resources reused, {} objects reused", description.getMethodName(), tripleAddCount, tripleRemoveCount, resourcesReused, objectsReused);
+        }
+    };
+
+    long tripleAddCount = 0;
+    long tripleRemoveCount = 0;
+
+    long resourcesReused = 0;
+    long objectsReused = 0;
+
+    @Test
+    @Concurrent(count = 10)
+    @Repeating(repetition = 10)
+    public void testConcurrency() throws Exception {
+        long run = runs++;
+        long removed = 0;
+
+        Set<Statement> addedTriples = new HashSet<>();
+
+        // generate random nodes and triples and add them
+        RepositoryConnection con = repository.getConnection();
+        try {
+            for(int i=0; i< rnd.nextInt(1000); i++) {
+                // there is a random chance of deleting a previously added triple, either from this session or from
+                // a previous session
+                if(allAddedTriples.size() + addedTriples.size() > 0 && rnd.nextInt(10) == 0) {
+                    List<Statement> statements = new ArrayList<>();
+                    synchronized (allAddedTriples) {
+                        statements.addAll(allAddedTriples);
+                    }
+                    statements.addAll(addedTriples);
+
+                    con.remove(statements.get(rnd.nextInt(statements.size())));
+
+                    removed ++;
+                    tripleRemoveCount++;
+                } else {
+                    URI subject = randomURI();
+                    URI predicate = randomURI();
+                    Value object = randomObject();
+                    Statement stmt = con.getValueFactory().createStatement(subject,predicate,object);
+                    con.add(stmt);
+                    addedTriples.add(stmt);
+                    tripleAddCount++;
+                }
+            }
+            con.commit();
+
+            // commit also all added triples
+            synchronized (allAddedTriples) {
+                allAddedTriples.addAll(addedTriples);
+            }
+        } finally {
+            con.close();
+        }
+
+
+        logger.info("run {}: triples added: {}; triples removed: {}", run, addedTriples.size(), removed);
+    }
+
+
+    /**
+     * Return a random URI, with a 10% chance of returning a URI that has already been used.
+     * @return
+     */
+    protected URI randomURI() {
+        if(resources.size() > 0 && rnd.nextInt(10) == 0) {
+            resourcesReused++;
+            // return a resource that was already used
+            return resources.get(rnd.nextInt(resources.size()));
+        } else {
+            URI resource = repository.getValueFactory().createURI("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+            resources.add(resource);
+            return resource;
+        }
+    }
+
+    /**
+     * Return a random RDF value, either a reused object (10% chance) or of any other kind.
+     * @return
+     */
+    protected Value randomObject() {
+        if(objects.size() > 0 && rnd.nextInt(10) == 0) {
+            objectsReused++;
+            return objects.get(rnd.nextInt(objects.size()));
+        } else {
+            Value object;
+            switch(rnd.nextInt(6)) {
+                case 0: object = repository.getValueFactory().createURI("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+                    break;
+                case 1: object = repository.getValueFactory().createBNode();
+                    break;
+                case 2: object = repository.getValueFactory().createLiteral(RandomStringUtils.randomAscii(40));
+                    break;
+                case 3: object = repository.getValueFactory().createLiteral(rnd.nextInt());
+                    break;
+                case 4: object = repository.getValueFactory().createLiteral(rnd.nextDouble());
+                    break;
+                case 5: object = repository.getValueFactory().createLiteral(rnd.nextBoolean());
+                    break;
+                default: object = repository.getValueFactory().createURI("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+                    break;
+
+            }
+            objects.add(object);
+            return object;
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/DialectTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/DialectTest.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/DialectTest.java
index a7af15b..ed47cee 100644
--- a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/DialectTest.java
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/DialectTest.java
@@ -1,13 +1,12 @@
-/**
- * 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
+/*
+ * 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
+ *      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,
@@ -17,66 +16,32 @@
  */
 package org.apache.marmotta.kiwi.test;
 
+import static org.hamcrest.Matchers.hasItem;
+
+import java.util.Set;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
 import org.apache.marmotta.kiwi.persistence.KiWiDialect;
-import org.apache.marmotta.kiwi.persistence.h2.H2Dialect;
-import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
-import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
 import org.junit.Assert;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.MethodRule;
-import org.junit.rules.TestWatcher;
-import org.junit.rules.TestWatchman;
-import org.junit.runner.Description;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.model.FrameworkMethod;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-import static org.hamcrest.Matchers.hasItem;
-
 /**
  * Test if the dialects returns correct values
  * <p/>
- * Author: Sebastian Schaffert
+ * @author Sebastian Schaffert
  */
-@RunWith(Parameterized.class)
+@RunWith(KiWiDatabaseRunner.class)
 public class DialectTest {
 
-    public KiWiDialect dialect;
-
-
-    /**
-     * Return database configurations if the appropriate parameters have been set.
-     *
-     * @return an array (database name)
-     */
-    @Parameterized.Parameters(name="Database Test {index}: {0}")
-    public static Iterable<Object[]> databases() {
-        String[] databases = {"H2", "PostgreSQL", "MySQL"};
-
-        List<Object[]> result = new ArrayList<Object[]>(databases.length);
-        for(String database : databases) {
-                result.add(new Object[] {
-                        database
-                });
-        }
-        return result;
-    }
+    public final KiWiDialect dialect;
 
-    public DialectTest(String database) {
-        if("H2".equals(database)) {
-            this.dialect = new H2Dialect();
-        } else if("MySQL".equals(database)) {
-            this.dialect = new MySQLDialect();
-        } else if("PostgreSQL".equals(database)) {
-            this.dialect = new PostgreSQLDialect();
-        }
+
+    public DialectTest(KiWiConfiguration configuration) {
+        this.dialect = configuration.getDialect();
     }
 
     @Test
@@ -110,22 +75,17 @@ public class DialectTest {
         String migrateScript = dialect.getMigrationScript(1,"base");
 
         Assert.assertNotNull(migrateScript);
-        Assert.assertTrue("".equals(migrateScript));
+        Assert.assertFalse("".equals(migrateScript));
+
+        String migrateScript2 = dialect.getMigrationScript(2,"base");
+
+        Assert.assertNotNull(migrateScript2);
+        Assert.assertTrue("".equals(migrateScript2));
     }
 
 
     final Logger logger =
             LoggerFactory.getLogger(DialectTest.class);
 
-    @Rule
-    public TestWatcher watchman = new TestWatcher() {
-        /**
-         * Invoked when a test is about to start
-         */
-        @Override
-        protected void starting(Description description) {
-            logger.info("{} being run...", description.getMethodName());
-        }
-    };
 
 }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/H2ConcurrencyTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/H2ConcurrencyTest.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/H2ConcurrencyTest.java
new file mode 100644
index 0000000..b526a0f
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/H2ConcurrencyTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.kiwi.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.sql.SQLException;
+import java.util.Random;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.persistence.h2.H2Dialect;
+import org.apache.marmotta.kiwi.sail.KiWiStore;
+import org.apache.marmotta.kiwi.test.helper.DBConnectionChecker;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.sail.SailException;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This test starts many triplestore operations in parallel to check if concurrent operations will break things,
+ *
+ * @author Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class H2ConcurrencyTest extends ConcurrencyTestBase {
+
+    private static KiWiStore store;
+
+    @BeforeClass
+    public static void setup() throws RepositoryException {
+        logger = LoggerFactory.getLogger(H2ConcurrencyTest.class);
+
+        KiWiConfiguration h2Config = KiWiDatabaseRunner.createKiWiConfig("H2", new H2Dialect());
+        DBConnectionChecker.checkDatabaseAvailability(h2Config);
+        
+        rnd = new Random();
+
+        store = new KiWiStore(h2Config);
+        repository = new SailRepository(store);
+        repository.initialize();
+    }
+
+    @AfterClass
+    public static void dropDatabase() throws RepositoryException, SQLException, SailException {
+        assertTrue(store.checkConsistency());
+        store.closeValueFactory(); // release all connections before dropping the database
+        store.getPersistence().dropDatabase();
+        repository.shutDown();
+    }
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/MySQLConcurrencyTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/MySQLConcurrencyTest.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/MySQLConcurrencyTest.java
new file mode 100644
index 0000000..29bfabf
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/MySQLConcurrencyTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.kiwi.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.sql.SQLException;
+import java.util.Random;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
+import org.apache.marmotta.kiwi.sail.KiWiStore;
+import org.apache.marmotta.kiwi.test.helper.DBConnectionChecker;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.sail.SailException;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This test starts many triplestore operations in parallel to check if concurrent operations will break things,
+ *
+ * @author Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class MySQLConcurrencyTest extends ConcurrencyTestBase {
+
+    private static KiWiStore store;
+
+    @BeforeClass
+    public static void setup() throws RepositoryException {
+        logger = LoggerFactory.getLogger(MySQLConcurrencyTest.class);
+
+        KiWiConfiguration mysqlConfig = KiWiDatabaseRunner.createKiWiConfig("MySQL", new MySQLDialect());
+        DBConnectionChecker.checkDatabaseAvailability(mysqlConfig);
+        
+        rnd = new Random();
+
+        store = new KiWiStore(mysqlConfig);
+        repository = new SailRepository(store);
+        repository.initialize();
+    }
+
+    @AfterClass
+    public static void dropDatabase() throws RepositoryException, SQLException, SailException {
+    	if (store != null && store.isInitialized()) {
+            assertTrue(store.checkConsistency());
+            store.closeValueFactory(); // release all connections before dropping the database 
+            store.getPersistence().dropDatabase();
+            repository.shutDown();
+    	}
+    }
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/PersistenceTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/PersistenceTest.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/PersistenceTest.java
index 15f8a52..1f9245e 100644
--- a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/PersistenceTest.java
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/PersistenceTest.java
@@ -1,13 +1,12 @@
-/**
- * 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
+/*
+ * 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
+ *      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,
@@ -18,134 +17,68 @@
 package org.apache.marmotta.kiwi.test;
 
 import static org.apache.marmotta.commons.sesame.model.LiteralCommons.getRDFLangStringType;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasItems;
+import info.aduna.iteration.Iterations;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Random;
 
+import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.marmotta.commons.sesame.model.Namespaces;
 import org.apache.marmotta.commons.util.DateUtils;
-import info.aduna.iteration.Iterations;
-import org.apache.commons.lang.RandomStringUtils;
-import org.apache.marmotta.kiwi.model.rdf.*;
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.model.rdf.KiWiAnonResource;
+import org.apache.marmotta.kiwi.model.rdf.KiWiBooleanLiteral;
+import org.apache.marmotta.kiwi.model.rdf.KiWiDateLiteral;
+import org.apache.marmotta.kiwi.model.rdf.KiWiDoubleLiteral;
+import org.apache.marmotta.kiwi.model.rdf.KiWiIntLiteral;
+import org.apache.marmotta.kiwi.model.rdf.KiWiLiteral;
+import org.apache.marmotta.kiwi.model.rdf.KiWiNamespace;
+import org.apache.marmotta.kiwi.model.rdf.KiWiNode;
+import org.apache.marmotta.kiwi.model.rdf.KiWiResource;
+import org.apache.marmotta.kiwi.model.rdf.KiWiStringLiteral;
+import org.apache.marmotta.kiwi.model.rdf.KiWiTriple;
+import org.apache.marmotta.kiwi.model.rdf.KiWiUriResource;
 import org.apache.marmotta.kiwi.persistence.KiWiConnection;
-import org.apache.marmotta.kiwi.persistence.KiWiDialect;
 import org.apache.marmotta.kiwi.persistence.KiWiPersistence;
-import org.apache.marmotta.kiwi.persistence.h2.H2Dialect;
-import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
-import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
-import org.apache.marmotta.kiwi.test.helper.DBConnectionChecker;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 import org.openrdf.model.Statement;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Random;
-
-import static org.hamcrest.Matchers.hasItem;
-import static org.hamcrest.Matchers.hasItems;
 
 /**
- * This test verifies the persistence functionality of the KiWi triple store. It will try running over all
- * available databases. Except for in-memory databases like H2 or Derby, database URLs must be passed as
- * system property, or otherwise the test is skipped for this database. Available system properties:
- * <ul>
- *     <li>PostgreSQL:
- *     <ul>
- *         <li>postgresql.url, e.g. jdbc:postgresql://localhost:5433/kiwitest?prepareThreshold=3</li>
- *         <li>postgresql.user (default: lmf)</li>
- *         <li>postgresql.pass (default: lmf)</li>
- *     </ul>
- *     </li>
- *     <li>MySQL:
- *     <ul>
- *         <li>mysql.url, e.g. jdbc:mysql://localhost:3306/kiwitest?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull</li>
- *         <li>mysql.user (default: lmf)</li>
- *         <li>mysql.pass (default: lmf</li>
- *     </ul>
- *     </li>
- *     <li>H2:
- *     <ul>
- *         <li>h2.url, e.g. jdbc:h2:mem;MVCC=true;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=10</li>
- *         <li>h2.user (default: lmf)</li>
- *         <li>h2.pass (default: lmf</li>
- *     </ul>
- *     </li>
- * </ul>
+ * This test verifies the persistence functionality of the KiWi triple store. 
  *
  * @see org.apache.marmotta.kiwi.persistence.KiWiConnection
  * @see org.apache.marmotta.kiwi.persistence.KiWiPersistence
- * <p/>
- * Author: Sebastian Schaffert
+ * @author Sebastian Schaffert
  */
-@RunWith(Parameterized.class)
+@RunWith(KiWiDatabaseRunner.class)
 public class PersistenceTest {
 
-    /**
-     * Return database configurations if the appropriate parameters have been set.
-     *
-     * @return an array (database name, url, user, password)
-     */
-    @Parameterized.Parameters(name="Database Test {index}: {0} at {1}")
-    public static Iterable<Object[]> databases() {
-        String[] databases = {"H2", "PostgreSQL", "MySQL"};
-
-        List<Object[]> result = new ArrayList<Object[]>(databases.length);
-        for(String database : databases) {
-            if(System.getProperty(database.toLowerCase()+".url") != null) {
-                result.add(new Object[] {
-                        database,
-                        System.getProperty(database.toLowerCase()+".url"),
-                        System.getProperty(database.toLowerCase()+".user","lmf"),
-                        System.getProperty(database.toLowerCase()+".pass","lmf")
-                });
-            }
-        }
-        return result;
-    }
-
-
-    private KiWiDialect dialect;
-
-    private String jdbcUrl;
-
-    private String jdbcUser;
-
-    private String jdbcPass;
 
     private KiWiPersistence persistence;
 
-    public PersistenceTest(String database, String jdbcUrl, String jdbcUser, String jdbcPass) {
-        this.jdbcPass = jdbcPass;
-        this.jdbcUrl = jdbcUrl;
-        this.jdbcUser = jdbcUser;
-
-        if("H2".equals(database)) {
-            this.dialect = new H2Dialect();
-        } else if("MySQL".equals(database)) {
-            this.dialect = new MySQLDialect();
-        } else if("PostgreSQL".equals(database)) {
-            this.dialect = new PostgreSQLDialect();
-        }
-        
-        DBConnectionChecker.checkDatabaseAvailability(jdbcUrl, jdbcUser, jdbcPass, dialect);
+    private final KiWiConfiguration kiwiConfig;
+
+    public PersistenceTest(KiWiConfiguration kiwiConfig) {
+        this.kiwiConfig = kiwiConfig;
     }
 
 
     @Before
     public void initDatabase() throws SQLException {
-        persistence = new KiWiPersistence("test",jdbcUrl,jdbcUser,jdbcPass,dialect);
+        persistence = new KiWiPersistence(kiwiConfig);
+        persistence.initialise();
         persistence.initDatabase();
     }
 
@@ -156,28 +89,13 @@ public class PersistenceTest {
     }
 
 
-    final Logger logger =
-            LoggerFactory.getLogger(PersistenceTest.class);
-
-    @Rule
-    public TestWatcher watchman = new TestWatcher() {
-        /**
-         * Invoked when a test is about to start
-         */
-        @Override
-        protected void starting(Description description) {
-            logger.info("{} being run...", description.getMethodName());
-        }
-    };
-
-
     @Test
     public void testCreateDropDatabase() throws SQLException {
         // test if database exists and has a version
         KiWiConnection connection = persistence.getConnection();
         try {
             Assert.assertThat(connection.getDatabaseTables(),hasItems("nodes","triples","namespaces"));
-            Assert.assertEquals(1, connection.getDatabaseVersion());
+            Assert.assertEquals(2, connection.getDatabaseVersion());
 
             connection.commit();
         } finally {
@@ -197,7 +115,7 @@ public class PersistenceTest {
         try {
             // add a new URI to the triple store and check if it exists afterwards, before and after commit
             KiWiUriResource uri = new KiWiUriResource("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
-            connection.storeNode(uri);
+            connection.storeNode(uri, false);
 
             // check if it then has a database ID
             Assert.assertNotNull(uri.getId());
@@ -226,6 +144,8 @@ public class PersistenceTest {
 
             connection.commit();
 
+            Assert.assertEquals(1,Iterations.asList(connection.listResources()).size());
+
 
             // clear cache and test again
             persistence.clearCache();
@@ -272,7 +192,7 @@ public class PersistenceTest {
         try {
             // add a new URI to the triple store and check if it exists afterwards, before and after commit
             KiWiAnonResource bnode = new KiWiAnonResource(RandomStringUtils.randomAlphanumeric(8));
-            connection.storeNode(bnode);
+            connection.storeNode(bnode, false);
 
             // check if it then has a database ID
             Assert.assertNotNull(bnode.getId());
@@ -301,6 +221,7 @@ public class PersistenceTest {
 
             connection.commit();
 
+            Assert.assertEquals(1,Iterations.asList(connection.listResources()).size());
 
             // clear cache and test again
             persistence.clearCache();
@@ -346,11 +267,11 @@ public class PersistenceTest {
         KiWiConnection connection = persistence.getConnection();
         try {
             KiWiUriResource   stype   = new KiWiUriResource(Namespaces.NS_XSD+"string");
-            connection.storeNode(stype);
+            connection.storeNode(stype, false);
 
             // add a new URI to the triple store and check if it exists afterwards, before and after commit
             KiWiStringLiteral literal = new KiWiStringLiteral(RandomStringUtils.randomAlphanumeric(8),null,stype);
-            connection.storeNode(literal);
+            connection.storeNode(literal, false);
 
             // check if it then has a database ID
             Assert.assertNotNull(literal.getId());
@@ -425,11 +346,11 @@ public class PersistenceTest {
         KiWiConnection connection = persistence.getConnection();
         try {
             KiWiUriResource   stype   = new KiWiUriResource(getRDFLangStringType());
-            connection.storeNode(stype);
+            connection.storeNode(stype, false);
 
             // add a new URI to the triple store and check if it exists afterwards, before and after commit
             KiWiStringLiteral literal = new KiWiStringLiteral(RandomStringUtils.randomAlphanumeric(8), Locale.ENGLISH, stype);
-            connection.storeNode(literal);
+            connection.storeNode(literal, false);
 
             // check if it then has a database ID
             Assert.assertNotNull(literal.getId());
@@ -507,7 +428,7 @@ public class PersistenceTest {
 
             // add a new URI to the triple store and check if it exists afterwards, before and after commit
             KiWiStringLiteral literal = new KiWiStringLiteral(RandomStringUtils.randomAlphanumeric(8), null, uri);
-            connection.storeNode(literal);
+            connection.storeNode(literal, false);
 
             // check if it then has a database ID
             Assert.assertNotNull(literal.getId());
@@ -582,6 +503,89 @@ public class PersistenceTest {
      * @throws SQLException
      */
     @Test
+    public void testStoreBigStringLiteral() throws SQLException {
+        KiWiConnection connection = persistence.getConnection();
+        try {
+            KiWiUriResource uri = new KiWiUriResource("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+
+            // add a new URI to the triple store and check if it exists afterwards, before and after commit
+            KiWiStringLiteral literal = new KiWiStringLiteral(RandomStringUtils.randomAlphanumeric(16384), null, uri);
+            connection.storeNode(literal, false);
+
+            // check if it then has a database ID
+            Assert.assertNotNull(literal.getId());
+
+            KiWiNode testLiteral1 = connection.loadNodeById(literal.getId());
+
+            // needs to be equal, and should also be the identical object!
+            Assert.assertEquals(literal,testLiteral1);
+            Assert.assertEquals(uri,((KiWiLiteral)testLiteral1).getType());
+            Assert.assertTrue(literal == testLiteral1);
+
+            connection.commit();
+
+            KiWiNode testLiteral2 = connection.loadNodeById(literal.getId());
+
+            // needs to be equal, and should also be the identical object!
+            Assert.assertEquals(literal,testLiteral2);
+            Assert.assertEquals(uri,((KiWiLiteral)testLiteral2).getType());
+            Assert.assertTrue(literal == testLiteral2);
+
+            KiWiNode testLiteral3 = connection.loadLiteral(literal.stringValue(),null,uri);
+
+            // needs to be equal, and should also be the identical object!
+            Assert.assertEquals(literal,testLiteral3);
+            Assert.assertEquals(uri,((KiWiLiteral)testLiteral3).getType());
+            Assert.assertTrue(literal == testLiteral3);
+
+            connection.commit();
+
+
+            // clear cache and test again
+            persistence.clearCache();
+            KiWiNode testLiteral4 = connection.loadNodeById(literal.getId());
+
+            // needs to be equal, but now it should not be the same object!
+            Assert.assertEquals(literal,testLiteral4);
+            Assert.assertEquals(uri,((KiWiLiteral)testLiteral4).getType());
+            Assert.assertTrue(literal != testLiteral4);
+
+            KiWiNode testLiteral5 = connection.loadLiteral(literal.stringValue(),null,uri);
+
+            // needs to be equal, but now it should not be the same object!
+            Assert.assertEquals(literal,testLiteral5);
+            Assert.assertEquals(uri,((KiWiLiteral)testLiteral5).getType());
+            Assert.assertTrue(literal != testLiteral5);
+
+            connection.commit();
+
+            // finally do a test on the nodes table, it should contain exactly one entry
+            PreparedStatement checkNodeStmt = connection.getJDBCConnection().prepareStatement("SELECT * FROM nodes WHERE ntype='string'");
+            ResultSet result = checkNodeStmt.executeQuery();
+
+            Assert.assertTrue(result.next());
+            Assert.assertEquals((long)literal.getId(),result.getLong("id"));
+            Assert.assertEquals(literal.stringValue(),result.getString("svalue"));
+            Assert.assertEquals("string",result.getString("ntype"));
+            Assert.assertNull(result.getString("lang"));
+            Assert.assertEquals((long) uri.getId(), result.getLong("ltype"));
+
+            result.close();
+            connection.commit();
+        } finally {
+            connection.close();
+        }
+
+    }
+
+
+
+    /**
+     * Test storing and loading string literals (with type and without language).
+     *
+     * @throws SQLException
+     */
+    @Test
     public void testStoreIntLiteral() throws SQLException {
         KiWiConnection connection = persistence.getConnection();
         try {
@@ -593,7 +597,7 @@ public class PersistenceTest {
 
                     // add a new URI to the triple store and check if it exists afterwards, before and after commit
             KiWiIntLiteral literal = new KiWiIntLiteral(value, uri);
-            connection.storeNode(literal);
+            connection.storeNode(literal, false);
 
             // check if it then has a database ID
             Assert.assertNotNull(literal.getId());
@@ -698,7 +702,7 @@ public class PersistenceTest {
 
             // add a new URI to the triple store and check if it exists afterwards, before and after commit
             KiWiDoubleLiteral literal = new KiWiDoubleLiteral(value, uri);
-            connection.storeNode(literal);
+            connection.storeNode(literal, false);
 
             // check if it then has a database ID
             Assert.assertNotNull(literal.getId());
@@ -802,7 +806,7 @@ public class PersistenceTest {
             boolean value = rnd.nextBoolean();
             // add a new URI to the triple store and check if it exists afterwards, before and after commit
             KiWiBooleanLiteral literal = new KiWiBooleanLiteral(value, uri);
-            connection.storeNode(literal);
+            connection.storeNode(literal, false);
 
             // check if it then has a database ID
             Assert.assertNotNull(literal.getId());
@@ -905,7 +909,7 @@ public class PersistenceTest {
             Date value = new Date();
             // add a new URI to the triple store and check if it exists afterwards, before and after commit
             KiWiDateLiteral literal = new KiWiDateLiteral(value, uri);
-            connection.storeNode(literal);
+            connection.storeNode(literal, false);
 
             // check if it then has a database ID
             Assert.assertNotNull(literal.getId());
@@ -994,6 +998,7 @@ public class PersistenceTest {
     }
 
 
+
     /**
      * Test storing, querying and deleting triples
      */
@@ -1009,13 +1014,13 @@ public class PersistenceTest {
                 KiWiStringLiteral object_2 = new KiWiStringLiteral(RandomStringUtils.randomAlphanumeric(32),null,stype);
                 KiWiUriResource context  = new KiWiUriResource("http://localhost/context/"+RandomStringUtils.randomAlphanumeric(8));
 
-                connection.storeNode(stype);
-                connection.storeNode(subject);
-                connection.storeNode(pred_1);
-                connection.storeNode(pred_2);
-                connection.storeNode(object_1);
-                connection.storeNode(object_2);
-                connection.storeNode(context);
+                connection.storeNode(stype, false);
+                connection.storeNode(subject, false);
+                connection.storeNode(pred_1, false);
+                connection.storeNode(pred_2, false);
+                connection.storeNode(object_1, false);
+                connection.storeNode(object_2, false);
+                connection.storeNode(context, false);
 
                 KiWiTriple triple1 = new KiWiTriple(subject,pred_1,object_1,context);
                 KiWiTriple triple2 = new KiWiTriple(subject,pred_2,object_2,context);
@@ -1024,7 +1029,7 @@ public class PersistenceTest {
                 connection.storeTriple(triple2);
 
                 // check querying within transaction
-                List<Statement> result1 = connection.listTriples(subject,null,null,null,false).asList();
+                List<Statement> result1 = connection.listTriples(subject,null,null,null,false, true).asList();
                 Assert.assertThat(result1,hasItems((Statement)triple1,(Statement)triple2));
 
                 Assert.assertEquals(2, connection.getSize());
@@ -1033,7 +1038,7 @@ public class PersistenceTest {
 
                 connection.commit();
 
-                List<Statement> result2 = connection.listTriples(subject,null,null,null,false).asList();
+                List<Statement> result2 = connection.listTriples(subject,null,null,null,false, true).asList();
                 Assert.assertThat(result2,hasItems((Statement)triple1,(Statement)triple2));
 
                 Assert.assertEquals(2, connection.getSize());
@@ -1045,7 +1050,7 @@ public class PersistenceTest {
                 // clear cache and test again
                 persistence.clearCache();
 
-                List<Statement> result3 = connection.listTriples(subject,null,null,null,false).asList();
+                List<Statement> result3 = connection.listTriples(subject,null,null,null,false, true).asList();
                 Assert.assertThat(result3,hasItems((Statement)triple1,(Statement)triple2));
 
 
@@ -1054,7 +1059,7 @@ public class PersistenceTest {
                 Assert.assertEquals(0, connection.getSize(subject));
 
                 // test database contents
-                PreparedStatement stmt = connection.getJDBCConnection().prepareStatement("SELECT * FROM triples WHERE deleted = false");
+                PreparedStatement stmt = connection.getJDBCConnection().prepareStatement("SELECT * FROM triples WHERE deleted = false ORDER BY subject, predicate");
                 ResultSet dbResult1 = stmt.executeQuery();
 
                 Assert.assertTrue(dbResult1.next());

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/PostgreSQLConcurrencyTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/PostgreSQLConcurrencyTest.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/PostgreSQLConcurrencyTest.java
new file mode 100644
index 0000000..7b7b3c1
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/PostgreSQLConcurrencyTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.kiwi.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.sql.SQLException;
+import java.util.Random;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
+import org.apache.marmotta.kiwi.sail.KiWiStore;
+import org.apache.marmotta.kiwi.test.helper.DBConnectionChecker;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.sail.SailException;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This test starts many triplestore operations in parallel to check if concurrent operations will break things,
+ *
+ * @author Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class PostgreSQLConcurrencyTest extends ConcurrencyTestBase {
+
+    private static KiWiStore store;
+
+    @BeforeClass
+    public static void setup() throws RepositoryException {
+        logger = LoggerFactory.getLogger(PostgreSQLConcurrencyTest.class);
+
+        logger.info("creating test setup...");
+
+        KiWiConfiguration psql = KiWiDatabaseRunner.createKiWiConfig("PostgreSQL", new PostgreSQLDialect());
+        DBConnectionChecker.checkDatabaseAvailability(psql);
+        
+        rnd = new Random();
+
+        store = new KiWiStore(psql);
+        repository = new SailRepository(store);
+        repository.initialize();
+    }
+
+    @AfterClass
+    public static void dropDatabase() throws RepositoryException, SQLException, SailException {
+        logger.info("cleaning up test setup...");
+    	if (store != null && store.isInitialized()) {
+            assertTrue(store.checkConsistency());
+            store.closeValueFactory(); // release all connections before dropping the database
+            store.getPersistence().dropDatabase();
+            repository.shutDown();
+    	}
+    }
+
+
+}