2
require 'queryengine/query2sparql'
5
# Soprano DBus server adapter
6
class SopranoAdapter < ActiveRdfAdapter
7
$activerdflog.info "loading Soprano adapter"
8
ConnectionPool.register_adapter(:soprano, self)
15
def SopranoAdapter.get_cache
16
return @@soprano_cache
19
# Instantiate the connection with the SPARQL Endpoint.
20
# available parameters:
21
# * :model => name of model to use, defaults to 'main'
22
# * :service => DBus service to use, defaults to 'org.soprano.Server'
23
# * :backend => the name of a backend, such as 'virtuoso'
24
def initialize(params = {})
29
@model_name = params[:model] || 'main'
30
@caching = params[:caching] || false
31
@backend_name = params[:backend]
34
@backend = Soprano.discoverBackendByName(@backend_name)
36
if @backend_name =~ /^virtuoso/
37
@host = params[:host] || 'localhost'
38
@port = params[:port] || 1111
39
@username = params[:username] || 'dba'
40
@password = params[:password] || 'dba'
41
settings << Soprano::BackendSetting.new(Soprano::BackendOptionHost, @host)
42
settings << Soprano::BackendSetting.new(Soprano::BackendOptionPort, @port)
43
settings << Soprano::BackendSetting.new(Soprano::BackendOptionUsername, @username)
44
settings << Soprano::BackendSetting.new(Soprano::BackendOptionPassword, @password)
46
@model = @backend.createModel(settings)
48
# For accessing the Nepomuk store in KDE, use 'org.kde.NepomukServer'
49
@service = params[:service] || 'org.soprano.Server'
51
@client = Soprano::Client::DBusClient.new(@service)
52
@model = @client.createModel(@model_name)
61
@model.removeStatement(Soprano::Node.new, Soprano::Node.new, Soprano::Node.new, Soprano::Node.new)
64
# load a file from the given location with the given syntax into the model.
65
def load(location, syntax="n-triples")
67
system("sopranocmd --backend #{@backend_name} --host #{@host} --port #{@port} --username #{@username} --password #{@password} --serialization #{syntax} import #{location}")
69
system("sopranocmd --dbus #{@service} --serialization #{syntax} --model #{@model_name} import #{location}")
73
# query datastore with query string (SPARQL), returns array with query results
74
# may be called with a block
75
def query(query, &block)
76
qs = Query2SPARQL.translate(query)
79
result = query_cache(qs)
81
$activerdflog.debug "cache miss for query #{qs}"
83
$activerdflog.debug "cache hit for query #{qs}"
88
result = execute_soprano_query(qs, query.select_clauses, &block)
89
add_to_cache(qs, result) if @caching
90
result = [] if result == "timeout"
94
# do the real work of executing the sparql query
95
def execute_soprano_query(qs, select_clauses, &block)
98
# querying soprano server
99
binding_set = @model.executeQuery(qs, Soprano::Query::QueryLanguageSparql)
101
binding_set.each do |binding|
103
select_clauses.each do |var|
105
result << soprano_node_to_activerdf(binding[var])
112
results.each do |*clauses|
129
ConnectionPool.remove_data_source(self)
132
# add triple to datamodel
133
def add(s, p, o, c=nil)
134
$activerdflog.debug "adding triple #{s} #{p} #{o} #{c}"
137
if s.nil? || p.nil? || o.nil?
138
$activerdflog.debug "cannot add triple with empty subject, exiting"
142
unless s.respond_to?(:uri) && p.respond_to?(:uri)
143
$activerdflog.debug "cannot add triple where s/p are not resources, exiting"
147
@model.addStatement(Soprano::Statement.new(wrap(s), wrap(p), wrap(o), wrap(c)))
148
save if ConnectionPool.auto_flush?
151
# deletes triple(s,p,o) from datastore
152
# nil parameters match anything: delete(nil,nil,nil) will delete all triples
153
# ActiveRDF will pass the symbol :all as 'o' when all values of
154
# object for the subject/predicate should be deleted
155
def delete(s, p, o, c=nil)
156
$activerdflog.debug "removing triple(s) #{s} #{p} #{o} #{c}"
159
@model.removeAllStatements(Soprano::Statement.new(wrap(s), wrap(p), wrap(o), wrap(c)))
163
def add_to_cache(query_string, result)
164
unless result.nil? or result.empty?
165
if result == "timeout"
166
@@soprano_cache.store(query_string, [])
168
$activerdflog.debug "adding to soprano cache - query: #{query_string}"
169
@@soprano_cache.store(query_string, result)
174
def query_cache(query_string)
175
if @@soprano_cache.include?(query_string)
176
return @@soprano_cache.fetch(query_string)
182
# Converts a Soprano::Node to the ActiveRDF equivalent
183
def soprano_node_to_activerdf(node)
185
when Soprano::Node::EmptyNode:
187
when Soprano::Node::ResourceNode:
188
RDFS::Resource.new(node.uri.toString)
189
when Soprano::Node::LiteralNode:
190
node.literal.variant.value
191
when Soprano::Node::BlankNode:
201
Soprano::Node.new(Qt::Url.new(node.uri))
204
Soprano::Node.new($1)
205
elsif node =~ /(.*)@(.*)/
206
Soprano::Node.new(Soprano::LiteralValue.new($1), $2)
208
Soprano::Node.new(Soprano::LiteralValue.new(node))
211
Soprano::Node.new(Soprano::LiteralValue.new(node))
217
# kate: space-indent on; indent-width 2; replace-tabs on; mixed-indent off;