SPARQL-Gremlin: REST - sparql

I am currently using the following plugin for Gremlin: GitHub -- It basically converts SPARQL to Gremlin. It works perfectly fine in the console but I am trying to execute commands via REST.
Is there a workaround when prepending a command with ":>" via REST?
Gremlin Console:
gremlin> :> SELECT * WHERE { }
==> ...
==> ...
.
.
.
Gremlin REST:
POST
{"gremlin": ":> SELECT * WHERE {}"}
RESPONSE
{"message": "startup failed:\nScript7.groovy: 1: unexpected token: : # line 1, column 1.\n :> SELECT * WHERE {}\n ^\n\n1 error\n",
"Exception-Class": "org.codehaus.groovy.control.MultipleCompilationErrorsException"}

Gremlin Server doesn't know how to process raw SPARQL and I don't think that the plugin you referenced supports the server in any way. As a result, your attempts to send SPARQL to Gremlin Server are failing. The plugin would need to be modified in some way to make that work.

Related

How to run multiple gremlin commands as a single transaction?

In Amazon Neptune I would like to run multiple Gremlin commands in Java as a single transactions. The document says that tx.commit() and tx.rollback() is not supported. It suggests this - Multiple statements separated by a semicolon (;) or a newline character (\n) are included in a single transaction.
Example from the document show that Gremlin is supported in Java but I don't understand how to "Multiple statements separated by a semicolon"
GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(cluster));
// Add a vertex.
// Note that a Gremlin terminal step, e.g. next(), is required to make a request to the remote server.
// The full list of Gremlin terminal steps is at https://tinkerpop.apache.org/docs/current/reference/#terminal-steps
g.addV("Person").property("Name", "Justin").next();
// Add a vertex with a user-supplied ID.
g.addV("Custom Label").property(T.id, "CustomId1").property("name", "Custom id vertex 1").next();
g.addV("Custom Label").property(T.id, "CustomId2").property("name", "Custom id vertex 2").next();
g.addE("Edge Label").from(g.V("CustomId1")).to(g.V("CustomId2")).next();
The doc you are referring is for using the "string" mode for query submission. In your approach you are using the "bytecode" mode by using the remote instance of the graph traversal source (the "g" object). Instead you should submit a string script via the client object
Client client = gremlinCluster.connect();
client.submit("g.V()...iterate(); g.V()...iterate(); g.V()...");
Gremlin sessions
Java Example
After getting the cluster object,
String sessionId = UUID.randomUUID().toString();
Client client = cluster.connect(sessionId);
client.submit(query1);
client.submit(query2);
.
.
.
client.submit(query3);
client.close();
When you run .close() all the mutations get committed.
You can also capture the response from the Query reference.
List<Result> results = client.submit(query);
results.stream()...
You can also use the SessionedClient, which will run all queries in the same transaction upon close().
More information is here: https://docs.aws.amazon.com/neptune/latest/userguide/access-graph-gremlin-sessions.html#access-graph-gremlin-sessions-glv

Apache spark jdbc connect to apache drill error

I am sending query to apache drill from apache spark. I am getting the following error:
java.sql.SQLException: Failed to create prepared statement: PARSE
ERROR: Encountered "\"" at line 1, column 23.
When traced, I found I need to write a custom sql dialect. The problem I do not find any examples for pyspark. All the examples are for scala or java. Any help is highly appreciated.!
Here is the pyspark code :
`dataframe_mysql = spark.read.format("jdbc").option("url", "jdbc:drill:zk=ip:2181;schema=dfs").option("driver","org.apache.drill.jdbc.Driver").option("dbtable","dfs.`/user/titanic_data/test.csv`").load()`
Looks like you have used a double quote in your SQL query (please share your SQL).
By default Drill uses back tick for quoting identifiers - `
But you can change it by setting the system/session option (when you are already connected to Drill by JDBC for example) or you can specify it in JDBC connecting string. You can find more information here:
https://drill.apache.org/docs/lexical-structure/#identifier-quotes
I navigated to the drill web ui and updated the planner.parser.quoting_identifiers parameter to ". Then I edited my query as below:
dataframe_mysql = spark.read.format("jdbc").option("url", "jdbc:drill:zk=ip:2181;schema=dfs;").option("driver","org.apache.drill.jdbc.Driver").option("dbtable","dfs.\"/user/titanic_data/test.csv\"").load()
And it worked like charm!

Spring Data Rest 2.4 doesn't work with {?page,size,sort} links

I've faced with the following problem:
Spring Data Rest version: org.springframework.data:spring-data-rest-webmvc:2.4.0.RELEASE
When i perform the query: http://localhost:8080/data/entities/ - the base query for my Rest servlet.
It produces the links for all entities i have. The links has the following standard form:
"entityA": {
"href": "http://localhost:8080/data/entities/entitiA{?page,size,sort}",
"templated": true
}
When i try to perform the generated link:
http://localhost:8080/data/entities/entitiA{?page,size,sort}
I have 404 NotFound exception.
But when i execute
http://localhost:8080/data/entities/entitiA
it works fine.
Do you have any ideas about it or could you suggest any solution to execute links in the format:
http://localhost:8080/data/entities/entitiA{?page,size,sort}
Thanks!
Sometimes it is worth to look at the documentation ;-)
http://docs.spring.io/spring-data/rest/docs/2.4.0.RELEASE/reference/html/#paging-and-sorting
{?page,size,sort} is a template. It tells you which request parameters the resource supports. You are not supposed to use a templated link as it is in the response - you expand it first.
So a request like this should be working
http://localhost:8080/cars/data/entities/entitiA?page=1&size=20

Share sqlite2 database with Yii webapp

Hi I've got a sqlite2 database that is being used by a PHP webapp and I want a Yii webapp to access it. At the moment I copied the db file to a local server and I've changed config/main.php to:
'db'=>array(
'connectionString' => 'sqlite:'.dirname(__FILE__).'/../data/thedatabase.db',
),
When I run the Gii model generator I get:
CDbException
CDbCommand failed to execute the SQL statement: CDbCommand failed to prepare the SQL statement: SQLSTATE[HY000]: General error: 26 file is encrypted or is not a database. The SQL statement executed was: SELECT DISTINCT tbl_name FROM sqlite_master WHERE tbl_name<>'sqlite_sequence'
BTW I am able to convert the database to SQL using
Exporting sqlite2 database to SQL
Though I want the database to stay as an sqlite2 database so that the Yii app can access up to date user info.
After some thought it looks like it would be simpler to just use some code from the old PHP project in the Yii project...
$db = sqlite_open($databasefilename, 0666, $sqliteerror);
$query = sqlite_query($db, "SELECT password FROM user WHERE username='$username'");
$row = sqlite_fetch_array($query);
if ($row) {
return $row[password];
}
Edit:
When using that code I get the following error:
undefined function sqlite_open()
I'm using PHP Version 5.4.7...
http://au1.php.net/manual/en/function.sqlite-open.php
Here it says:
PHP 5 < 5.4.0
I got it working with the sqlite2 database by using 'sqlite2:' instead of 'sqlite:'
'db2'=>array(
'class'=>'CDbConnection',
'connectionString' => 'sqlite2:'.dirname(__FILE__).'/../../../thedatabase.db',
),
I can do queries like this:
Yii::app()->db2->createCommand($sql)->queryAll());
To stop Error 500 Object configuration must be an array containing a "class" element 'class'=>'CDbConnection' is required in config/main.php. I think that info is already included in the first database connection somewhere.

Update VOS 6.1.6 using Jena without loading to memory by invoking Sparql endpoint

If I run DELETE/INSERT query from the SPARQL endpoint, the UPDATE operation works. The SPARQL query is
SELECT ALL
INSERT DATA INTO <PERSONGRAPH> { personURI rdf:type foaf:Person }
Is it possible to do the same operation using Java code (either Jena or VirtuosoExecutionFactory), such that the UPDATE operation happens without needing to load the entire graphs into memory? I would like to invoke SPARQL endpoint from code to do the UPDATE operation. Please correct me if the assumption that the entire triples of a graph will be loaded in memory is wrong. The following Jena code works, but it loads the entire model to memory which causes the machine to not work when the triple size grows above 50,000.
SELECT ALL
String queryString1 = " INSERT DATA { personURI
rdf:type foaf:Person } ";
UpdateRequest request1 = UpdateFactory.create(queryString1);
UpdateAction.execute(request1, personModel);
I would like to do the same by invoking sparqlService or using createServiceRequest so that it avoids loading the entire graph into memory similar to the way it works for SPARQL endpoint.
The following code is not updating the Virtuoso store.
SELECT ALL
String queryString1 = " INSERT DATA { personURI
rdf:type foaf:Person } ";
com.hp.hpl.jenafix.query.Query query1 = com.hp.hpl.jenafix.query.QueryFactory.create(queryString1);
com.hp.hpl.jenafix.query.QueryExecution qexec1 = com.hp.hpl.jenafix.query.QueryExecutionFactory.sparqlService("http://IP:8890/sparql", query1);
I have tried using VirtuosoQueryExecutionFactory.sparqlService, QueryExecutionFactory.createServiceRequest and QueryExecutionFactory.sparqlService. These work for SELECT but not for UPDATE. Please let me know how to do update by invoking the SPARQL endpoint from Java code. Any suggestions, tips are much appreciated.
For new StackOverflow users there is a restriction of 2 URLs. Sadly personUri is an URL and can't be mentioned due to restriction. I am mentioning the personUri here for completeness. personUri is http://onmobile.com/umdb/person/juhi_chawla_268e7a02-8737-464f-97f8-172961d3335b
Based on Andy's feedback tried using both suggestions of UpdateExecutionFactory and Http Client.
On trying to use UpdateExecutionFactory and Http Client, got Connection refused problem while performing UPDATE but not on doing SELECT. Proxy Host and port are already set.
Thank you for the comment. The INSERT syntax works for Virtuoso Open Source which is the store that is being used. I have problem using the UpdateExecutionFactory. I tried with the following
String queryString = "DELETE DATA FROM <PERSONGRAPH> { <"
+ personURI
+ "> rdf:type foaf:Person } ";
com.hp.hpl.jena.update.UpdateRequest request = com.hp.hpl.jena.update.UpdateFactory.create(queryString);
UpdateProcessor proc = UpdateExecutionFactory.createRemote(request, "http://IP:8890/sparql");
proc.execute();
and got the following error stacktrace
org.apache.http.conn.HttpHostConnectException: Connection to IP:8890 refused
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:158)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:573)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:425)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
at org.openjena.riot.web.HttpOp.execHttpPost(HttpOp.java:208)
at org.openjena.riot.web.HttpOp.execHttpPost(HttpOp.java:154)
at org.openjena.riot.web.HttpOp.execHttpPost(HttpOp.java:128)
at com.hp.hpl.jena.sparql.modify.UpdateProcessRemote.execute(UpdateProcessRemote.java:60)
Could it be possible that Virtuoso has a different URL endpoint for update?
An update is not a query in SPARQL.
Use
UpdateExecutionFactory
To stream data to the server, simply open an HTTP POST connection with content type application/sparql-update, and write the update (with large data) into the stream.
BTW:
INSERT DATA INTO <PERSONGRAPH>
isn't legal SPARQL Update syntax.
I'm not sure I follow your question. It's not clear what was added after AndyS' response, and what was there to start with. His note about your syntax error is probably worth more study, if you haven't resolved this yet -- and if you have, an update sharing that resolution would be a good idea.
I'd also recommend reviewing the documentation regarding Jena connections to Virtuoso.
Also worth noting -- questions specifically regarding Virtuoso are generally best raised on the public OpenLink Discussion Forums, the Virtuoso Users mailing list, or through a confidential Support Case.
You could use the following code to update data directly on server side without loading to local client memory.
public static void main(String[] args) {
String url;
if(args.length == 0)
url = "jdbc:virtuoso://localhost:1111";
else
url = args[0];
VirtGraph set = new VirtGraph (url, "dba", "dba");
String str = "CLEAR GRAPH <http://test1>";
VirtuosoUpdateRequest vur = VirtuosoUpdateFactory.create(str, set);
vur.exec();
str = "INSERT INTO GRAPH <http://test1> { <http://aa> <http://bb> 'cc' . <http://aa1> <http://bb> 123 . <http://aa1> <http://bb> 124 . <http://aa1> <http://bb> 125 . }";
vur = VirtuosoUpdateFactory.create(str, set);
vur.exec();
Look at VirtuosoSPARQLExample8.java and VirtuosoSPARQLExample9.java in Virtuoso Jena Provider examples.