Project

General

Profile

UserAPI » History » Version 8

Alex Hall -, 05/23/2008 07:23 PM

1 1 Paula Gearon
2 8 Alex Hall -
h1. Connection API =
3
 Overview ==
4
Mulgara now supports a new interface called a @Connection@. This will be replacing the current @ItqlInterpreterBean@ interface as the full suite of utilities becomes available.
5 1 Paula Gearon
6 8 Alex Hall -
The existing @ItqlInterpreterBean@ interface provides a completely automated connection mechanism, based on the URLs of graphs referenced in TQL queries. While convenient, this has several undesirable effects:
7 1 Paula Gearon
8 8 Alex Hall -
* All queries issued to this interface must contain at least one URL for a graph on the server that will handle the query.
9
* Arbitrary graph names are not permitted. Graph names must follow a particular format, and will include the hostname of the server containing the graph.
10
* Queries against graphs must be changed when the server hosting the graph changes.
11
* Connections to a server cannot be cached.
12
* Distributed queries (queries where the requested data comes from more than one server) are sent to an arbitrary server and not necessarily the most desirable one.
13
* Query languages which use a default graph name (like "SPARQL":http://www.w3.org/TR/rdf-sparql-query/) cannot identify a server if no graph names are given.
14 1 Paula Gearon
15 8 Alex Hall -
The @Connection@ interface avoids these issues by establishing a link to a specified server. This link can be to a server running in the current process, over inter-process-communication (IPC) to a server running on the same machine, or across a network. Queries and commands can be sent along this link, and all operations will be performed by the server that has been connected to.
16 1 Paula Gearon
17 8 Alex Hall -
The @Connection@ interface and its supporting classes are found in the @org.mulgara.connection@ package.
18 1 Paula Gearon
19
20 8 Alex Hall -
h2. Connection Factory
21 1 Paula Gearon
22 8 Alex Hall -
While Connections can be created directly, the @ConnectionFactory@ class attempts to manage connections to ensure that the correct type is created, and reduce network overhead. The connections returned by a @ConnectionFactory@ are only managed by that factory, and will not interfere with connections from a separate factory instance.
23 1 Paula Gearon
24 8 Alex Hall -
@Connection@s can be established based on the URL of a database (in the form _protocol_://_host_/_service_) or by wrapping a @Session@ instance. The @Session@ interface has existed in Mulgara for some time, and it may be more appropriate for existing code to use its internal @Session@ instances to create new @Connection@s.
25 7 Alex Hall -
26 8 Alex Hall -
When the @ConnectionFactory@ is used to obtain a connection based on the database URL, the factory will first check to see if it has previously established a @Connection@ to that database.  If it has, and the connection is no longer in use, then it will try to re-use the resources associated with that previous connection that are cached in the factory.  This will avoid setting up a new remote session with the database, which in turn should reduce network overhead.  The @ConnectionFactory@ is designed to support concurrent access by multiple clients in different threads; if two clients simultaneously get @Connection@s to the same database, the @Connection@s they receive will be distinct and commands issued on one will not interfere with commands issued on the other.  Note, however, that the @Connection@ itself is not designed for concurrent access.
27 1 Paula Gearon
28 8 Alex Hall -
When the @ConnectionFactory@ is used to obtain a connection based on an existing @Session@ instance, no caching is performed.  It is assumed that the user will take responsibility for managing their own @Session@s since they are using a lower-level API.
29
30
For the moment, the only supported protocol is _rmi_. Other protocols, including _http_ are expected shortly.
31
32
33
h2. Using a Connection ==
34
 Commands ===
35
Once a @Connection@ has been created, commands can be sent on it using the @execute@ method. Alternatively, commands also have their own @execute@ method that can be applied to a connection, with the same effect.
36
37 1 Paula Gearon
The following is an example of using a Connection to create a graph, and load a file into that graph:
38 8 Alex Hall -
<pre>
39
<code class="java">
40 1 Paula Gearon
    // define the server we want to connect to
41
    URI serverURI = new URI("rmi://localhost/server1");
42
    // define the file we want to load
43
    URI dataFile = new File("data.rdf").toURI();
44
    // define the name of the graph to load the data into
45
    URI myData = new URI("test:data");
46
47
    // Create a factory, and connect to the server
48 8 Alex Hall -
    [[ConnectionFactory]] factory = new [[ConnectionFactory]]();
49 1 Paula Gearon
    Connection connection = factory.newConnection(serverUri);
50
51
    // execute a CREATE command
52 8 Alex Hall -
    connection.execute(new [[CreateGraph]](myData));
53 2 Paula Gearon
    // execute a LOAD command
54
    connection.execute(new Load(dataFile, myData, true));
55
56 1 Paula Gearon
    // cleaning up the connection allows the network resources to be re-used
57 2 Paula Gearon
    connection.close();
58 8 Alex Hall -
</code></pre>
59 1 Paula Gearon
60 8 Alex Hall -
Executing a command returns a String containing a message related to the success of the command. If commands are kept, then it is also possible to retrieve the last message from a command with the @getResultMessage@ method.
61 1 Paula Gearon
62 8 Alex Hall -
63
h3. Queries
64
65
Queries are a type of command that return an @Answer@ instead of a message string. Queries can be created using either the TQL or SPARQL parsers:
66
<pre>
67
<code class="java">
68 2 Paula Gearon
    // define the server we want to connect to
69
    URI serverURI = new URI("rmi://localhost/server1");
70 1 Paula Gearon
71
    // Create a factory, and connect to the server
72 8 Alex Hall -
    [[ConnectionFactory]] factory = new [[ConnectionFactory]]();
73 3 Paula Gearon
    Connection connection = factory.newConnection(serverUri);
74
75 2 Paula Gearon
    // Use a SPARQL query
76 8 Alex Hall -
    Query query = new [[SparqlInterpreter]]().parseQuery(
77 2 Paula Gearon
                  "SELECT * FROM <test:data> WHERE { ?s ?p ?o }");
78
    Answer answer = connection.execute(query);
79
80
    // display the result
81
    answer.beforeFirst();
82
    while (answer.next()) {
83
      System.out.print(" " + answer.getObject(0));
84
      System.out.print(" " + answer.getObject(1));
85 1 Paula Gearon
      System.out.println(" " + answer.getObject(2));
86
    }
87 6 Paula Gearon
    answer.close();
88
89
    connection.close();
90 8 Alex Hall -
</code></pre>
91 7 Alex Hall -
92 1 Paula Gearon
A working example program for issuing SPARQL queries is provided with the source code. It can be found on the following path:
93 8 Alex Hall -
  "tools/src/org/mulgara/tools/Sparql.java":http://mulgara.org/svn/mulgara/tags/release-2.0-alpha-final/tools/src/org/mulgara/tools/Sparql.java
94 7 Alex Hall -
95
96 8 Alex Hall -
h3. Closing Connections
97 7 Alex Hall -
98 8 Alex Hall -
When a @Connection@ is no longer in use, it should be either closed or disposed in order to release the resources.  Close a connection that was obtained from a @ConnectionFactory@ using the database URL by calling the @Connection.close()@ method.  This will release the resources associated with the connection back to the factory, where they may be re-used for subsequent connections.  If a connection was obtained based on an existing @Session@ or was created directly (not using the factory) then close it by calling the @Connection.dispose()@ method.  This will destroy the underlying resources for that connection, both in the local process and in the remote database, including the @Session@ itself.  Once @close()@ or @dispose()@ has been called on a @Connection@ and further attempts to execute commands or queries on that connection will cause an exception to be thrown.  Some care should be taken when using the @Connection.close()@ method; if autocommit is turned off on a connection when the connection is closed (but not disposed) then the write-lock will not be released and any modifications made on that connection will remain uncommitted.  Also, authentication credentials are stored in the @Session@ that backs a @Connection@, so if you are using a @ConnectionFactory@ in a multi-user environment then you should use the @dispose()@ method to ensure that credentials are not shared between users.
99
100
Finally, the @ConnectionFactory@ provides a @closeAll()@ method that disposes of all resources associated with the factory.  Exercise caution when using this method, as it will dispose of both cached resources and any resources which might still be in use by active connections created by the factory.  This method is intended to be used when an application is shutting down and releasing all of its resources.
101
102
<pre>
103
<code class="java">
104 7 Alex Hall -
    // define the server we want to connect to
105
    URI serverURI = new URI("rmi://localhost/server1");
106
107
    // Create a SPARQL query
108 8 Alex Hall -
    Query query = new [[SparqlInterpreter]]().parseQuery(
109 7 Alex Hall -
                  "SELECT * FROM <test:data> WHERE { ?s ?p ?o }");
110
111
    // Create a factory, and connect to the server
112 8 Alex Hall -
    [[ConnectionFactory]] factory = new [[ConnectionFactory]]();
113 7 Alex Hall -
    Connection connection1 = factory.newConnection(serverUri);
114
115
    // This query will execute successfully.
116
    connection1.execute(query);
117
118
    // Return the session for this connection to the factory for re-use
119
    connection1.close();
120
121
    // This call will throw an exception since the connection was closed
122
    connection1.execute(query);
123
124
    // The previous connection was closed, so this will re-use the cached session
125
    Connection connection2 = factory.newConnection(serverUri);
126
127
    // connection2 is still in use, so this will cause a new session to be created
128
    Connection connection3 = factory.newConnection(serverUri);
129
130
    // This will close the session for this connection; it will not be re-used
131 1 Paula Gearon
    connection2.dispose();
132
133
    // Clears the cache and closes the session for connection3
134
    factory.closeAll();
135 8 Alex Hall -
</code></pre>