tripod 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,18 @@ module Tripod::Errors
3
3
 
4
4
  # not found error.
5
5
  class ResourceNotFound < StandardError
6
+
7
+ attr_accessor :uri
8
+
9
+ def initialize(uri=nil)
10
+ @uri = uri
11
+ end
12
+
13
+ def message
14
+ msg = "Resource Not Found"
15
+ msg += ": #{@uri.to_s}" if @uri
16
+ msg
17
+ end
6
18
  end
7
19
 
8
20
  end
@@ -4,7 +4,8 @@ module Tripod::Fields
4
4
  class Standard
5
5
 
6
6
  # Set readers for the instance variables.
7
- attr_accessor :name, :predicate, :options, :datatype, :multivalued
7
+ attr_accessor :name, :predicate, :options, :datatype, :is_uri, :multivalued
8
+ alias_method :is_uri?, :is_uri
8
9
 
9
10
  # Create the new field with a name and optional additional options.
10
11
  #
@@ -22,8 +23,8 @@ module Tripod::Fields
22
23
  @options = options
23
24
  @predicate = RDF::URI.new(predicate.to_s)
24
25
  @datatype = RDF::URI.new(options[:datatype].to_s) if options[:datatype]
26
+ @is_uri = !!options[:is_uri]
25
27
  @multivalued = options[:multivalued] || false
26
28
  end
27
-
28
29
  end
29
30
  end
data/lib/tripod/fields.rb CHANGED
@@ -34,7 +34,9 @@ module Tripod::Fields
34
34
 
35
35
 
36
36
  def new_value_for_field(value, field)
37
- if field.datatype
37
+ if field.is_uri?
38
+ RDF::URI.new(value.to_s)
39
+ elsif field.datatype
38
40
  RDF::Literal.new(value, :datatype => field.datatype)
39
41
  else
40
42
  value
@@ -30,7 +30,7 @@ module Tripod::Finders
30
30
  if result.length > 0
31
31
  graph_uri = result[0]["g"]["value"]
32
32
  else
33
- raise Tripod::Errors::ResourceNotFound.new
33
+ raise Tripod::Errors::ResourceNotFound.new(uri)
34
34
  end
35
35
  end
36
36
 
@@ -42,7 +42,7 @@ module Tripod::Finders
42
42
 
43
43
  # check that there are triples for the resource (catches case when someone has deleted data
44
44
  # between our original check for the graph and hydrating the object.
45
- raise Tripod::Errors::ResourceNotFound.new if resource.repository.empty?
45
+ raise Tripod::Errors::ResourceNotFound.new(uri) if resource.repository.empty?
46
46
 
47
47
  # return the instantiated, hydrated resource
48
48
  resource
@@ -28,13 +28,19 @@ module Tripod::Repository
28
28
 
29
29
  if graph
30
30
  graph.each_statement do |statement|
31
- # only use statements about this resource for hydrating
32
- if statement.subject.to_s == @uri.to_s
33
- @repository << statement
34
- end
31
+ # Note that we use all statements, even those not about this resource, in case we're being
32
+ # passed eager-loaded ones.
33
+ @repository << statement
35
34
  end
36
35
  else
37
- triples = Tripod::SparqlClient::Query.query("DESCRIBE <#{uri}>", "application/n-triples")
36
+
37
+ graph_selector = self.graph_uri.present? ? "<#{graph_uri.to_s}>" : "?g"
38
+
39
+ triples = Tripod::SparqlClient::Query.query(
40
+ "CONSTRUCT {<#{uri}> ?p ?o} WHERE { GRAPH #{graph_selector} { <#{uri}> ?p ?o } }",
41
+ "application/n-triples"
42
+ )
43
+
38
44
  @repository = RDF::Repository.new
39
45
  RDF::Reader.for(:ntriples).new(triples) do |reader|
40
46
  reader.each_statement do |statement|
@@ -45,6 +51,15 @@ module Tripod::Repository
45
51
 
46
52
  end
47
53
 
54
+ # returns a graph of all triples in the repository
55
+ def repository_as_graph
56
+ g = RDF::Graph.new
57
+ @repository.each_statement do |s|
58
+ g << s
59
+ end
60
+ g
61
+ end
62
+
48
63
  # returns a graph of triples from the underlying repository where this resource's uri is the subject.
49
64
  def get_triples_for_this_resource
50
65
  triples_graph = RDF::Graph.new
@@ -17,6 +17,10 @@ module Tripod::SparqlClient
17
17
  def self.query(sparql, accept_header, extra_params={})
18
18
 
19
19
  begin
20
+ if defined?(Rails)
21
+ Rails.logger.debug "TRIPOD: About to run query:"
22
+ Rails.logger.debug sparql
23
+ end
20
24
  params = {:query => sparql}.merge(extra_params)
21
25
  hdrs = {:accept => accept_header, :params => params}
22
26
 
@@ -33,7 +37,7 @@ module Tripod::SparqlClient
33
37
  if Tripod.cache_store # if a cache store is configured
34
38
  # SHA-2 the key to keep the it within the small limit for many cache stores (e.g. Memcached is 250bytes)
35
39
  # Note: SHA2's are pretty certain to be unique http://en.wikipedia.org/wiki/SHA-2.
36
- key = 'SPARQL-QUERY-' + Digest::SHA2.hexdigest([format, headers, sparql].join(" "))
40
+ key = 'SPARQL-QUERY-' + Digest::SHA2.hexdigest([extra_params, accept_header, sparql].join(" "))
37
41
  Tripod.cache_store.fetch(key, &make_the_call)
38
42
  else
39
43
  make_the_call.call()
@@ -1,3 +1,3 @@
1
1
  module Tripod
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.2"
3
3
  end
@@ -6,7 +6,7 @@ class Person
6
6
  graph_uri 'http://example.com/graph'
7
7
 
8
8
  field :name, 'http://example.com/name'
9
- field :father, 'http://example.com/father'
9
+ field :father, 'http://example.com/father', :is_uri => true
10
10
  field :knows, 'http://example.com/knows', :multivalued => true
11
11
  field :aliases, 'http://exmample.com/alias', :multivalued => true
12
12
  field :age, 'http://example.com/age', :datatype => RDF::XSD.integer
@@ -26,10 +26,7 @@ describe Tripod::Attributes do
26
26
  end
27
27
 
28
28
  context "for a uri" do
29
-
30
29
  it "should return an RDF::URI" do
31
- puts person[:father]
32
-
33
30
  person[:father].class.should == RDF::URI
34
31
  end
35
32
 
@@ -62,6 +59,15 @@ describe Tripod::Attributes do
62
59
  it "should return a single value" do
63
60
  person.read_attribute(:hat_type, field).should == 'fez'
64
61
  end
62
+
63
+ context "and the value is a URI" do
64
+ let(:field) { Person.send(:field_for, :hat_type, 'http://example.com/hat', {is_uri: true}) }
65
+ before do
66
+ person.stub(:read_predicate).with('http://example.com/hat').and_return(['fez'])
67
+ end
68
+
69
+
70
+ end
65
71
  end
66
72
 
67
73
  context "where field is given and is multi-valued" do
@@ -95,6 +101,13 @@ describe Tripod::Attributes do
95
101
  person.read_predicate('http://example.com/age').first.datatype.should == RDF::XSD.integer
96
102
  end
97
103
 
104
+ context "where the attribute is a uri" do
105
+ it "should convert a string to an RDF::URI" do
106
+ person[:father] = 'http://example.com/darth'
107
+ person.read_predicate('http://example.com/father').first.should be_a(RDF::URI)
108
+ end
109
+ end
110
+
98
111
  context "where the attribute is multi-valued" do
99
112
  it "should co-erce all the values to the correct datatype" do
100
113
  person[:important_dates] = [Date.today]
@@ -8,7 +8,6 @@ describe Tripod::Fields do
8
8
  b = Person.new('http://example.com/id/barry')
9
9
  b.name = 'Barry'
10
10
  b
11
- b
12
11
  end
13
12
 
14
13
  it "creates a getter for the field, which accesses data for the predicate, returning a single String" do
@@ -2,14 +2,14 @@ require "spec_helper"
2
2
 
3
3
  describe Tripod::Finders do
4
4
 
5
- let(:ric) do
5
+ let!(:ric) do
6
6
  r = Person.new('http://example.com/id/ric')
7
7
  r.name = "ric"
8
8
  r.knows = RDF::URI.new("http://example.com/id/bill")
9
9
  r
10
10
  end
11
11
 
12
- let(:bill) do
12
+ let!(:bill) do
13
13
  b = Person.new('http://example.com/id/bill')
14
14
  b.name = "bill"
15
15
  b
@@ -48,10 +48,31 @@ describe Tripod::Finders do
48
48
  end
49
49
 
50
50
  context 'with graph_uri supplied' do
51
- it 'should use that graph to call new' do
52
- ric # trigger the lazy load
53
- Person.should_receive(:new).with(ric.uri, 'http://example.com/graphx').and_call_original
54
- Person.find(ric.uri, "http://example.com/graphx")
51
+
52
+ let!(:another_person) do
53
+ p = Person.new('http://example.com/anotherperson', 'http://example.com/graphx')
54
+ p.name = 'a.n.other'
55
+ p.save!
56
+ p
57
+ end
58
+
59
+ context 'when there are triples about the resource in that graph' do
60
+
61
+ it 'should use that graph to call new' do
62
+ Person.should_receive(:new).with(another_person.uri, 'http://example.com/graphx').and_call_original
63
+ Person.find(another_person.uri, "http://example.com/graphx")
64
+ end
65
+
66
+ end
67
+
68
+ context 'when there are no triples about the resource in that graph' do
69
+ it 'should raise nto found' do
70
+
71
+ lambda {
72
+ Person.find(another_person.uri, "http://example.com/graphy")
73
+ }.should raise_error(Tripod::Errors::ResourceNotFound)
74
+
75
+ end
55
76
  end
56
77
  end
57
78
 
@@ -22,21 +22,36 @@ describe Tripod::Repository do
22
22
  Person.new(@uri, @graph_uri)
23
23
  end
24
24
 
25
- context 'no graph passed' do
25
+ let(:graphless_resource) do
26
+ Resource.new(@uri)
27
+ end
26
28
 
27
- context 'no predicate restrictions passed' do
29
+ context 'no graph passed' do
28
30
 
29
- it 'populates the repository with a graph of triples from the db' do
30
- Tripod::SparqlClient::Query.should_receive(:query).with("DESCRIBE <#{@uri}>", "application/n-triples").and_call_original
31
+ context 'graph_uri set on object' do
32
+ it 'populates the object with triples, restricted to the graph_uri' do
33
+ Tripod::SparqlClient::Query.should_receive(:query).with(
34
+ "CONSTRUCT {<#{person.uri}> ?p ?o} WHERE { GRAPH <#{person.graph_uri}> { <#{person.uri}> ?p ?o } }",
35
+ "application/n-triples").and_call_original
31
36
  person.hydrate!
32
37
  person.repository.should_not be_empty
33
38
  end
39
+ end
34
40
 
41
+ context 'graph_uri not set on object' do
42
+ it 'populates the object with triples, not to a graph' do
43
+ Tripod::SparqlClient::Query.should_receive(:query).with(
44
+ "CONSTRUCT {<#{graphless_resource.uri}> ?p ?o} WHERE { GRAPH ?g { <#{graphless_resource.uri}> ?p ?o } }",
45
+ "application/n-triples").and_call_original
46
+ graphless_resource.hydrate!
47
+ graphless_resource.repository.should_not be_empty
48
+ end
35
49
  end
50
+
36
51
  end
37
52
 
38
53
  context 'graph passed' do
39
- it 'populates the repository with the graph of triples passed in, ingoring triples not about this resource' do
54
+ it 'populates the repository with the graph of triples passed in' do
40
55
  @graph = RDF::Graph.new
41
56
 
42
57
  person.repository.statements.each do |s|
@@ -44,12 +59,12 @@ describe Tripod::Repository do
44
59
  end
45
60
 
46
61
  @graph << RDF::Statement.new( 'http://example.com/anotherresource', 'http://example.com/pred', 'http://example.com/obj')
47
- @graph.statements.count.should ==2 # there'll already be a statement about type in the person.
62
+ @graph.statements.count.should == 2 # there'll already be a statement about type in the person.
48
63
 
49
64
  person.hydrate!(:graph => @graph)
50
65
  person.repository.should_not be_empty
51
- person.repository.statements.count.should == 1 # not the extra ones
52
- person.repository.statements.first.should == @graph.statements.first
66
+ person.repository.statements.count.should == 2 # not the extra ones
67
+ person.repository.statements.to_a.should == @graph.statements.to_a
53
68
  end
54
69
  end
55
70
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tripod
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-03-13 00:00:00.000000000 Z
14
+ date: 2013-03-21 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rest-client
18
- requirement: &70364886263520 !ruby/object:Gem::Requirement
18
+ requirement: &70208187066620 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: '0'
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *70364886263520
26
+ version_requirements: *70208187066620
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activemodel
29
- requirement: &70364886262400 !ruby/object:Gem::Requirement
29
+ requirement: &70208187061260 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ~>
@@ -34,10 +34,10 @@ dependencies:
34
34
  version: '3.1'
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *70364886262400
37
+ version_requirements: *70208187061260
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: equivalent-xml
40
- requirement: &70364886261680 !ruby/object:Gem::Requirement
40
+ requirement: &70208187091120 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
@@ -45,10 +45,10 @@ dependencies:
45
45
  version: '0'
46
46
  type: :runtime
47
47
  prerelease: false
48
- version_requirements: *70364886261680
48
+ version_requirements: *70208187091120
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: rdf
51
- requirement: &70364886260440 !ruby/object:Gem::Requirement
51
+ requirement: &70208187100360 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ~>
@@ -56,10 +56,10 @@ dependencies:
56
56
  version: '1.0'
57
57
  type: :runtime
58
58
  prerelease: false
59
- version_requirements: *70364886260440
59
+ version_requirements: *70208187100360
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: rdf-rdfxml
62
- requirement: &70364886259940 !ruby/object:Gem::Requirement
62
+ requirement: &70208187094320 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ! '>='
@@ -67,10 +67,10 @@ dependencies:
67
67
  version: '0'
68
68
  type: :runtime
69
69
  prerelease: false
70
- version_requirements: *70364886259940
70
+ version_requirements: *70208187094320
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: rdf-n3
73
- requirement: &70364886258140 !ruby/object:Gem::Requirement
73
+ requirement: &70208186978440 !ruby/object:Gem::Requirement
74
74
  none: false
75
75
  requirements:
76
76
  - - ! '>='
@@ -78,10 +78,10 @@ dependencies:
78
78
  version: '0'
79
79
  type: :runtime
80
80
  prerelease: false
81
- version_requirements: *70364886258140
81
+ version_requirements: *70208186978440
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: rdf-json
84
- requirement: &70364886255600 !ruby/object:Gem::Requirement
84
+ requirement: &70208186977380 !ruby/object:Gem::Requirement
85
85
  none: false
86
86
  requirements:
87
87
  - - ! '>='
@@ -89,10 +89,10 @@ dependencies:
89
89
  version: '0'
90
90
  type: :runtime
91
91
  prerelease: false
92
- version_requirements: *70364886255600
92
+ version_requirements: *70208186977380
93
93
  - !ruby/object:Gem::Dependency
94
94
  name: json-ld
95
- requirement: &70364886254440 !ruby/object:Gem::Requirement
95
+ requirement: &70208186975660 !ruby/object:Gem::Requirement
96
96
  none: false
97
97
  requirements:
98
98
  - - ! '>='
@@ -100,10 +100,10 @@ dependencies:
100
100
  version: '0'
101
101
  type: :runtime
102
102
  prerelease: false
103
- version_requirements: *70364886254440
103
+ version_requirements: *70208186975660
104
104
  - !ruby/object:Gem::Dependency
105
105
  name: guid
106
- requirement: &70364886240960 !ruby/object:Gem::Requirement
106
+ requirement: &70208186974980 !ruby/object:Gem::Requirement
107
107
  none: false
108
108
  requirements:
109
109
  - - ! '>='
@@ -111,10 +111,10 @@ dependencies:
111
111
  version: '0'
112
112
  type: :runtime
113
113
  prerelease: false
114
- version_requirements: *70364886240960
114
+ version_requirements: *70208186974980
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: dalli
117
- requirement: &70364886240040 !ruby/object:Gem::Requirement
117
+ requirement: &70208186973620 !ruby/object:Gem::Requirement
118
118
  none: false
119
119
  requirements:
120
120
  - - ~>
@@ -122,7 +122,7 @@ dependencies:
122
122
  version: '2.6'
123
123
  type: :runtime
124
124
  prerelease: false
125
- version_requirements: *70364886240040
125
+ version_requirements: *70208186973620
126
126
  description: RDF ruby ORM
127
127
  email:
128
128
  - ric@swirrl.com