Class: IqTriplestorage::VirtuosoAdaptor

Inherits:
Object
  • Object
show all
Defined in:
lib/iq_triplestorage/virtuoso_adaptor.rb

Instance Method Summary collapse

Constructor Details

#initialize(host, port, username, password) ⇒ VirtuosoAdaptor

Returns a new instance of VirtuosoAdaptor.

Raises:

  • (ArgumentError)


6
7
8
9
10
11
12
13
14
# File 'lib/iq_triplestorage/virtuoso_adaptor.rb', line 6

def initialize(host, port, username, password)
  # validate to avoid nasty errors
  raise(ArgumentError, "username must not be nil") if username.nil?

  @host = host
  @port = port
  @username = username
  @password = password
end

Instance Method Details

#batch_update(triples_by_graph) ⇒ Object

expects a hash of N-Triples by graph URI



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/iq_triplestorage/virtuoso_adaptor.rb', line 21

def batch_update(triples_by_graph)
  # apparently Virtuoso gets confused when mixing CLEAR and INSERT queries,
  # so we have to do use separate requests

  reset_queries = triples_by_graph.keys.map do |graph_uri|
    "CLEAR GRAPH <#{graph_uri}>" # XXX: duplicates `reset`
  end
  success = sparql_query(reset_queries)
  return false unless success

  insert_queries = triples_by_graph.map do |graph_uri, ntriples|
    "INSERT IN GRAPH <#{graph_uri}> {\n#{ntriples}\n}"
  end
  success = sparql_query(insert_queries)

  return success
end

#http_request(method, path, body, headers = {}) ⇒ Object



85
86
87
88
89
90
91
92
93
94
# File 'lib/iq_triplestorage/virtuoso_adaptor.rb', line 85

def http_request(method, path, body, headers={})
  uri = URI.parse("#{@host}:#{@port}#{path}")

  req = Net::HTTP.const_get(method.downcase.capitalize).new(uri.to_s)
  req.basic_auth(@username, @password)
  headers.each { |key, value| req[key] = value }
  req.body = body

  return Net::HTTP.new(uri.host, uri.port).request(req)
end

#reset(uri) ⇒ Object



16
17
18
# File 'lib/iq_triplestorage/virtuoso_adaptor.rb', line 16

def reset(uri)
  return sparql_pull("CLEAR GRAPH <#{uri}>") # XXX: s/CLEAR/DROP/ was rejected (405)
end

#sparql_pull(query) ⇒ Object



65
66
67
68
69
70
71
# File 'lib/iq_triplestorage/virtuoso_adaptor.rb', line 65

def sparql_pull(query)
  path = "/DAV/home/#{@username}/rdf_sink" # XXX: shouldn't this be /sparql?
  res = http_request("POST", path, query, {
    "Content-Type" => "application/sparql-query"
  })
  return res.code == "200" # XXX: always returns 409
end

#sparql_push(uri, rdf_data, content_type) ⇒ Object

Raises:

  • (TypeError)


52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/iq_triplestorage/virtuoso_adaptor.rb', line 52

def sparql_push(uri, rdf_data, content_type)
  raise TypeError, "missing content type" unless content_type

  filename = uri.gsub(/[^0-9A-Za-z]/, "_") # XXX: too simplistic?
  path = "/DAV/home/#{@username}/rdf_sink/#{filename}"

  res = http_request("PUT", path, rdf_data, { # XXX: is PUT correct here?
    "Content-Type" => content_type
  })

  return res.code == "201"
end

#sparql_query(query) ⇒ Object

query is a string or an array of strings



74
75
76
77
78
79
80
81
82
83
# File 'lib/iq_triplestorage/virtuoso_adaptor.rb', line 74

def sparql_query(query)
  query = query.join("\n\n") + "\n" rescue query
  path = "/DAV/home/#{@username}/query"

  res = http_request("POST", path, query, {
    "Content-Type" => "application/sparql-query"
  })

  return res.code == "201"
end

#update(uri, rdf_data = nil, content_type = nil) ⇒ Object

uses push method if ‘rdf_data` is provided, pull otherwise



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/iq_triplestorage/virtuoso_adaptor.rb', line 40

def update(uri, rdf_data=nil, content_type=nil)
  reset(uri)

  if rdf_data
    res = sparql_push(uri, rdf_data.strip, content_type)
  else
    res = sparql_pull(%{LOAD "#{uri}" INTO GRAPH <#{uri}>})
  end

  return res
end