[Mulgara-general] Mulgara API's

Alex Hall alexhall at revelytix.com
Fri Feb 22 21:51:50 UTC 2008


Paul Gearon wrote:
> The client side stuff has been
> updated to allow you to use any URI you like for a model name.
> ItqlInterpreterBean will still try to use the protocol and authority
> to find a server, but that is for backward compatibility.  If you use
> the API, then the following nearly works:
> 
> // get a connection
> ConnectionFactory factory = new ConnectionFactory();
> Connection conn = factory.newConnection("rmi://localhost/server1");
> 
> // set up the commands
> URI model = URI.create("foo:bar:baz");
> Command create = new CreateGraph(model, MODEL_TYPE);
> Command load = new Load(dataFile.toURI(), model, false);
> Command query = new TqlInterpreter().parseCommand("select $s $p $o
> from <" + model + "> where $s $p $o;");
> 
> // execute the commands
> create.execute(conn);
> load.execute(conn);
> Answer a = (Answer)query.execute(conn);
> 
> 
>>From a client perspective, this all works perfectly.  However, at the
> server end, the CreateModelOperation class checks if the model has a
> fragment, and fails at this point.  This appears to be a bug, as
> opaque URIs are handled elsewhere in the class.  I want to test that
> it works properly with resolvers, but I ought to be able to fix this
> very soon, and the above code will work.

That's certainly a step in the right direction.  I remember a big 
concern from a couple of years ago being that if you referenced model 
URI's from client code, other models, etc. then those references would 
no longer work if you moved the server to a new location.  Now you only 
have to remember the location in one place, where you create the 
connection, and the rest of your code can be blissfully unaware of where 
the server is actually running.  The next question is, how to get the 
following code working:

// set up connections
ConnectionFactory factory = new ConnectionFactory();
Connection conn1 = factory.newConnection("rmi://localhost/server1");
Connection conn2 = factory.newConnection("rmi://remotehost/server1");

// set up commands
URI model1 = URI.create("foo:bar");
URI model2 = URI.create("bar:baz");
Command create1 = new CreateGraph(model1, MODEL_TYPE);
Command create2 = new CreateGraph(model2, MODEL_TYPE);
Command load1 = new Load(dataFile1.toURI(), model, false);
Command load2 = new Load(dataFile2.toURI(), model, false);
Command query = new TqlInterpreter().parseCommand("select $s $p $o
from <" + model1 + "> where $s $p $o and $s <rdf:type> <foo> in " + 
model2 + ";");

// execute the commands
create1.execute(conn1);
load1.execute(conn1);
create2.execute(conn2);
load2.execute(conn2);
Answer a = (Answer)query.execute(conn1);

What I'm guessing will happen right now is that server1 will not 
recognize "bar:baz" as an internal model, and will pass the second 
constraint to the remote resolver, which will try to use the protocol 
and authority to locate the remote server.  Since this particular URI 
doesn't have those parts, it will not be able to resolve that 
constraint.  You would need some sort of directory service or other 
discovery mechanism to answer that query.

>>  > For backward compatibility, the ItqlInterpreterBean is still there,
>>  > but now it works differently.  Now it parses a query into a command.
>>  > If the command is something that is to operate on a remote server,
>>  > then it interrogates the command for the URLs of the graphs it refers
>>  > to.  It then establishes new connections (caching old ones for the
>>  > current ItqlInterpreterBean) as needed, and issues commands on these.
>>  > If it is in a transaction, then any new connections are put into that
>>  > transaction as well.  When a transaction completes, then all servers
>>  > that have been spoken to during that transaction are informed that the
>>  > transaction is complete.  The whole thing performs faster, more
>>  > efficiently, and has greater functionality than the previous
>>  > ItqlInterpreterBean.
>>
>>  If I'm following you correctly, this means that processing a single user
>>  command can result in the ItqlInterpreterBean coordinating commands
>>  across connections to multiple servers.  If that's the case, that seems
>>  like a bit too much logic to have on the client side.  Am I missing
>>  something here?
> 
> For client *code* it is certainly more logic than you want.  But as
> soon as I have SPARQL going I'll be documenting how everyone should be
> moving to using Connections anyway.  Client code should thereafter
> stay away from ItqlInterpreterBean.  This complexity is really to
> support the command prompt, which will not be going away.  In the
> meantime, it also provides ItqlInterpreterBean functionality to make
> it easier to transition.

I think I'm beginning to understand.  It sounds to me like the main 
difference is that now each command is responsible for determining the 
remote URL for any models that it references.  Rather than attempting to 
maintain the session state from one command to the next, 
ItqlInterpreterBean now relies on the command to find the connection 
information.  So if I issue the iTQL command

"create <rmi://localhost/server1#MyModel>;"

Then the Create command will examine the URI and determine that this 
command is for rmi://localhost/server1.  But if I say

"create <foo:bar:MyModel>;"

then the Create command will not be able to determine a server URL based 
on the model URI, and the ItqlInterpreterBean will not be able to 
execute the command.  Whereas if I was using the Connections API 
programmatically, I would be able to execute that command on an existing 
connection with no problem.

I think that for further enlightenment on this topic, I'll have to refer 
to the code, but I certainly appreciate the nudge in the right direction.

Regards,
Alex



More information about the Mulgara-general mailing list