tripod 0.0.3 → 0.0.4
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.
- data/README.md +60 -4
- data/lib/tripod/finders.rb +52 -0
- data/lib/tripod/version.rb +1 -1
- data/spec/tripod/finders_spec.rb +25 -0
- metadata +15 -15
data/README.md
CHANGED
@@ -1,13 +1,69 @@
|
|
1
1
|
# Tripod
|
2
2
|
|
3
|
-
ActiveModel-style Ruby ORM for RDF
|
3
|
+
ActiveModel-style Ruby ORM for RDF Linked Data. Works with SPARQL 1.1 HTTP endpoints.
|
4
4
|
|
5
|
-
|
5
|
+
## Quick start, for using in a rails app.
|
6
6
|
|
7
|
-
|
7
|
+
1. Install the gem:
|
8
|
+
|
9
|
+
gem install tripod
|
10
|
+
|
11
|
+
2. Add it to your Gemfile
|
12
|
+
|
13
|
+
gem tripod
|
14
|
+
|
15
|
+
3. Configure it (in application.rb, or development.rb/production.rb/test.rb)
|
16
|
+
|
17
|
+
# (values shown are the defaults)
|
18
|
+
Tripod.configure do |config|
|
19
|
+
config.update_endpoint = 'http://127.0.0.1:3030/tripod/update'
|
20
|
+
config.query_endpoint = 'http://127.0.0.1:3030/tripod/sparql'
|
21
|
+
config.timeout_seconds = 30
|
22
|
+
end
|
23
|
+
|
24
|
+
4. Include it in your model classes.
|
25
|
+
|
26
|
+
class Person
|
27
|
+
include Tripod::Resource
|
28
|
+
|
29
|
+
field :name, 'http://name'
|
30
|
+
field :aliases, 'http://alias', :multivalued => true
|
31
|
+
field :age, 'http://age', :datatype => RDF::XSD.integer
|
32
|
+
field :important_dates, 'http://importantdates', :datatype => RDF::XSD.date, :multivalued => true
|
33
|
+
end
|
34
|
+
|
35
|
+
# Note: Active Model validations are supported
|
36
|
+
|
37
|
+
5. Use it
|
38
|
+
|
39
|
+
uri = 'http://ric'
|
40
|
+
graph = 'http://people'
|
41
|
+
p = Person.new(uri, graph)
|
42
|
+
p.name = 'Ric'
|
43
|
+
p.age = 31
|
44
|
+
p.aliases = ['Rich', 'Richard']
|
45
|
+
p.important_dates = [Date.new(2011,1,1)]
|
46
|
+
p[RDF::type] = RDF::URI('http://person')
|
47
|
+
p.save!
|
48
|
+
|
49
|
+
people = Person.where("
|
50
|
+
SELECT ?person ?graph
|
51
|
+
WHERE {
|
52
|
+
GRAPH ?graph {
|
53
|
+
?person ?p ?o .
|
54
|
+
?person a <http://person> .
|
55
|
+
}
|
56
|
+
}",
|
57
|
+
:uri_variable => 'person' )
|
58
|
+
# => returns an array of Person objects, containing all data we know about them.
|
59
|
+
|
60
|
+
ric = Person.find('http://ric')
|
61
|
+
# => returns a single Person object.
|
62
|
+
|
63
|
+
[Full Documentation](http://rubydoc.info/github/Swirrl/tripod/master/frames)
|
8
64
|
|
9
65
|
__Warning: Work still in progress / experimental. Not production ready!__
|
10
66
|
|
11
|
-
|
67
|
+
Inspired by [Durran Jordan's](https://github.com/durran) [Mongoid](http://mongoid.org/en/mongoid/) ORM for [MongoDB](http://www.mongodb.org/), and [Ben Lavender's](https://github.com/bhuga) RDF ORM, [Spira](https://github.com/ruby-rdf/spira).
|
12
68
|
|
13
69
|
Copyright (c) 2012 [Swirrl IT Limited](http://swirrl.com). Released under MIT License
|
data/lib/tripod/finders.rb
CHANGED
@@ -40,5 +40,57 @@ module Tripod::Finders
|
|
40
40
|
resource
|
41
41
|
end
|
42
42
|
|
43
|
+
# Find a collection of +Resource+s by a SPARQL select statement which returns their uris.
|
44
|
+
# Under the hood, this only executes two queries: a select, then a describe.
|
45
|
+
#
|
46
|
+
# @example
|
47
|
+
# Person.where('SELECT ?uri ?graph WHERE { GRAPH ?graph { ?uri ?p ?o } } LIMIT 3')
|
48
|
+
#
|
49
|
+
# @param [ String ] criteria. A sparql query which returns a list of uris of the objects.
|
50
|
+
# @param [ Hash ] opts. A hash of options.
|
51
|
+
#
|
52
|
+
# @option options [ String ] uri_variable The name of the uri variable in thh query, if not 'uri'
|
53
|
+
# @option options [ String ] graph_variable The name of the uri variable in thh query, if not 'graph'
|
54
|
+
#
|
55
|
+
# @return [ Array ] An array of hydrated resources of this class's type.
|
56
|
+
def where(criteria, opts={})
|
57
|
+
|
58
|
+
# 1. Run the select.
|
59
|
+
select_results = Tripod::SparqlClient::Query.select(criteria)
|
60
|
+
|
61
|
+
data = {}
|
62
|
+
|
63
|
+
select_results.each do |r|
|
64
|
+
uri_variable = opts[:uri_variable] || 'uri'
|
65
|
+
graph_variable = opts[:graph_variable] || 'graph'
|
66
|
+
data[ r[uri_variable]["value"] ] = r[graph_variable]["value"]
|
67
|
+
end
|
68
|
+
|
69
|
+
uris_sparql_str = data.keys.map{ |u| "<#{u}>" }.join(" ")
|
70
|
+
|
71
|
+
# 2. Do a big describe statement, and read the results into an in-memory repo
|
72
|
+
triples = Tripod::SparqlClient::Query::describe("DESCRIBE #{uris_sparql_str}")
|
73
|
+
triples_repository = RDF::Repository.new()
|
74
|
+
RDF::Reader.for(:ntriples).new(triples) do |reader|
|
75
|
+
reader.each_statement do |statement|
|
76
|
+
triples_repository << statement
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
resources = []
|
81
|
+
# 3. for each of our uris, make a resource, with a graph of triples for that uri from the in-mem repo
|
82
|
+
data.each_pair do |u,g|
|
83
|
+
r = self.new(u,g)
|
84
|
+
data_graph = RDF::Graph.new
|
85
|
+
triples_repository.query( [RDF::URI.new(u), :predicate, :object] ) do |statement|
|
86
|
+
data_graph << statement
|
87
|
+
end
|
88
|
+
r.hydrate!(data_graph)
|
89
|
+
resources << r
|
90
|
+
end
|
91
|
+
|
92
|
+
resources
|
93
|
+
|
94
|
+
end
|
43
95
|
end
|
44
96
|
end
|
data/lib/tripod/version.rb
CHANGED
data/spec/tripod/finders_spec.rb
CHANGED
@@ -68,4 +68,29 @@ describe Tripod::Finders do
|
|
68
68
|
|
69
69
|
end
|
70
70
|
|
71
|
+
describe '.where' do
|
72
|
+
|
73
|
+
before do
|
74
|
+
# save these into the db
|
75
|
+
bill
|
76
|
+
ric
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'returns an array of resources which match those in the db' do
|
80
|
+
res = Person.where('SELECT ?uri ?graph WHERE { GRAPH ?graph { ?uri ?p ?o } }')
|
81
|
+
res.length.should == 2
|
82
|
+
res.first.should == ric
|
83
|
+
res.last.should == bill
|
84
|
+
|
85
|
+
res.first.name.should == "ric"
|
86
|
+
res.first['http://knows'].should == [RDF::URI.new("http://bill")]
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'uses the uri and graph variables if supplied' do
|
90
|
+
res = Person.where('SELECT ?bob ?geoff WHERE { GRAPH ?geoff { ?bob ?p ?o } }', :uri_variable => 'bob', :graph_variable => 'geoff')
|
91
|
+
res.length.should == 2
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
71
96
|
end
|
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.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-08-28 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|
16
|
-
requirement: &
|
16
|
+
requirement: &70121805448680 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70121805448680
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: activemodel
|
27
|
-
requirement: &
|
27
|
+
requirement: &70121805448140 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '3.1'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70121805448140
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: equivalent-xml
|
38
|
-
requirement: &
|
38
|
+
requirement: &70121805447720 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70121805447720
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rdf
|
49
|
-
requirement: &
|
49
|
+
requirement: &70121805447180 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0.3'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70121805447180
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rdf-rdfxml
|
60
|
-
requirement: &
|
60
|
+
requirement: &70121805446760 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70121805446760
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rdf-n3
|
71
|
-
requirement: &
|
71
|
+
requirement: &70121805446300 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70121805446300
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: rdf-json
|
82
|
-
requirement: &
|
82
|
+
requirement: &70121805445880 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :runtime
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70121805445880
|
91
91
|
description: RDF ruby ORM
|
92
92
|
email:
|
93
93
|
- ric@swirrl.com
|