jena-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a...@apache.org
Subject [022/100] [abbrv] [partial] jena git commit: JENA-1397: Rename modules and set versions
Date Thu, 28 Sep 2017 16:05:34 GMT
http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2-cmds/testing/Values/manifest.ttl
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2-cmds/testing/Values/manifest.ttl b/jena-db/jena-tdb2-cmds/testing/Values/manifest.ttl
new file mode 100644
index 0000000..3396af5
--- /dev/null
+++ b/jena-db/jena-tdb2-cmds/testing/Values/manifest.ttl
@@ -0,0 +1,76 @@
+#  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 rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs:	<http://www.w3.org/2000/01/rdf-schema#> .
+@prefix mf:     <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
+@prefix qt:     <http://www.w3.org/2001/sw/DataAccess/tests/test-query#> .
+
+<>  rdf:type mf:Manifest ;
+    rdfs:label "Value tests" ;
+    mf:entries
+    ( 
+      [  mf:name    "Value-00" ;
+         mf:action
+            [ qt:query  <value-00.rq> ;
+              qt:data   <data-1.ttl> ] ;
+      ]
+      [  mf:name    "Value-01" ;
+         mf:action
+            [ qt:query  <value-01.rq> ;
+              qt:data   <data-1.ttl> ] ;
+      ]
+      [  mf:name    "Value-02" ;
+         mf:action
+            [ qt:query  <value-02.rq> ;
+              qt:data   <data-1.ttl> ] ;
+      ]
+      [  mf:name    "Value-03" ;
+         mf:action
+            [ qt:query  <value-03.rq> ;
+              qt:data   <data-1.ttl> ] ;
+      ]
+
+      [  mf:name    "Value-04" ;
+         mf:action
+            [ qt:query  <value-04.rq> ;
+              qt:data   <data-1.ttl> ] ;
+      ]
+      [  mf:name    "Value-05" ;
+         mf:action
+            [ qt:query  <value-05.rq> ;
+              qt:data   <data-1.ttl> ] ;
+      ]
+      [  mf:name    "Value-06" ;
+         mf:action
+            [ qt:query  <value-06.rq> ;
+              qt:data   <data-1.ttl> ] ;
+      ]
+      [  mf:name    "Value-07" ;
+         mf:action
+            [ qt:query  <value-07.rq> ;
+              qt:data   <data-1.ttl> ] ;
+      ]
+      [  mf:name    "Value-08" ;
+         mf:action
+            [ qt:query  <value-08.rq> ;
+              qt:data   <data-1.ttl> ] ;
+      ]
+      [  mf:name    "Value-09" ;
+         mf:action
+            [ qt:query  <value-09.rq> ;
+              qt:data   <data-1.ttl> ] ;
+      ]
+    ) .
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2-cmds/testing/Values/value-00.rq
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2-cmds/testing/Values/value-00.rq b/jena-db/jena-tdb2-cmds/testing/Values/value-00.rq
new file mode 100644
index 0000000..d1fe80b
--- /dev/null
+++ b/jena-db/jena-tdb2-cmds/testing/Values/value-00.rq
@@ -0,0 +1 @@
+SELECT * { ?s ?p ?o }

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2-cmds/testing/Values/value-01.rq
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2-cmds/testing/Values/value-01.rq b/jena-db/jena-tdb2-cmds/testing/Values/value-01.rq
new file mode 100644
index 0000000..664f67a
--- /dev/null
+++ b/jena-db/jena-tdb2-cmds/testing/Values/value-01.rq
@@ -0,0 +1 @@
+SELECT * { ?s ?p 1 }

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2-cmds/testing/Values/value-02.rq
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2-cmds/testing/Values/value-02.rq b/jena-db/jena-tdb2-cmds/testing/Values/value-02.rq
new file mode 100644
index 0000000..5dfe5ec
--- /dev/null
+++ b/jena-db/jena-tdb2-cmds/testing/Values/value-02.rq
@@ -0,0 +1 @@
+SELECT * { ?s ?p 1.5 }

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2-cmds/testing/Values/value-03.rq
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2-cmds/testing/Values/value-03.rq b/jena-db/jena-tdb2-cmds/testing/Values/value-03.rq
new file mode 100644
index 0000000..7134be8
--- /dev/null
+++ b/jena-db/jena-tdb2-cmds/testing/Values/value-03.rq
@@ -0,0 +1 @@
+SELECT * { ?s ?p "1" }

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2-cmds/testing/Values/value-04.rq
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2-cmds/testing/Values/value-04.rq b/jena-db/jena-tdb2-cmds/testing/Values/value-04.rq
new file mode 100644
index 0000000..030116d
--- /dev/null
+++ b/jena-db/jena-tdb2-cmds/testing/Values/value-04.rq
@@ -0,0 +1 @@
+SELECT * { ?s ?p "1"@en }

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2-cmds/testing/Values/value-05.rq
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2-cmds/testing/Values/value-05.rq b/jena-db/jena-tdb2-cmds/testing/Values/value-05.rq
new file mode 100644
index 0000000..fbd8d9b
--- /dev/null
+++ b/jena-db/jena-tdb2-cmds/testing/Values/value-05.rq
@@ -0,0 +1,5 @@
+SELECT *
+{ 
+    ?s ?p ?o . 
+    FILTER(?o = 1)
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2-cmds/testing/Values/value-06.rq
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2-cmds/testing/Values/value-06.rq b/jena-db/jena-tdb2-cmds/testing/Values/value-06.rq
new file mode 100644
index 0000000..8f34124
--- /dev/null
+++ b/jena-db/jena-tdb2-cmds/testing/Values/value-06.rq
@@ -0,0 +1,6 @@
+PREFIX  xsd:    <http://www.w3.org/2001/XMLSchema#>
+
+SELECT *
+{ 
+    ?s ?p "2008-04-29+01:00"^^xsd:date .
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2-cmds/testing/Values/value-07.rq
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2-cmds/testing/Values/value-07.rq b/jena-db/jena-tdb2-cmds/testing/Values/value-07.rq
new file mode 100644
index 0000000..cafd777
--- /dev/null
+++ b/jena-db/jena-tdb2-cmds/testing/Values/value-07.rq
@@ -0,0 +1,6 @@
+PREFIX  xsd:    <http://www.w3.org/2001/XMLSchema#>
+
+SELECT *
+{ 
+    ?s ?p ?x . FILTER (?x = "2008-04-29+01:00"^^xsd:date) .
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2-cmds/testing/Values/value-08.rq
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2-cmds/testing/Values/value-08.rq b/jena-db/jena-tdb2-cmds/testing/Values/value-08.rq
new file mode 100644
index 0000000..e6fc284
--- /dev/null
+++ b/jena-db/jena-tdb2-cmds/testing/Values/value-08.rq
@@ -0,0 +1,6 @@
+PREFIX  xsd:    <http://www.w3.org/2001/XMLSchema#>
+
+SELECT *
+{ 
+    ?s ?p "2008-04-29T09:13:15+01:00"^^xsd:dateTime .
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2-cmds/testing/Values/value-09.rq
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2-cmds/testing/Values/value-09.rq b/jena-db/jena-tdb2-cmds/testing/Values/value-09.rq
new file mode 100644
index 0000000..02dcc20
--- /dev/null
+++ b/jena-db/jena-tdb2-cmds/testing/Values/value-09.rq
@@ -0,0 +1,7 @@
+PREFIX  xsd:    <http://www.w3.org/2001/XMLSchema#>
+
+SELECT *
+{ 
+    # Out of range - not an immediate literal
+    ?s ?p "-3000-04-29T09:13:15Z"^^xsd:dateTime
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2-cmds/testing/manifest.ttl
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2-cmds/testing/manifest.ttl b/jena-db/jena-tdb2-cmds/testing/manifest.ttl
new file mode 100644
index 0000000..aeaf80e
--- /dev/null
+++ b/jena-db/jena-tdb2-cmds/testing/manifest.ttl
@@ -0,0 +1,31 @@
+#  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 rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs:	<http://www.w3.org/2000/01/rdf-schema#> .
+@prefix mf:     <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
+@prefix qt:     <http://www.w3.org/2001/sw/DataAccess/tests/test-query#> .
+
+<>  rdf:type mf:Manifest ;
+    rdfs:label "TDB - Scripts" ;
+    mf:include (
+        <Basic/manifest.ttl>
+        <Pattern/manifest.ttl>
+        <Quads/manifest.ttl>
+        <Values/manifest.ttl>
+        <UnionGraph/manifest.ttl>
+    ) .
+
+

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/.gitignore
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/.gitignore b/jena-db/jena-tdb2/.gitignore
new file mode 100644
index 0000000..731afb6
--- /dev/null
+++ b/jena-db/jena-tdb2/.gitignore
@@ -0,0 +1,2 @@
+DB*
+D.*

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/pom.xml
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/pom.xml b/jena-db/jena-tdb2/pom.xml
new file mode 100644
index 0000000..e034ca6
--- /dev/null
+++ b/jena-db/jena-tdb2/pom.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+   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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>jena-tdb2</artifactId>
+  <packaging>jar</packaging>
+  <name>Mantis (${project.artifactId})</name>
+
+  <parent>
+    <groupId>org.apache.jena</groupId>
+    <artifactId>jena-db</artifactId>
+    <version>3.5.0-SNAPSHOT</version>
+  </parent> 
+
+  <dependencies>
+
+    <dependency>
+      <groupId>org.apache.jena</groupId>
+      <artifactId>jena-dboe-trans-data</artifactId>
+      <version>3.5.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.jena</groupId>
+      <artifactId>jena-core</artifactId>
+      <classifier>tests</classifier>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.jena</groupId>
+      <artifactId>jena-arq</artifactId>
+      <classifier>tests</classifier>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.jena</groupId>
+      <artifactId>jena-base</artifactId>
+      <classifier>tests</classifier>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <!-- <phase>package</phase> package is the default -->
+            <goals>
+              <goal>jar-no-fork</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>attach-sources-test</id>
+            <goals>
+              <goal>test-jar-no-fork</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+    </plugins>
+  </build>
+  
+</project>

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/DatabaseMgr.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/DatabaseMgr.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/DatabaseMgr.java
new file mode 100644
index 0000000..098a646
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/DatabaseMgr.java
@@ -0,0 +1,114 @@
+/*
+ * 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.seaborne.tdb2;
+
+import org.apache.jena.query.Dataset ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.seaborne.dboe.base.file.Location ;
+import org.seaborne.tdb2.store.DatasetGraphSwitchable ;
+import org.seaborne.tdb2.store.DatasetGraphTDB ;
+import org.seaborne.tdb2.sys.DatabaseConnection ;
+import org.seaborne.tdb2.sys.DatabaseOps ;
+import org.seaborne.tdb2.sys.TDBInternal ;
+
+/** Operations for TDBS DatasetGraph, including admin operations 
+ * See {@link TDB2Factory} for creating API-level {@link Dataset Datasets}.
+ * 
+ * @see TDB2Factory
+ */
+public class DatabaseMgr {
+
+    // All creation of DatasetGraph for TDB2 goes through this method.
+    private static DatasetGraph DB_ConnectCreate(Location location) {
+        return DatabaseConnection.connectCreate(location).getDatasetGraph();
+//        // One level.
+//        return StoreConnection.connectCreate(location).getDatasetGraph() ; 
+    }
+
+    /** Create or connect to a TDB2-backed dataset */
+    public static DatasetGraph connectDatasetGraph(Location location) {
+        return DB_ConnectCreate(location); 
+    }
+
+    /** Create or connect to a TDB2-backed dataset */
+    public static DatasetGraph connectDatasetGraph(String location) {
+        return connectDatasetGraph(Location.create(location)) ;
+    }
+    
+    /**
+     * Compact a datasets which must be a switchable TDB database.
+     * This is the normal dataset type for on-disk TDB2 databases.
+     *  
+     * @param container
+     */
+    public static void compact(DatasetGraph container) {
+        DatasetGraphSwitchable dsg = requireSwitchable(container);
+        DatabaseOps.compact(dsg);
+    }
+
+    /**
+     * Create a backup for a switchable TDB database. This is the normal dataset type for
+     * on-disk TDB2 databases.
+     * <p>
+     * The backup is created in the databases folder, under "Backups".
+     * <p>
+     * Backup creates a consistent copy og the database. It is performed as a read-transaction
+     * and does not lock out other use of the dataset.
+     * 
+     * @param container
+     * @return File name of the backup.
+     */
+    public static String backup(DatasetGraph container) {
+        DatasetGraphSwitchable dsg = requireSwitchable(container);
+        return DatabaseOps.backup(dsg);
+    }
+
+
+    /** Create an in-memory TDB2-backed dataset (for testing) */
+    public static DatasetGraph createDatasetGraph() {
+        return connectDatasetGraph(Location.mem()) ;
+    }
+
+    /** Return the location of a dataset if it is backed by TDB, else null */ 
+    public static boolean isBackedByTDB(DatasetGraph datasetGraph) {
+        return TDBInternal.isBackedByTDB(datasetGraph);
+    }
+
+    /** Return the location of a DatasetGraph if it is backed by TDB, else null. */
+    public static Location location(DatasetGraph datasetGraph) {
+        DatasetGraphSwitchable dsg = requireSwitchable(datasetGraph);
+        if ( dsg == null )
+            return null ;
+        return dsg.getLocation();
+    }
+
+    private static DatasetGraphSwitchable requireSwitchable(DatasetGraph datasetGraph) {
+        if ( datasetGraph instanceof DatasetGraphSwitchable )
+            return (DatasetGraphSwitchable)datasetGraph;
+        throw new TDBException("Not a switchable TDB database");
+    }
+
+    static DatasetGraphTDB requireDirect(DatasetGraph datasetGraph) {
+        DatasetGraphTDB dsg = TDBInternal.getDatasetGraphTDB(datasetGraph);
+        if ( dsg == null )
+            throw new TDBException("Not a TDB database (argument is neither a switchable nor direct TDB DatasetGraph)");
+        return dsg;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/TDB2.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/TDB2.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/TDB2.java
new file mode 100644
index 0000000..4582cfe
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/TDB2.java
@@ -0,0 +1,269 @@
+/*
+ * 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.seaborne.tdb2 ;
+
+import org.apache.jena.atlas.lib.Sync ;
+import org.apache.jena.graph.Graph ;
+import org.apache.jena.ontology.OntModel ;
+import org.apache.jena.ontology.impl.OntModelImpl ;
+import org.apache.jena.query.ARQ ;
+import org.apache.jena.rdf.model.Model ;
+import org.apache.jena.reasoner.InfGraph ;
+import org.apache.jena.riot.lang.ReaderRIOTRDFXML;
+import org.apache.jena.sparql.SystemARQ ;
+import org.apache.jena.sparql.core.assembler.AssemblerUtils ;
+import org.apache.jena.sparql.engine.main.StageBuilder ;
+import org.apache.jena.sparql.engine.main.StageGenerator ;
+import org.apache.jena.sparql.lib.Metadata ;
+import org.apache.jena.sparql.mgt.SystemInfo ;
+import org.apache.jena.sparql.util.Context ;
+import org.apache.jena.sparql.util.MappingRegistry ;
+import org.apache.jena.sparql.util.Symbol ;
+import org.apache.jena.system.JenaSystem ;
+import org.seaborne.tdb2.assembler.VocabTDB2 ;
+import org.seaborne.tdb2.modify.UpdateEngineTDB ;
+import org.seaborne.tdb2.solver.QueryEngineTDB ;
+import org.seaborne.tdb2.solver.StageGeneratorDirectTDB ;
+import org.seaborne.tdb2.sys.EnvTDB ;
+import org.seaborne.tdb2.sys.SystemTDB ;
+import org.seaborne.tdb2.sys.TDBInternal ;
+import org.slf4j.Logger ;
+import org.slf4j.LoggerFactory ;
+
+public class TDB2 {
+    /** IRI for TDB */
+    public static final String  tdbIRI                           = "http://seaborne.org/#tdb" ;
+
+    /** Root of TDB-defined parameter names */
+    public static final String  tdbParamNS                       = "http://seaborne.org/TDB#" ;
+
+    /** Prefix for TDB-defined parameter names */
+    public static final String  tdbSymbolPrefix                  = "tdb" ;
+
+    // Internal logging
+    private static final Logger log                              = LoggerFactory.getLogger(TDB2.class) ;
+
+    /** Logger for loading information */
+    public static final String  logLoaderName                    = "org.apache.jena.tdb.loader" ;
+    /** Logger for loading information */
+    public static final Logger  logLoader                        = LoggerFactory.getLogger(logLoaderName) ;
+
+    /** Logger for general information */
+    public static final String  logInfoName                      = "org.apache.jena.info" ;
+    /** Logger for general information */
+    public static final Logger  logInfo                          = LoggerFactory.getLogger(logInfoName) ;
+
+    // /** Logger for execution information */
+    // public static final String logExecName = "org.apache.jena.tdb.exec" ;
+    // /** Logger for execution information */
+    // public static final Logger logExec = LoggerFactory.getLogger(logExecName)
+    // ;
+
+    public final static String  namespace                        = "http://jena.apache.org/2016/tdb#" ;
+
+    /** Symbol to use the union of named graphs as the default graph of a query */
+    public static final Symbol  symUnionDefaultGraph             = SystemTDB.allocSymbol("unionDefaultGraph") ;
+
+    /**
+     * A String enum Symbol that specifies the type of temporary storage for
+     * transaction journal write blocks.
+     * <p/>
+     * "mem" = Java heap memory (default) <br>
+     * "direct" = Process heap memory <br>
+     * "mapped" = Memory mapped temporary file <br>
+     */
+    public static final Symbol  transactionJournalWriteBlockMode = SystemTDB.allocSymbol("transactionJournalWriteBlockMode") ;
+
+    public static Context getContext() {
+        return ARQ.getContext() ;
+    }
+
+    /**
+     * Release any and all system resources held by TDB.
+     * All release datasets or graphs held by client code are no longer valid. 
+     */
+    public static void closedown() {
+        TDBInternal.reset() ;
+    }
+
+    /** Sync a TDB-backed Model. Do nothing if not TDB-backed. */
+    public static void sync(Model model) {
+        if ( model instanceof OntModelImpl ) {
+            OntModelImpl ontModel = (OntModelImpl)model ;
+            sync(ontModel.getBaseGraph()) ;
+            return ;
+        }
+        // This never happens (there is only one OntModel implementation)
+        if ( model instanceof OntModel ) {
+            OntModel ontModel = (OntModel)model ;
+            sync(ontModel.getBaseModel()) ;
+            return ;
+        }
+
+        sync(model.getGraph()) ;
+    }
+
+    /** Sync a TDB-backed Graph. Do nothing if not TDB-backed. */
+    public static void sync(Graph graph) {
+        if ( graph == null )
+            return ;
+
+        if ( graph instanceof InfGraph ) {
+            InfGraph infGraph = (InfGraph)graph ;
+            sync(infGraph.getRawGraph()) ;
+            return ;
+        }
+        syncObject(graph) ;
+    }
+
+//    /** Sync a TDB-backed Dataset. Do nothing if not TDB-backed. */
+//    public static void sync(Dataset dataset) {
+//        if ( dataset == null )
+//            return ;
+//        DatasetGraph ds = dataset.asDatasetGraph() ;
+//        sync(ds) ;
+//    }
+//
+//    /** Sync a TDB-backed DatasetGraph. Do nothing if not TDB-backed. */
+//    public static void sync(DatasetGraph dataset) {
+//        if ( dataset == null )
+//            return ;
+//        
+//        // Should be: SystemARQ.sync(dataset) ;
+//        if ( dataset instanceof DatasetGraphTDB ) {
+//            syncObject(dataset) ;
+//            return ;
+//        }
+//
+//        if ( dataset instanceof DatasetGraphTransaction ) {
+//            DatasetGraphTransaction dsgt = (DatasetGraphTransaction)dataset ;
+//            // This only sync if the dataset has not been used transactionally.
+//            // Can't sync transactional datasets (it's meaningless)
+//            dsgt.syncIfNotTransactional() ;
+//            return ;
+//        }
+//
+//        // May be a general purpose dataset with TDB objects in it.
+//        sync(dataset.getDefaultGraph()) ;
+//        Iterator<Node> iter = dataset.listGraphNodes() ;
+//        iter = Iter.toList(iter).iterator() ; // Avoid iterator concurrency.
+//        for (; iter.hasNext();) {
+//            Node n = iter.next() ;
+//            Graph g = dataset.getGraph(n) ;
+//            sync(g) ;
+//        }
+//    }
+
+    /**
+     * Sync a TDB synchronizable object (model, graph, dataset). If force is
+     * true, synchronize as much as possible (e.g. file metadata) else make a
+     * reasonable attenpt at synchronization but does not gauarantee disk state.
+     * Do nothing otherwise
+     */
+    private static void syncObject(Object object) {
+        if ( object == null )
+            return ;
+        if ( object instanceof Sync )
+            ((Sync)object).sync() ;
+    }
+
+    private static final Object initLock = new Object() ;
+    private static volatile boolean initialized = false ;
+    static { JenaSystem.init(); }
+    
+    /**
+     * TDB System initialization - normally, this is not explicitly called
+     * because all routes to use TDB will cause initialization to occur.
+     * However, calling it repeatedly is safe and low cost.
+     */
+    public static void init() {
+        if ( initialized )
+            return ;
+        synchronized(initLock) {
+            if ( initialized ) {
+                if ( JenaSystem.DEBUG_INIT )
+                    System.err.println("TDB2.init - return") ;
+                return ;
+            }
+            initialized = true ;
+            if ( JenaSystem.DEBUG_INIT )
+                System.err.println("TDB2.init - start") ;
+
+            SystemTDB.init() ;
+            ARQ.init() ;
+            ReaderRIOTRDFXML.RiotUniformCompatibility = true ;
+            EnvTDB.processGlobalSystemProperties() ;
+
+            MappingRegistry.addPrefixMapping(SystemTDB.tdbSymbolPrefix, SystemTDB.symbolNamespace) ;
+            AssemblerUtils.init() ;
+            VocabTDB2.init() ;
+            QueryEngineTDB.register() ;
+            UpdateEngineTDB.register() ;
+            MappingRegistry.addPrefixMapping(TDB2.tdbSymbolPrefix, TDB2.tdbParamNS) ;
+
+            wireIntoExecution() ;
+            if ( JenaSystem.DEBUG_INIT )
+                System.err.println("TDB.init - finish") ;
+        }
+    }
+
+    private static void wireIntoExecution() {
+        // Globally change the stage generator to intercept BGP on TDB
+        // Globally change the stage generator to intercept BGP on TDB
+        Context cxt = ARQ.getContext() ;
+        StageGenerator orig = StageBuilder.chooseStageGenerator(cxt) ; 
+
+        // Wire in the TDB stage generator which will make TDB work whether
+        // or not the TDB executor is used. This means that datasets of mixed
+        // graph types inside a general purpose dataset work.
+        StageGenerator stageGenerator = new StageGeneratorDirectTDB(orig) ;
+        StageBuilder.setGenerator(ARQ.getContext(), stageGenerator) ;
+    }
+
+    // ---- Static constants read by modVersion
+    // ---- Must be after initialization.
+
+    static private String      metadataLocation = "org/apache/jena/tdb/tdb-properties.xml" ;
+    static private Metadata    metadata         = new Metadata(metadataLocation) ;
+
+    /** The root package name for TDB */
+    public static final String PATH             = "org.apache.jena.tdb" ;
+
+    // The names known to ModVersion : "NAME", "VERSION", "BUILD_DATE"
+
+    public static final String NAME             = "TDB" ;
+
+    /** The full name of the current TDB version */
+    public static final String VERSION          = metadata.get(PATH + ".version", "DEV") ;
+
+    /** The date and time at which this release was built */
+    public static final String BUILD_DATE       = metadata.get(PATH + ".build.datetime", "unset") ;
+
+    // Final initialization (in case any statics in this file are important).
+    static {
+        initialization2() ;
+    }
+
+    private static void initialization2() {
+        // Set management information.
+        SystemInfo systemInfo = new SystemInfo(TDB2.tdbIRI, TDB2.PATH, TDB2.VERSION, TDB2.BUILD_DATE) ;
+        SystemARQ.registerSubSystem(systemInfo) ;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/TDB2Factory.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/TDB2Factory.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/TDB2Factory.java
new file mode 100644
index 0000000..96d355e
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/TDB2Factory.java
@@ -0,0 +1,125 @@
+/*
+ * 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.seaborne.tdb2;
+
+import org.apache.jena.query.Dataset ;
+import org.apache.jena.query.DatasetFactory ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.seaborne.dboe.base.file.Location ;
+
+/**
+ *  Public factory for connecting to and creating datasets backed by TDB2 storage.
+ */
+public class TDB2Factory
+{
+    private TDB2Factory() {} 
+
+    /** @deprecated Use {@link DatabaseMgr#connectDatasetGraph(Location)} */
+    @Deprecated
+    public static DatasetGraph createDatasetGraph(Location location) {
+        return DatabaseMgr.connectDatasetGraph(location);
+    }
+    
+    /** @deprecated Use {@link #connectDataset(Location)} */
+    @Deprecated
+    public static Dataset createDataset(Location location) {
+        return connectDataset(location);
+    }
+    
+    /** Create or connect to a TDB2-backed dataset */
+    public static Dataset connectDataset(Location location) {
+        DatasetGraph dsg = DatabaseMgr.connectDatasetGraph(location) ;
+        return DatasetFactory.wrap(dsg) ;
+    }
+
+    /** @deprecated Use {@link DatabaseMgr#connectDatasetGraph(String)} */
+    @Deprecated
+    public static DatasetGraph createDatasetGraph(String location) {
+        return DatabaseMgr.connectDatasetGraph(location);
+    }
+    
+    /** @deprecated Use {@link #connectDataset(String)} */
+    @Deprecated
+    public static Dataset createDataset(String location) {
+        return connectDataset(location);
+    }
+    
+    /** Create or connect to a TDB2-backed dataset */
+    public static Dataset connectDataset(String location) {
+        return connectDataset(Location.create(location)) ;    }
+
+    /**
+     * Create an in-memory TDB2-backed dataset (for testing). In-memory TDB2 datasets are use
+     * a simple simulation of disk I/O to give exact semantics, which is useful to create
+     * tests that run fast where setup and teardown of datasets can be the major cost.
+     * <p> 
+     * In-memory TDB2 datasets are not designed to scale, nor provide efficient execution for
+     * applications for long-term use. 
+     */ 
+    public static Dataset createDataset() { return connectDataset(Location.mem()) ; }
+
+//    /**
+//     *  Read the file and assembler a dataset
+//     */
+//    public static Dataset assembleDataset(String assemblerFile) {
+//        return (Dataset)AssemblerUtils.build(assemblerFile, VocabTDB.tDatasetTDB) ;
+//    }
+//    
+//    /** Release from the JVM. All caching is lost. */
+//    public static void release(Dataset dataset) {
+//        _release(location(dataset)) ;
+//    }
+//    
+//    /** Release from the JVM.  All caching is lost. */
+//    public static void release(DatasetGraph dataset) {
+//        _release(location(dataset)) ;
+//    }
+
+    /** Tes whether a dataset is backed by TDB or not. */ 
+    public static boolean isBackedByTDB(Dataset dataset) {
+        DatasetGraph dsg = dataset.asDatasetGraph() ;
+        return DatabaseMgr.isBackedByTDB(dsg) ;
+    }
+    
+    /** Return the location of a dataset if it is backed by TDB, else null */
+    public static Location location(Dataset dataset) {
+        DatasetGraph dsg = dataset.asDatasetGraph() ;
+        return DatabaseMgr.location(dsg) ;
+    }
+
+//    /** Set the {@link StoreParams} for specific Location.
+//     *  This call must only be called before a dataset from Location
+//     *  is created. This operation should be used with care; bad choices
+//     *  of {@link StoreParams} can reduce performance.
+//     *  
+//     *  <a href="http://jena.apache.org/documentation/tdb/store-paramters.html"
+//     *  >See documentation</a>.
+//     *  
+//     *  @param location  The persistent storage location
+//     *  @param params  StoreParams to use
+//     *  @throws IllegalStateException If the dataset has already been setup.
+//     */
+//    public static void setup(Location location, StoreParams params) {
+//        StoreConnection sConn = StoreConnection.getExisting(location) ;
+//        if ( sConn != null )
+//            throw new IllegalStateException("Location is already active") ;
+//        StoreConnection.make(location, params) ;
+//    }
+    
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/TDBException.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/TDBException.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/TDBException.java
new file mode 100644
index 0000000..d6c6d4e
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/TDBException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.seaborne.tdb2;
+
+import org.apache.jena.shared.JenaException ;
+
+public class TDBException extends JenaException
+{
+    public TDBException()                          { super() ; }
+    public TDBException(String msg)                { super(msg) ; }
+    public TDBException(Throwable th)              { super(th) ; }
+    public TDBException(String msg, Throwable th)  { super(msg, th) ; }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/DatasetAssemblerTDB.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/DatasetAssemblerTDB.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/DatasetAssemblerTDB.java
new file mode 100644
index 0000000..223896d
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/DatasetAssemblerTDB.java
@@ -0,0 +1,80 @@
+/*
+ * 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.seaborne.tdb2.assembler;
+
+import static org.apache.jena.sparql.util.graph.GraphUtils.exactlyOneProperty ;
+import static org.apache.jena.sparql.util.graph.GraphUtils.getStringValue ;
+import static org.seaborne.tdb2.assembler.VocabTDB2.pLocation ;
+import static org.seaborne.tdb2.assembler.VocabTDB2.pUnionDefaultGraph ;
+
+import org.apache.jena.assembler.Assembler ;
+import org.apache.jena.assembler.Mode ;
+import org.apache.jena.assembler.exceptions.AssemblerException ;
+import org.apache.jena.atlas.logging.Log ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.query.Dataset ;
+import org.apache.jena.query.DatasetFactory ;
+import org.apache.jena.rdf.model.Resource ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.assembler.AssemblerUtils ;
+import org.apache.jena.sparql.core.assembler.DatasetAssembler ;
+import org.apache.jena.sparql.expr.NodeValue ;
+import org.apache.jena.system.JenaSystem ;
+import org.seaborne.dboe.base.file.Location ;
+import org.seaborne.tdb2.DatabaseMgr ;
+import org.seaborne.tdb2.TDB2 ;
+
+public class DatasetAssemblerTDB extends DatasetAssembler
+{
+    static { JenaSystem.init(); }
+    
+    @Override
+    public Dataset createDataset(Assembler a, Resource root, Mode mode) {
+        TDB2.init() ;
+        return make(root) ;
+    }
+
+    static Dataset make(Resource root) {
+        if ( !exactlyOneProperty(root, pLocation) )
+            throw new AssemblerException(root, "No location given") ;
+
+        String dir = getStringValue(root, pLocation) ;
+        Location loc = Location.create(dir) ;
+        DatasetGraph dsg = DatabaseMgr.connectDatasetGraph(loc) ;
+
+        if ( root.hasProperty(pUnionDefaultGraph) ) {
+            Node b = root.getProperty(pUnionDefaultGraph).getObject().asNode() ;
+            NodeValue nv = NodeValue.makeNode(b) ;
+            if ( nv.isBoolean() )
+                dsg.getContext().set(TDB2.symUnionDefaultGraph, nv.getBoolean()) ;
+            else
+                Log.warn(DatasetAssemblerTDB.class, "Failed to recognize value for union graph setting (ignored): " + b) ;
+        }
+
+        /*
+        <r> rdf:type tdb:DatasetTDB2 ;
+            tdb:location "dir" ;
+            //ja:context [ ja:cxtName "arq:queryTimeout" ;  ja:cxtValue "10000" ] ;
+            tdb:unionGraph true ; # or "true"
+        */
+        AssemblerUtils.setContext(root, dsg.getContext());
+        return DatasetFactory.wrap(dsg) ; 
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/TDBGraphAssembler.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/TDBGraphAssembler.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/TDBGraphAssembler.java
new file mode 100644
index 0000000..55fb944
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/TDBGraphAssembler.java
@@ -0,0 +1,125 @@
+/*
+ * 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.seaborne.tdb2.assembler;
+
+import static org.apache.jena.sparql.util.graph.GraphUtils.getAsStringValue ;
+import static org.apache.jena.sparql.util.graph.GraphUtils.getResourceValue ;
+import static org.apache.jena.sparql.util.graph.GraphUtils.getStringValue ;
+import static org.seaborne.tdb2.assembler.VocabTDB2.* ;
+
+import org.apache.jena.assembler.Assembler ;
+import org.apache.jena.assembler.Mode ;
+import org.apache.jena.assembler.assemblers.AssemblerBase ;
+import org.apache.jena.assembler.exceptions.AssemblerException ;
+import org.apache.jena.atlas.logging.Log ;
+import org.apache.jena.query.Dataset ;
+import org.apache.jena.rdf.model.* ;
+import org.apache.jena.riot.out.NodeFmtLib ;
+import org.seaborne.dboe.base.file.Location ;
+import org.seaborne.tdb2.TDB2 ;
+import org.seaborne.tdb2.TDBException ;
+import org.seaborne.tdb2.TDB2Factory ;
+
+public class TDBGraphAssembler extends AssemblerBase implements Assembler
+{
+    @Override
+    public Model open(Assembler a, Resource root, Mode mode)
+    {
+        // In case we go via explicit index construction,
+        // although given we got here, the assembler is wired in
+        // and that probably means TDB.init
+        TDB2.init() ;
+        
+        // Make a model - the default model of the TDB dataset
+        // [] rdf:type tdb:GraphTDB ;
+        //    tdb:location "dir" ;
+        
+        // Make a named model.
+        // [] rdf:type tdb:GraphTDB ;
+        //    tdb:location "dir" ;
+        //    tdb:graphName <http://example/name> ;
+
+        // Location or dataset reference.
+        String locationDir = getStringValue(root, pLocation) ;
+        Resource dataset = getResourceValue(root, pDataset) ;
+        
+        if ( locationDir != null && dataset != null )
+            throw new AssemblerException(root, "Both location and dataset given: exactly one required") ; 
+        
+        if ( locationDir == null && dataset == null )
+            throw new AssemblerException(root, "Must give location or refer to a dataset description") ;
+        
+        String graphName = null ;
+        if ( root.hasProperty(pGraphName1) )
+            graphName = getAsStringValue(root, pGraphName1) ;
+        if ( root.hasProperty(pGraphName2) )
+            graphName = getAsStringValue(root, pGraphName2) ;
+
+        if ( root.hasProperty(pIndex) )
+            Log.warn(this, "Custom indexes not implemented yet - ignored") ;
+
+        final Dataset ds ;
+        
+        if ( locationDir != null )
+        {
+            Location location = Location.create(locationDir) ;
+            ds = TDB2Factory.connectDataset(location) ;
+        }
+        else
+            ds = DatasetAssemblerTDB.make(dataset) ;
+
+        try {
+            if ( graphName != null )
+                return ds.getNamedModel(graphName) ;
+            else
+                return ds.getDefaultModel() ;
+        } catch (RuntimeException ex)
+        {
+            ex.printStackTrace(System.err) ;
+            throw ex ;
+        }
+    }
+    
+    //@Unused
+    private void indexes(Resource root)
+    {
+        // ---- API ways
+
+        StmtIterator sIter = root.listProperties(pIndex) ;
+        while(sIter.hasNext())
+        {
+            RDFNode obj = sIter.nextStatement().getObject() ;
+            if ( obj.isLiteral() )
+            {
+                String desc = ((Literal)obj).getString() ;
+                System.out.printf("Index: %s\n", desc) ; System.out.flush();
+                continue ;
+            }
+            throw new TDBException("Wrong format for tdb:index: should be a string: found: "+NodeFmtLib.displayStr(obj)) ; 
+            //          Resource x = (Resource)obj ;
+            //          String desc = x.getProperty(pDescription).getString() ;
+            //          String file = x.getProperty(pFile).getString() ;
+            //          System.out.printf("Index: %s in file %s\n", desc, file) ; System.out.flush();
+        }
+
+        System.out.flush();
+        throw new TDBException("Custom indexes turned off") ; 
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/Vocab.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/Vocab.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/Vocab.java
new file mode 100644
index 0000000..72b2326
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/Vocab.java
@@ -0,0 +1,37 @@
+/*
+ * 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.seaborne.tdb2.assembler ;
+
+import org.apache.jena.rdf.model.Property ;
+import org.apache.jena.rdf.model.Resource ;
+import org.apache.jena.rdf.model.ResourceFactory ;
+
+public class Vocab {
+    public static Resource type(String namespace, String localName) {
+        return ResourceFactory.createResource(namespace + localName) ;
+    }
+
+    public static Resource resource(String namespace, String localName) {
+        return ResourceFactory.createResource(namespace + localName) ;
+    }
+
+    public static Property property(String namespace, String localName) {
+        return ResourceFactory.createProperty(namespace + localName) ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/VocabTDB2.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/VocabTDB2.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/VocabTDB2.java
new file mode 100644
index 0000000..f44f034
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/assembler/VocabTDB2.java
@@ -0,0 +1,91 @@
+/*
+ * 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.seaborne.tdb2.assembler;
+
+
+import org.apache.jena.assembler.Assembler ;
+import org.apache.jena.assembler.ConstAssembler ;
+import org.apache.jena.assembler.JA ;
+import org.apache.jena.assembler.assemblers.AssemblerGroup ;
+import org.apache.jena.rdf.model.Property ;
+import org.apache.jena.rdf.model.Resource ;
+import org.apache.jena.sparql.core.assembler.AssemblerUtils ;
+import org.seaborne.tdb2.TDB2 ;
+
+public class VocabTDB2
+{
+    private static final String NS = TDB2.namespace ;
+    
+    public static String getURI() { return NS ; } 
+
+    // Types
+    public static final Resource tDatasetTDB        = Vocab.type(NS, "DatasetTDB2") ;
+    public static final Resource tDatasetTDB_alt    = Vocab.type(NS, "DatasetTDB") ;
+    public static final Resource tGraphTDB          = Vocab.type(NS, "GraphTDB2") ;
+    public static final Resource tGraphTDB_alt      = Vocab.type(NS, "GraphTDB") ;
+//    public static final Resource tTupleIndex        = Vocab.type(NS, "TupleIndex") ;
+    public static final Resource tNodeTable         = Vocab.type(NS, "NodeTable") ;
+
+    public static final Property pLocation          = Vocab.property(NS, "location") ;
+    public static final Property pUnionDefaultGraph = Vocab.property(NS, "unionDefaultGraph") ;
+    
+    public static final Property pIndex             = Vocab.property(NS, "index") ;
+    public static final Property pGraphName1        = Vocab.property(NS, "graphName") ;
+    public static final Property pGraphName2        = Vocab.property(NS, "namedGraph") ;
+    public static final Property pDataset           = Vocab.property(NS, "dataset") ;
+    
+    public static final Property pNodes             = Vocab.property(NS, "nodes") ;
+
+    // Indexes
+    public static final Property pDescription       = Vocab.property(getURI(), "description") ;
+    public static final Property pFile              = Vocab.property(getURI(), "file") ;
+
+    // Nodes
+    public static final Property pNodeIndex         = Vocab.property(getURI(), "nodeIndex") ;
+    public static final Property pNodeData          = Vocab.property(getURI(), "nodeData") ;
+    
+    // Setting
+    public static final Property pSetting           = Vocab.property(getURI(), "setting") ;
+    public static final Property pName              = Vocab.property(getURI(), "name") ;
+    public static final Property pValue             = Vocab.property(getURI(), "value") ;
+    
+    private static boolean initialized = false ; 
+    
+    static { init() ; }
+    
+    static synchronized public void init()
+    {
+        if ( initialized )
+            return ;
+        registerWith(Assembler.general) ;
+        initialized = true ;
+    }
+    
+    static void registerWith(AssemblerGroup g)
+    {
+        // Wire in the extension assemblers (extensions relative to the Jena assembler framework)
+        // Domain and range for properties.
+        // Separated and use ja:imports
+        AssemblerUtils.registerDataset(tDatasetTDB, new DatasetAssemblerTDB());
+        AssemblerUtils.registerDataset(tDatasetTDB_alt, new DatasetAssemblerTDB());
+        AssemblerUtils.register(ConstAssembler.general(), tGraphTDB, new TDBGraphAssembler(), JA.Model);
+        AssemblerUtils.register(ConstAssembler.general(), tGraphTDB_alt, new TDBGraphAssembler(), JA.Model);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/graph/TransactionHandlerTDB.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/graph/TransactionHandlerTDB.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/graph/TransactionHandlerTDB.java
new file mode 100644
index 0000000..88e064e
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/graph/TransactionHandlerTDB.java
@@ -0,0 +1,61 @@
+/*
+ * 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.seaborne.tdb2.graph;
+
+import org.apache.jena.graph.impl.TransactionHandlerBase ;
+import org.apache.jena.query.ReadWrite;
+import org.seaborne.dboe.transaction.txn.TransactionCoordinator;
+import org.seaborne.tdb2.store.DatasetGraphTDB;
+import org.seaborne.tdb2.store.GraphTDB ;
+
+public class TransactionHandlerTDB extends TransactionHandlerBase //implements TransactionHandler 
+{
+    private final GraphTDB graph ;
+    private final DatasetGraphTDB dsg;
+
+    public TransactionHandlerTDB(GraphTDB graph) {
+        this.graph = graph;
+        this.dsg = graph.getDSG();
+    }
+
+    @Override
+    public void abort() {
+        graph.getDSG().abort();
+        graph.getDSG().end();
+    }
+
+    @Override
+    public void begin() {
+        if ( TransactionCoordinator.promotion )
+            dsg.begin(ReadWrite.READ);
+        else
+            dsg.begin(ReadWrite.WRITE);
+    }
+
+    @Override
+    public void commit() {
+        dsg.commit();
+        dsg.end();
+    }
+
+    @Override
+    public boolean transactionsSupported() {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/lib/Async.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/lib/Async.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/lib/Async.java
new file mode 100644
index 0000000..cfb4976
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/lib/Async.java
@@ -0,0 +1,85 @@
+/*
+ * 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.seaborne.tdb2.lib;
+
+import java.util.concurrent.* ;
+
+import org.seaborne.tdb2.TDBException ;
+
+/** Asyncrhonous operations support
+ *  This class provides a simple framework for asynchronous operations.
+ *  There is a thread pool and a pending queue. 
+ *  <p>
+ *  Default settings are thread pool of one and at most two pending operations.
+ *  When a new async operation is added, the pending queue is checked, and the
+ *  call blocks until the pending queue is below the threashold.
+ *  <p>
+ *  With the default setting of a thread pool of one, operations are
+ *  executed in the order submitted.
+ *  <p>
+ *  If the far end is the bottleneck, a longer queeue is no help.
+ */
+public final class Async {
+    // Currently specific to ThriftRunnable
+    private static final int THREAD_POOL_SIZE = 1 ;
+    private static final int PENDING_MAX = 2 ;
+    private static final int BlockingQueueSize = PENDING_MAX+2 ;
+    
+    private final int pendingQueueLimit ;
+    private final int blockingQueueSize ;
+    private final ExecutorService executorService; 
+    private final BlockingQueue<Future<Void>> outstanding ; 
+    
+    public Async() {
+        this(THREAD_POOL_SIZE, PENDING_MAX) ;
+    }
+
+    public Async(int threadPoolSize, int pendingQueueLimit) {
+        this.pendingQueueLimit = pendingQueueLimit ;
+        this.blockingQueueSize = this.pendingQueueLimit+1 ;
+        this.executorService = Executors.newFixedThreadPool(threadPoolSize) ;
+        this.outstanding = new ArrayBlockingQueue<>(BlockingQueueSize) ;
+    }
+    
+    /** Block until all pending oeprations has been completed */
+    public void completeAsyncOperations() {
+        reduceAsyncQueue(0) ;
+    }
+    
+    /** Block until the pending operations queue is below the given size. */
+    public void reduceAsyncQueue(int reduceSize) {
+        System.out.println("Reduce: "+outstanding.size()) ;
+        while ( outstanding.size() > reduceSize ) {
+            try { outstanding.take().get() ; }
+            catch (Exception ex) {
+                throw new TDBException("Exception taking from async queue", ex) ;
+            } 
+        }
+    }
+    
+    public void execAsync(Object lock, Runnable action) {
+        reduceAsyncQueue(pendingQueueLimit) ;
+        Future<Void> task = executorService.submit(()-> {
+            try { action.run() ; } 
+            catch (Exception ex)    { throw new TDBException("Unexpected exception: "+ex.getMessage(), ex) ; }
+            return null ;
+        }) ;
+        outstanding.add(task) ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/lib/NodeLib.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/lib/NodeLib.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/lib/NodeLib.java
new file mode 100644
index 0000000..f7a563b
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/lib/NodeLib.java
@@ -0,0 +1,142 @@
+/*
+ * 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.seaborne.tdb2.lib;
+
+import static org.seaborne.tdb2.sys.SystemTDB.LenNodeHash;
+
+import java.security.DigestException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Iterator;
+
+import org.apache.jena.atlas.iterator.Iter;
+import org.apache.jena.atlas.lib.Bytes;
+import org.apache.jena.atlas.lib.Pool;
+import org.apache.jena.atlas.lib.PoolBase;
+import org.apache.jena.atlas.lib.PoolSync;
+import org.apache.jena.atlas.logging.Log;
+import org.apache.jena.graph.Node;
+import org.apache.jena.sparql.util.NodeUtils;
+import org.seaborne.dboe.base.record.Record;
+import org.seaborne.tdb2.TDBException;
+import org.seaborne.tdb2.store.Hash;
+import org.seaborne.tdb2.store.NodeId;
+import org.seaborne.tdb2.store.NodeIdFactory;
+import org.seaborne.tdb2.store.nodetable.NodeTable;
+
+public class NodeLib {
+    public static Hash hash(Node n) {
+        Hash h = new Hash(LenNodeHash);
+        setHash(h, n);
+        return h;
+    }
+
+    private static String BNODE   = "bnode";
+    private static String URI     = "uri";
+    private static String LITERAL = "literal";
+
+    public static void setHash(Hash h, Node n) {
+        if ( n.isURI() )
+            hash(h, n.getURI(), null, null, URI);
+        else if ( n.isBlank() )
+            hash(h, n.getBlankNodeLabel(), null, null, BNODE);
+        else if ( n.isLiteral() ) {
+            String dt = n.getLiteralDatatypeURI();
+            if ( NodeUtils.isSimpleString(n) || NodeUtils.isLangString(n) ) {
+                // RDF 1.1 : No datatype for:
+                // xsd:String as simple literals
+                // rdf:langString and @
+                dt = null;
+            }
+            hash(h, n.getLiteralLexicalForm(), n.getLiteralLanguage(), dt, LITERAL);
+        } else
+            throw new TDBException("Attempt to hash something strange: " + n);
+    }
+
+    private static int                 InitialPoolSize = 5;
+    private static Pool<MessageDigest> digesters       = PoolSync.create(new PoolBase<MessageDigest>());
+    static {
+        try {
+            for ( int i = 0 ; i < InitialPoolSize ; i++ )
+                digesters.put(MessageDigest.getInstance("MD5"));
+        }
+        catch (NoSuchAlgorithmException e) {
+            Log.warn(NodeLib.class, "NoSuchAlgorithmException", e);
+            throw new RuntimeException(e);  
+        }
+    }
+
+    private static MessageDigest allocDigest() {
+        try {
+            MessageDigest disgest = digesters.get();
+            if ( disgest == null )
+                disgest = MessageDigest.getInstance("MD5");
+            return disgest;
+        }
+        catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    private static void deallocDigest(MessageDigest digest) {
+        digest.reset();
+        digesters.put(digest);
+    }
+
+    private static void hash(Hash h, String lex, String lang, String datatype, String nodeName) {
+        if ( datatype == null )
+            datatype = "";
+        if ( lang == null )
+            lang = "";
+        String toHash = lex + "|" + lang + "|" + datatype + "|" + nodeName;
+        MessageDigest digest;
+        try {
+            // MessageDigest.getInstance("MD5");
+            digest = allocDigest();
+            digest.update(Bytes.string2bytes(toHash));
+            if ( h.getLen() == 16 ) {
+                // MD5 is 16 bytes.
+                digest.digest(h.getBytes(), 0, 16);
+            } else {
+                byte b[] = digest.digest(); // 16 bytes.
+                System.arraycopy(b, 0, h.getBytes(), 0, h.getLen());
+            }
+            deallocDigest(digest);
+            return;
+        }
+        catch (DigestException ex) {
+            Log.error(NodeLib.class, "DigestException", ex);
+        }
+    }
+
+    public static NodeId getNodeId(Record r, int idx) {
+        return NodeIdFactory.get(r.getKey(), idx);
+    }
+
+    public static Node termOrAny(Node node) {
+        if ( node == null || node.isVariable() )
+            return Node.ANY;
+        return node;
+    }
+
+    public static Iterator<Node> nodes(final NodeTable nodeTable, Iterator<NodeId> iter) {
+        return Iter.map(iter, nodeTable::getNodeForNodeId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/lib/TupleLib.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/lib/TupleLib.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/lib/TupleLib.java
new file mode 100644
index 0000000..2f67382
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/lib/TupleLib.java
@@ -0,0 +1,155 @@
+/*
+ * 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.seaborne.tdb2.lib;
+
+import java.util.Iterator ;
+
+import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.atlas.lib.InternalErrorException ;
+import org.apache.jena.atlas.lib.tuple.Tuple ;
+import org.apache.jena.atlas.lib.tuple.TupleFactory ;
+import org.apache.jena.atlas.lib.tuple.TupleMap ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.Triple ;
+import org.apache.jena.sparql.core.Quad ;
+import org.seaborne.dboe.base.record.Record ;
+import org.seaborne.dboe.base.record.RecordFactory ;
+import org.seaborne.tdb2.TDBException ;
+import org.seaborne.tdb2.store.NodeId ;
+import org.seaborne.tdb2.store.NodeIdFactory;
+import org.seaborne.tdb2.store.nodetable.NodeTable ;
+
+public class TupleLib
+{
+    public static Iterator<Tuple<Node>> convertToNodes(final NodeTable nodeTable, Iterator<Tuple<NodeId>> iter) {
+        return Iter.map(iter, item -> tupleNodes(nodeTable, item));
+    }
+
+    public static Iterator<Tuple<NodeId>> convertToNodeId(final NodeTable nodeTable, Iterator<Tuple<Node>> iter) {
+        return Iter.map(iter, item -> tupleNodeIds(nodeTable, item));
+    }
+
+    // Leave - bypasses extract step in Tuple<NodeId> -> Tuple<Node> -> Triple
+    public static Iterator<Triple> convertToTriples(final NodeTable nodeTable, Iterator<Tuple<NodeId>> iter) {
+        return Iter.map(iter, item -> triple(nodeTable, item));
+    }
+
+    public static Iterator<Quad> convertToQuads(final NodeTable nodeTable, Iterator<Tuple<NodeId>> iter) {
+        return Iter.map(iter, item -> quad(nodeTable, item));
+    }
+
+    public static Tuple<Node> tupleNodes(NodeTable nodeTable, Tuple<NodeId> ids) {
+        int N = ids.len();
+        Node[] n = new Node[N];
+        for ( int i = 0 ; i < N ; i++ )
+            n[i] = nodeTable.getNodeForNodeId(ids.get(i));
+        return TupleFactory.create(n);
+    }
+
+    public static Tuple<NodeId> tupleNodeIds(NodeTable nodeTable, Tuple<Node> nodes) {
+        int N = nodes.len();
+        NodeId[] n = new NodeId[N];
+        for ( int i = 0 ; i < N ; i++ )
+            n[i] = nodeTable.getNodeIdForNode(nodes.get(i));
+        return TupleFactory.create(n);
+    }
+    
+    private static Triple triple(NodeTable nodeTable, Tuple<NodeId> tuple) {
+        if ( tuple.len() != 3 )
+            throw new TDBException("Tuple is not of length 3: " + tuple);
+        return triple(nodeTable, tuple.get(0), tuple.get(1), tuple.get(2));
+    }
+
+    private static Triple triple(NodeTable nodeTable, NodeId s, NodeId p, NodeId o) {
+        if ( ! NodeId.isConcrete(s) )
+            throw new InternalErrorException("Invalid id for subject: "+fmt(s,p,o)) ;
+        if ( ! NodeId.isConcrete(p) )
+            throw new InternalErrorException("Invalid id for predicate: "+fmt(s,p,o)) ;
+        if ( ! NodeId.isConcrete(o) )
+            throw new InternalErrorException("Invalid id for object: "+fmt(s,p,o)) ;
+        
+        Node sNode = nodeTable.getNodeForNodeId(s) ;
+        if ( sNode == null )
+            throw new InternalErrorException("Invalid id node for subject (null node): "+fmt(s,p,o)) ;
+
+        Node pNode = nodeTable.getNodeForNodeId(p) ;
+        if ( pNode == null )
+        {
+            nodeTable.getNodeForNodeId(p) ;
+            throw new InternalErrorException("Invalid id node for predicate (null node): "+fmt(s,p,o)) ;
+        }
+        
+        Node oNode = nodeTable.getNodeForNodeId(o) ;
+        if ( oNode == null )
+            throw new InternalErrorException("Invalid id node for object (null node): "+fmt(s,p,o)) ;
+        
+        return new Triple(sNode, pNode, oNode) ;
+    }
+    
+    private static String fmt(NodeId s, NodeId p, NodeId o)
+    {
+        return "("+s+", "+p+", "+o+")" ;
+    }
+    
+    private static Quad quad(NodeTable nodeTable, Tuple<NodeId> tuple) 
+    {
+        if ( tuple.len() != 4 )
+            throw new TDBException("Tuple is not of length 4: "+tuple) ;
+        return quad(nodeTable, tuple.get(0), tuple.get(1), tuple.get(2), tuple.get(3)) ;
+    }
+    
+    private static Quad quad(NodeTable nodeTable, NodeId g, NodeId s, NodeId p, NodeId o) 
+    {
+        Node gNode = nodeTable.getNodeForNodeId(g) ;
+        Node sNode = nodeTable.getNodeForNodeId(s) ;
+        Node pNode = nodeTable.getNodeForNodeId(p) ;
+        Node oNode = nodeTable.getNodeForNodeId(o) ;
+        return new Quad(gNode, sNode, pNode, oNode) ;
+    }
+
+    // ---- Tuples and Records
+    public static Tuple<NodeId> tuple(Record r, TupleMap tMap) {
+        // Unmapping.
+        int N = r.getKey().length/NodeId.SIZE;
+        NodeId[] nodeIds = new NodeId[N] ;
+        for ( int i = 0 ; i < N ; i++ )
+        {
+            int j = i ;
+            if ( tMap != null )
+                j = tMap.unmapIdx(i) ;
+            NodeId id = NodeIdFactory.get(r.getKey(), j*NodeId.SIZE) ;
+            nodeIds[i] = id ;
+        }
+        return TupleFactory.create(nodeIds) ;
+    }
+
+
+    public static Record record(RecordFactory factory, Tuple<NodeId> tuple, TupleMap tMap) {
+        // Mapping.
+        byte[] b = new byte[tuple.len()*NodeId.SIZE] ;
+        for ( int i = 0 ; i < tuple.len() ; i++ )
+        {
+            int j = tMap.getSlotIdx(i) ;
+            // i'th Nodeid goes to j'th bytes slot.
+            NodeIdFactory.set(tuple.get(j), b, i*NodeId.SIZE) ;
+        }
+            
+        return factory.create(b) ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/loader/Loader.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/loader/Loader.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/loader/Loader.java
new file mode 100644
index 0000000..ac125b6
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/loader/Loader.java
@@ -0,0 +1,79 @@
+/*
+ * 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.seaborne.tdb2.loader;
+
+import org.apache.jena.atlas.lib.ProgressMonitor ;
+import org.apache.jena.atlas.logging.FmtLog ;
+import org.apache.jena.query.Dataset ;
+import org.apache.jena.riot.RDFDataMgr ;
+import org.apache.jena.riot.system.ProgressStreamRDF ;
+import org.apache.jena.riot.system.StreamRDF ;
+import org.apache.jena.riot.system.StreamRDFLib ;
+import org.seaborne.dboe.jenax.Txn ;
+import org.seaborne.tdb2.store.DatasetGraphTDB ;
+import org.slf4j.Logger ;
+import org.slf4j.LoggerFactory ;
+
+public class Loader {
+    
+    private static final int BATCH_SIZE = 100 ;
+    
+    // XXX StreamRDFBatchSplit and parallel index update.
+    private static Logger LOG = LoggerFactory.getLogger("Loader") ;
+    
+    public static void bulkLoad(Dataset ds, String ... files) {
+        DatasetGraphTDB dsg = (DatasetGraphTDB)ds.asDatasetGraph() ;
+        StreamRDF s1 = StreamRDFLib.dataset(dsg) ;
+        ProgressMonitor plog = ProgressMonitor.create(LOG, "Triples", 100000, 10) ;
+        ProgressStreamRDF sMonitor = new ProgressStreamRDF(s1, plog) ;
+        StreamRDF s3 = sMonitor ;
+
+        plog.start(); 
+        Txn.executeWrite(ds, () -> {
+            for ( String fn : files ) {
+                if ( files.length > 1 )
+                    FmtLog.info(LOG, "File: %s",fn);
+                RDFDataMgr.parse(s3, fn) ;
+            }
+        }) ;
+        plog.finish();
+        plog.finishMessage();
+    }
+    
+    public static void bulkLoadBatching(Dataset ds, String ... files) {
+        DatasetGraphTDB dsg = (DatasetGraphTDB)ds.asDatasetGraph() ;
+
+        StreamRDFBatchSplit s1 = new StreamRDFBatchSplit(dsg, 10) ;
+        ProgressMonitor plog = ProgressMonitor.create(LOG, "Triples", 100000, BATCH_SIZE) ;
+        // Want the monitor on the outside to capture transaction wrapper costs.
+        StreamRDF s3 = new ProgressStreamRDF(s1, plog) ;
+
+        plog.start(); 
+        Txn.executeWrite(ds, () -> {
+            for ( String fn : files ) {
+                if ( files.length > 1 )
+                    FmtLog.info(LOG, "File: %s",fn);
+                RDFDataMgr.parse(s3, fn) ;
+            }
+        }) ;
+        plog.finish();  
+        plog.finishMessage();
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/loader/StreamRDFBatchSplit.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/loader/StreamRDFBatchSplit.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/loader/StreamRDFBatchSplit.java
new file mode 100644
index 0000000..7778614
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/loader/StreamRDFBatchSplit.java
@@ -0,0 +1,225 @@
+/*
+ * 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.seaborne.tdb2.loader;
+
+import java.util.* ;
+import java.util.stream.Collectors ;
+
+import org.apache.jena.atlas.lib.tuple.Tuple ;
+import org.apache.jena.atlas.lib.tuple.TupleFactory ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.Triple ;
+import org.apache.jena.riot.other.BatchedStreamRDF ;
+import org.apache.jena.riot.system.StreamRDF ;
+import org.apache.jena.sparql.core.Quad ;
+import org.seaborne.dboe.transaction.txn.Transaction ;
+import org.seaborne.tdb2.TDBException ;
+import org.seaborne.tdb2.setup.TDBDatasetDetails ;
+import org.seaborne.tdb2.store.DatasetGraphTDB ;
+import org.seaborne.tdb2.store.NodeId ;
+import org.seaborne.tdb2.store.NodeIdFactory;
+import org.seaborne.tdb2.store.nodetable.NodeTable ;
+import org.seaborne.tdb2.store.tupletable.TupleTable ;
+import org.slf4j.Logger ;
+import org.slf4j.LoggerFactory ;
+
+/**
+ * @see BatchedStreamRDF BatchedStreamRDF, which batches by subject
+ */
+public class StreamRDFBatchSplit implements StreamRDF {
+    // Need to handle transactions?
+    // Lizard des (TxnClient) 
+    
+    private static Logger log = LoggerFactory.getLogger(StreamRDFBatchSplit.class) ;
+    protected static NodeId placeholder = NodeIdFactory.genUnique();
+    protected final List<Triple> triples ;
+    protected final List<Tuple<NodeId>> tuples ;
+    protected final Map<Node, NodeId> mapping ;
+    
+    private final int batchSize ;
+    private final TDBDatasetDetails details ;
+    private final DatasetGraphTDB dsg ;
+    private Transaction txn = null ;
+    
+    public StreamRDFBatchSplit(DatasetGraphTDB dsg, int batchSize) {
+        this.dsg = dsg ;
+        this.batchSize = batchSize ;
+        this.triples = new ArrayList<>(batchSize) ;
+        this.tuples = new ArrayList<>(triples.size()) ;
+        this.mapping = new HashMap<>(2*batchSize) ;
+        this.details = new TDBDatasetDetails(dsg) ;
+    }
+        
+    @Override
+    public void start() {
+        log.info("Batch size: "+batchSize);
+        // Multiple starts in one trnasaciton are possible.
+        if ( txn == null )
+            txn = dsg.getTxnSystem().getThreadTransaction() ;
+        if ( txn == null )
+            throw new TDBException("Not in a transaction") ;
+    }
+
+    @Override
+    public void triple(Triple triple) {
+        //Find nodes.
+        //log.info("Triple: "+triple) ;
+        processNode(triple.getSubject()) ;
+        processNode(triple.getPredicate()) ;
+        processNode(triple.getObject()) ;
+        triples.add(triple) ;
+        if ( triples.size() >= batchSize )
+            processBatch() ;
+    }
+
+    int batchNumber = 0 ;
+    
+    protected void processBatch() {
+        //if ( batchNumber < 10 )
+        batchNumber++ ;
+        //FmtLog.info(log, ">>processBatch: [%d]->%d", batchNumber, triples.size()) ;
+
+        Set<Node> requiredNodes = mapping.keySet() ;
+
+        boolean executeBatchNodesPhase = true ;
+        boolean executeIndexPhase = true ;
+        // Derived control.
+        boolean batchUpdateIndexes = true ;
+        
+        if ( executeBatchNodesPhase )
+            // Check this is a cache node table.
+            batchUpdateNodes(requiredNodes, details) ;
+        
+        if ( executeIndexPhase ) {
+            if ( batchUpdateIndexes )
+                batchUpdateIndexes(dsg, details, triples, /*tuples*/null) ;
+            else
+                incrementalUpdateIndexes(triples, dsg) ;
+        }
+        triples.clear();
+        tuples.clear() ;
+        //FmtLog.info(log, "<<processBatch") ;
+        mapping.clear();
+//        if ( batchSize < 10 )
+//            System.exit(0) ;
+    }
+   
+    private static void incrementalUpdateIndexes(List<Triple> triples, DatasetGraphTDB dsg) {
+        for ( Triple triple : triples ) {
+            dsg.getTripleTable().add(triple); 
+        }
+    }
+
+    /** This files the cache so that the tuples adds are faster */ 
+    private static void batchUpdateNodes(Set<Node> required, TDBDatasetDetails details) {
+        List<Node> nodes = new ArrayList<>() ;
+        // Resolve NodeIds
+        
+        // ** Move this into cache - code. 
+        
+        for ( Node n : required ) {
+            // 
+            if ( details.ntCache.getNodeIdForNodeCache(n) == null /* set input - no need :: && ! nodes.contains(n) /* Not good?*/ )
+                nodes.add(n) ;
+        }
+        //log.info("Batch nodes: "+nodes.size()) ;
+        // This drops into the default method.
+        details.ntTop.bulkNodeToNodeId(nodes, true) ;
+        
+        // Check
+        // Resolve NodeIds
+        for ( Node n : required ) {
+            if ( details.ntCache.getNodeIdForNodeCache(n) == null  )
+                log.info("Not in cache: "+n) ;
+        }
+        //details.ntCluster.bulkNodeToNodeId(nodes, true) ;
+        
+        
+        
+    }
+
+    private static void batchUpdateIndexes(DatasetGraphTDB dsg, TDBDatasetDetails details, List<Triple> batchTriples, List<Tuple<NodeId>> workspace) {
+        List<Tuple<NodeId>> tuples = workspace ;
+        if ( tuples == null )
+            tuples = new ArrayList<>(batchTriples.size()) ;
+
+        convert(batchTriples, tuples, details.ntTop) ;
+        //log.info("Batch triples: "+tuples.size()) ;
+
+        TupleTable tupleTable = dsg.getTripleTable().getNodeTupleTable().getTupleTable() ;
+        tupleTable.addAll(tuples);
+    }
+
+    // check for duplicate code
+    private static List<Tuple<NodeId>> convert(List<Triple> triples, NodeTable nodeTable) {
+        return triples.stream().map(t -> TupleFactory.tuple(nodeTable.getAllocateNodeId(t.getSubject()),
+                                                            nodeTable.getAllocateNodeId(t.getPredicate()),
+                                                            nodeTable.getAllocateNodeId(t.getObject())))
+            .collect(Collectors.toList());
+    }
+    
+    private static void convert(List<Triple> triples, List<Tuple<NodeId>> tuples, NodeTable nodeTable) {
+        // Slightly faster.  But larger batches?
+        for ( Triple t : triples ) {
+            NodeId nid_s = nodeTable.getAllocateNodeId(t.getSubject()) ;
+            NodeId nid_p = nodeTable.getAllocateNodeId(t.getPredicate()) ;
+            NodeId nid_o = nodeTable.getAllocateNodeId(t.getObject()) ;
+            Tuple<NodeId> x = TupleFactory.tuple(nid_s, nid_p, nid_o) ;
+            tuples.add(x) ;
+        }
+        
+//        triples.stream().map(t->
+//                  TupleFactory.tuple
+//                  (nodeTable.getAllocateNodeId(t.getSubject()),
+//                   nodeTable.getAllocateNodeId(t.getPredicate()),
+//                   nodeTable.getAllocateNodeId(t.getObject())))
+//                .collect(Collectors.toCollection(()->tuples)) ;
+    }
+    
+    
+    private void processNode(Node node) {
+        
+        if ( mapping.containsKey(node)) 
+            return ;
+        
+        if ( NodeId.hasInlineDatatype(node) ) {
+            NodeId nodeId = NodeId.inline(node) ;
+            if ( nodeId != null )
+                return ;
+        }
+        mapping.put(node, placeholder) ;
+    }
+    
+    @Override
+    public void quad(Quad quad) {}
+
+    @Override
+    public void base(String base) {}
+
+    @Override
+    public void prefix(String prefix, String iri) {}
+
+    @Override
+    public void finish() { 
+        if ( ! triples.isEmpty() )
+            processBatch() ;
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/migrate/A2.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/migrate/A2.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/migrate/A2.java
new file mode 100644
index 0000000..0a80ee1
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/migrate/A2.java
@@ -0,0 +1,38 @@
+/*
+ * 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.seaborne.tdb2.migrate;
+
+import org.apache.jena.sparql.algebra.Op ;
+import org.apache.jena.sparql.algebra.Transform ;
+import org.apache.jena.sparql.algebra.Transformer ;
+import org.apache.jena.sparql.core.Quad ;
+
+public class A2
+{
+    /** Convert a pattern, assumed to be quad form, 
+     * so that the default graph is the union of named graphs.  
+     */
+    public static Op unionDefaultGraphQuads(Op op)
+    {
+        // Rewrite so that any explicitly named "default graph" is union graph.
+        Transform t = new TransformGraphRename(Quad.defaultGraphNodeGenerated, Quad.unionGraph)  ;
+        op = Transformer.transform(t, op) ;
+        return op ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1dabea3a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/migrate/TransformGraphRename.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/migrate/TransformGraphRename.java b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/migrate/TransformGraphRename.java
new file mode 100644
index 0000000..402b130
--- /dev/null
+++ b/jena-db/jena-tdb2/src/main/java/org/seaborne/tdb2/migrate/TransformGraphRename.java
@@ -0,0 +1,54 @@
+/*
+ * 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.seaborne.tdb2.migrate;
+
+import org.apache.jena.graph.Node ;
+import org.apache.jena.sparql.algebra.Op ;
+import org.apache.jena.sparql.algebra.TransformCopy ;
+import org.apache.jena.sparql.algebra.op.OpGraph ;
+import org.apache.jena.sparql.algebra.op.OpQuadPattern ;
+
+public class TransformGraphRename extends TransformCopy
+{ 
+    private Node oldGraphName ;
+    private Node newGraphName ;
+
+    public TransformGraphRename(Node oldGraphName, Node newGraphName)
+    {
+        this.oldGraphName = oldGraphName ;
+        this.newGraphName = newGraphName ;
+    }
+
+    // Does not affect variables.
+    @Override
+    public Op transform(OpGraph opGraph, Op x)
+    { 
+        if ( opGraph.getNode().equals(oldGraphName) )
+            opGraph = new OpGraph(newGraphName, x) ;
+        return super.transform(opGraph, x) ;
+    }
+
+    @Override
+    public Op transform(OpQuadPattern opQuadPattern)
+    {
+        if ( opQuadPattern.getGraphNode().equals(oldGraphName) )
+            opQuadPattern = new OpQuadPattern(newGraphName, opQuadPattern.getBasicPattern()) ;
+        return super.transform(opQuadPattern) ;
+    }
+}


Mime
View raw message