Virtual Graphs

From Developer Documents
Jump to: navigation, search

Intro

The Simantics database client allows for defining memory-based and disk-based graph fragments which are applied on top of the server-based semantic graph.

A reading user perceives the combined model and the virtual graph information can be specifically queried if necessary.

A modifying user needs to specify in which virtual graph the modifications are made.

Virtual graphs are manipulated via the following interfaces

  • org.simantics.db.service.VirtualGraphSupport, for management
  • org.simantics.db.request.WriteTraits, for identifying the graph to write into

Specification

A write request has a single graph into which it writes. This is determined by WriteTraits and usually as a parameter to WriteRequest. If null is provided, the client applies modifications into the persistent graph. The following rules apply:

  • New resources are created into the given virtual graph
  • Claim statements are added into the given virtual graph
  • Value changes are applied into the given virtual graph
  • When the virtual graph provided to the WriteRequest is:
    • null:
      • For denied statements the location of the statement is determined and the statement is removed from that virtual graph. If the denied statement is not a part of any virtual graph, it is removed from the persistent graph.
    • non-null:
      • Statements are only removed from the virtual graph specified for the write request

The user can perform modifications into multiple virtual graphs within a single transaction. This is accomplished by issuing a new synchronous modification (WriteGraph.sync) into a new virtual graph.

Examples

The following code examples show in practice how to write into virtual graphs, both memory- and disk-based. Writing to several virtual graphs within the same write transaction is also demonstrated.

package org.simantics.db.tests.api.support.virtualGraphSupport;
 
import org.simantics.db.ReadGraph;
import org.simantics.db.RequestProcessor;
import org.simantics.db.Resource;
import org.simantics.db.Session;
import org.simantics.db.Statement;
import org.simantics.db.VirtualGraph;
import org.simantics.db.WriteGraph;
import org.simantics.db.common.request.ReadRequest;
import org.simantics.db.common.request.WriteRequest;
import org.simantics.db.common.request.WriteResultRequest;
import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.service.VirtualGraphSupport;
import org.simantics.layer0.Layer0;
 
public class VirtualGraphExample {
 
    public Resource createLibrary(RequestProcessor processor, VirtualGraph vg, final String libraryName)
            throws DatabaseException {
        return processor.syncRequest(new WriteResultRequest<Resource>(vg) {
            @Override
            public Resource perform(WriteGraph graph) throws DatabaseException {
                Layer0 L0 = Layer0.getInstance(graph);
                Resource r = graph.newResource();
                graph.claim(r, L0.InstanceOf, null, L0.Library);
                graph.claimLiteral(r, L0.HasName, libraryName);
                return r;
            }
        });
    }
 
    public void testVirtualGraphs(Session session) throws DatabaseException {
        VirtualGraphSupport vgSupport = session.getService(VirtualGraphSupport.class);
        VirtualGraph memory = vgSupport.getMemoryPersistent("memory");
        VirtualGraph workspace = vgSupport.getWorkspacePersistent("workspace");
        // NOTICE: resource are created in difference virtual graphs in separate
        // transactions through Session.syncRequest.
        Resource memResource = createLibrary(session, memory, "memory");
        Resource workspaceResource = createLibrary(session, workspace, "workspace");
        printVirtualGraphs(session);
    }
 
    public void testMultipleVirtualGraphsInSameTransaction(Session session) throws DatabaseException {
        final VirtualGraphSupport vgSupport = session.getService(VirtualGraphSupport.class);
        session.syncRequest(new WriteRequest() {
            @Override
            public void perform(WriteGraph graph) throws DatabaseException {
                VirtualGraph memory = vgSupport.getMemoryPersistent("memory");
                VirtualGraph workspace = vgSupport.getWorkspacePersistent("workspace");
                // NOTICE: resource are created in different virtual graphs in
                // the same transaction through WriteGraph.syncRequest
                Resource memResource = createLibrary(graph, memory, "memory");
                Resource workspaceResource = createLibrary(graph, workspace, "workspace");
            }
        });
        printVirtualGraphs(session);
    }
 
    public void printVirtualGraphs(Session session) throws DatabaseException {
        session.syncRequest(new ReadRequest() {
            @Override
            public void run(ReadGraph graph) throws DatabaseException {
                VirtualGraphSupport vgSupport = graph.getService(VirtualGraphSupport.class);
                for (VirtualGraph vg : vgSupport.listGraphs()) {
                    for (Statement stm : vgSupport.listStatements(vg)) {
                        System.out.println("Statement: " + NameUtils.toString(graph, stm));
                    }
                    for (Resource r : vgSupport.listValues(vg)) {
                        System.out.println("Literal value: " + graph.getValue(r));
                    }
                }
            }
        });
    }
 
}

Debugging

The standard Simantics Graph Debugger view shows for every statement which virtual graph it belongs to. This information is visible on the Graph column of the statement table. The Graph column will show:

DB
when the statement is in the persistent graph
'name' (W)
when the statement is in a named workspace-persistent virtual graph
'name' (M)
when the statement is in a named memory-persistent (transient) virtual graph
Graph debugger example with statements in virtual graphs.