tripod 0.9.6 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/lib/tripod.rb +4 -1
- data/lib/tripod/cache_stores/memcached_cache_store.rb +26 -8
- data/lib/tripod/components.rb +2 -2
- data/lib/tripod/graphs.rb +12 -0
- data/lib/tripod/persistence.rb +3 -3
- data/lib/tripod/version.rb +1 -1
- data/spec/tripod/eager_loading_spec.rb +4 -4
- data/spec/tripod/graphs_spec.rb +26 -0
- data/spec/tripod/memcached_cache_store_spec.rb +57 -0
- data/spec/tripod/persistence_spec.rb +21 -3
- data/tripod.gemspec +2 -1
- metadata +23 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0d0bb81441871fbdb4115e399bca413f309c7c4
|
4
|
+
data.tar.gz: 3b72bae40446b70dd252383f82193c4764a2b669
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 614d0632c00fd4b5c99347f035fad525a2e9a9cf9240cd9376bf1c6fa1585ccda99a28ff0c8f74c988f7c8480723845195b6ffc74d05b5a7c1321ba849436062
|
7
|
+
data.tar.gz: 515dafcdb449015ef2b8728b00c65687f3d777e232022e34e9d96311a77229a7c9b2eea7332ea6dae7c19c34ba34a52e2b6117bc038fa81314cbba64b819b795
|
data/README.md
CHANGED
@@ -134,6 +134,8 @@ Tripod doesn't supply a database. You need to install one. I recommend [Fuseki](
|
|
134
134
|
|
135
135
|
With a Fuseki instance ready and up, edit the config in `spec/spec_helper.rb` to reflect your settings. Make sure you `bundle` to pull in all dependencies before trying to run the tests.
|
136
136
|
|
137
|
+
Some tests require memcached to be set up and running. The tests that require memcached are tagged with `:caching_tests => true`; do with this information what you will.
|
138
|
+
|
137
139
|
[Full Documentation](http://rubydoc.info/gems/tripod/frames)
|
138
140
|
|
139
141
|
Copyright (c) 2012 [Swirrl IT Limited](http://swirrl.com). Released under MIT License
|
data/lib/tripod.rb
CHANGED
@@ -70,6 +70,7 @@ module Tripod
|
|
70
70
|
# config.cache_store = nil #e.g Tripod::CacheStores::MemcachedCacheStore.new('localhost:11211')
|
71
71
|
# # note: if using memcached, make sure you set the -I (slab size) to big enough to store each result
|
72
72
|
# # and set the -m (total size) to something quite big (or the cache will recycle too often).
|
73
|
+
# # also note that the connection pool size can be passed in as an optional second parameter.
|
73
74
|
# config.logger = Logger.new(STDOUT) # you can set this to the Rails.logger in a rails app.
|
74
75
|
# end
|
75
76
|
#
|
@@ -100,6 +101,7 @@ require "tripod/persistence"
|
|
100
101
|
require "tripod/eager_loading"
|
101
102
|
require "tripod/serialization"
|
102
103
|
require "tripod/state"
|
104
|
+
require "tripod/graphs"
|
103
105
|
require "tripod/version"
|
104
106
|
|
105
107
|
# these need to be at the end
|
@@ -107,4 +109,5 @@ require "tripod/components"
|
|
107
109
|
require "tripod/resource"
|
108
110
|
|
109
111
|
require 'active_support/i18n'
|
110
|
-
I18n.
|
112
|
+
I18n.enforce_available_locales = true
|
113
|
+
I18n.load_path << File.dirname(__FILE__) + '/tripod/locale/en.yml'
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'dalli'
|
2
|
+
require 'connection_pool'
|
2
3
|
|
3
4
|
module Tripod
|
4
5
|
module CacheStores
|
@@ -9,33 +10,50 @@ module Tripod
|
|
9
10
|
class MemcachedCacheStore
|
10
11
|
|
11
12
|
# initialize a memcached cache store at the specified port (default 'localhost:11211')
|
12
|
-
|
13
|
-
|
13
|
+
# a pool size should also be specified (defaults to 1 for development/local use reasons)
|
14
|
+
def initialize(location, size = 1)
|
15
|
+
@dalli_pool = ConnectionPool.new(:size => size, :timeout => 3) { Dalli::Client.new(location, :value_max_bytes => Tripod.response_limit_bytes) }
|
14
16
|
end
|
15
17
|
|
16
18
|
# takes a block
|
17
19
|
def fetch(key)
|
18
20
|
raise ArgumentError.new("expected a block") unless block_given?
|
19
21
|
|
20
|
-
@
|
21
|
-
yield
|
22
|
+
@dalli_pool.with do |client|
|
23
|
+
client.fetch(key) { yield }
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
25
27
|
def exist?(key)
|
26
|
-
|
28
|
+
@dalli_pool.with do |client|
|
29
|
+
!!client.get(key)
|
30
|
+
end
|
27
31
|
end
|
28
32
|
|
29
33
|
def write(key, data)
|
30
|
-
@
|
34
|
+
@dalli_pool.with do |client|
|
35
|
+
client.set(key, data)
|
36
|
+
end
|
31
37
|
end
|
32
38
|
|
33
39
|
def read(key)
|
34
|
-
@
|
40
|
+
@dalli_pool.with do |client|
|
41
|
+
client.get(key)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def stats
|
46
|
+
output = []
|
47
|
+
@dalli_pool.with do |client|
|
48
|
+
output << client.stats
|
49
|
+
end
|
50
|
+
output
|
35
51
|
end
|
36
52
|
|
37
53
|
def clear!
|
38
|
-
@
|
54
|
+
@dalli_pool.with do |client|
|
55
|
+
client.flush
|
56
|
+
end
|
39
57
|
end
|
40
58
|
|
41
59
|
end
|
data/lib/tripod/components.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# This module defines behaviour for resources with data across multiple graphs
|
4
|
+
module Tripod::Graphs
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
def graphs
|
8
|
+
select_query = "SELECT DISTINCT ?g WHERE { GRAPH ?g {<#{uri.to_s}> ?p ?o } }"
|
9
|
+
result = Tripod::SparqlClient::Query.select(select_query)
|
10
|
+
result.map{|r| r["g"]["value"]}
|
11
|
+
end
|
12
|
+
end
|
data/lib/tripod/persistence.rb
CHANGED
@@ -73,9 +73,9 @@ module Tripod::Persistence
|
|
73
73
|
transaction = Tripod::Persistence::Transaction.get_transaction(opts[:transaction])
|
74
74
|
|
75
75
|
if self.valid?
|
76
|
-
|
76
|
+
graph_selector = self.graph_uri.present? ? "<#{graph_uri.to_s}>" : "?g"
|
77
77
|
query = "
|
78
|
-
DELETE {GRAPH
|
78
|
+
DELETE {GRAPH #{graph_selector} {<#{@uri.to_s}> ?p ?o}} WHERE {GRAPH #{graph_selector} {<#{@uri.to_s}> ?p ?o}};
|
79
79
|
INSERT DATA {
|
80
80
|
GRAPH <#{@graph_uri}> {
|
81
81
|
#{ @repository.dump(:ntriples) }
|
@@ -174,4 +174,4 @@ module Tripod::Persistence
|
|
174
174
|
|
175
175
|
end
|
176
176
|
|
177
|
-
end
|
177
|
+
end
|
data/lib/tripod/version.rb
CHANGED
@@ -143,13 +143,13 @@ describe Tripod::EagerLoading do
|
|
143
143
|
context "when eager load not called" do
|
144
144
|
context "and related resource exists" do
|
145
145
|
it "should return false" do
|
146
|
-
@john.has_related_resource?(RDF::URI.new('http://example.com/name'), Resource).should
|
146
|
+
@john.has_related_resource?(RDF::URI.new('http://example.com/name'), Resource).should be false
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
150
|
context "and related resource doesn't exist" do
|
151
151
|
it "should return false" do
|
152
|
-
@john.has_related_resource?(RDF::URI.new('http://example.com/nonexistent/person'), Person).should
|
152
|
+
@john.has_related_resource?(RDF::URI.new('http://example.com/nonexistent/person'), Person).should be false
|
153
153
|
end
|
154
154
|
end
|
155
155
|
end
|
@@ -161,13 +161,13 @@ describe Tripod::EagerLoading do
|
|
161
161
|
|
162
162
|
context "and related resource exists" do
|
163
163
|
it "should return true" do
|
164
|
-
@john.has_related_resource?(RDF::URI.new('http://example.com/name'), Resource).should
|
164
|
+
@john.has_related_resource?(RDF::URI.new('http://example.com/name'), Resource).should be true
|
165
165
|
end
|
166
166
|
end
|
167
167
|
|
168
168
|
context "and related resource doesn't exist" do
|
169
169
|
it "should return false" do
|
170
|
-
@john.has_related_resource?(RDF::URI.new('http://example.com/nonexistent/person'), Person).should
|
170
|
+
@john.has_related_resource?(RDF::URI.new('http://example.com/nonexistent/person'), Person).should be false
|
171
171
|
end
|
172
172
|
end
|
173
173
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Tripod::Graphs do
|
4
|
+
describe "#graphs" do
|
5
|
+
let(:uri) { 'http://example.com/foobar' }
|
6
|
+
let(:graph_uri) { 'http://example.com/irl' }
|
7
|
+
let(:another_graph_uri) { 'http://example.com/make-believe' }
|
8
|
+
let(:person) do
|
9
|
+
p = Person.new(uri, graph_uri: graph_uri)
|
10
|
+
p.write_predicate('http://example.com/vocation', RDF::URI.new('http://example.com/accountant'))
|
11
|
+
p.save!
|
12
|
+
p
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
p2 = Person.new(uri, graph_uri: another_graph_uri)
|
17
|
+
p2.write_predicate('http://example.com/vocation', RDF::URI.new('http://example.com/lion-tamer'))
|
18
|
+
p2.save!
|
19
|
+
p2
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should return an array of all the graphs for which there are triples about this URI' do
|
23
|
+
person.graphs.should =~ [graph_uri, another_graph_uri]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Tripod::CacheStores, :caching_tests => true do
|
4
|
+
|
5
|
+
let(:query) { "SELECT * WHERE {?s ?p ?o}" }
|
6
|
+
let(:accept_header) { "application/sparql-results+json" }
|
7
|
+
let(:params) { {:query => query}.to_query }
|
8
|
+
let(:streaming_opts) { {:accept => accept_header, :timeout_seconds => Tripod.timeout_seconds} }
|
9
|
+
|
10
|
+
before do
|
11
|
+
Tripod.cache_store = Tripod::CacheStores::MemcachedCacheStore.new('localhost:11211', 10)
|
12
|
+
|
13
|
+
p = Person.new('http://example.com/id/garry')
|
14
|
+
p.name = "garry"
|
15
|
+
p.save!
|
16
|
+
p
|
17
|
+
end
|
18
|
+
|
19
|
+
# if Tripod cache_store is not reset to nil, other tests will fail due to caching
|
20
|
+
after(:all) do
|
21
|
+
Tripod.cache_store = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "sending a query with caching enabled" do
|
25
|
+
before do
|
26
|
+
@query_result = Tripod::SparqlClient::Query.query(query, accept_header)
|
27
|
+
@cache_key = 'SPARQL-QUERY-' + Digest::SHA2.hexdigest([accept_header, query].join("-"))
|
28
|
+
@stream_data = -> { Tripod::Streaming.get_data(Tripod.query_endpoint, params, streaming_opts) }
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should set the data in the cache" do
|
32
|
+
Tripod.cache_store.fetch(@cache_key, &@stream_data).should_not be_nil
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "with a large number of subsequent requests" do
|
36
|
+
before do
|
37
|
+
@number_of_memcache_get_calls = Tripod.cache_store.stats[0]["localhost:11211"]["cmd_get"]
|
38
|
+
@number_of_memcache_set_calls = Tripod.cache_store.stats[0]["localhost:11211"]["cmd_set"]
|
39
|
+
|
40
|
+
100.times do
|
41
|
+
Thread.new do
|
42
|
+
Tripod::SparqlClient::Query.query(query, accept_header)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should increase number of memcache get calls" do
|
48
|
+
Tripod.cache_store.stats[0]["localhost:11211"]["cmd_get"].to_i.should be > @number_of_memcache_get_calls.to_i
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should not increase cache size" do
|
52
|
+
Tripod.cache_store.stats[0]["localhost:11211"]["cmd_set"].to_i.should == @number_of_memcache_set_calls.to_i
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -63,6 +63,24 @@ describe Tripod::Persistence do
|
|
63
63
|
p2.repository.dump(:ntriples).should == saved_person.repository.dump(:ntriples)
|
64
64
|
end
|
65
65
|
|
66
|
+
context 'given triples about this resource in another graph' do
|
67
|
+
let(:graph_uri) { 'http://example.com/my_other_life' }
|
68
|
+
let(:father) { RDF::URI.new('http://example.com/vader') }
|
69
|
+
|
70
|
+
before do
|
71
|
+
p = Person.new(saved_person.uri, graph_uri: graph_uri)
|
72
|
+
p.father = father
|
73
|
+
p.save!
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should leave those triples untouched' do
|
77
|
+
saved_person.name = 'Luke'
|
78
|
+
saved_person.save!
|
79
|
+
p = Person.find(saved_person.uri, graph_uri: graph_uri)
|
80
|
+
p.father.should == father
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
66
84
|
it 'runs the callbacks' do
|
67
85
|
unsaved_person.should_receive(:pre_save)
|
68
86
|
unsaved_person.save
|
@@ -95,7 +113,7 @@ describe Tripod::Persistence do
|
|
95
113
|
|
96
114
|
describe '.update_attribute' do
|
97
115
|
let (:person) { Person.new('http://example.com/newperson') }
|
98
|
-
|
116
|
+
|
99
117
|
context 'without transactions' do
|
100
118
|
before { person.stub(:save) }
|
101
119
|
|
@@ -136,7 +154,7 @@ describe Tripod::Persistence do
|
|
136
154
|
|
137
155
|
describe '.update_attributes' do
|
138
156
|
let (:person) { Person.new('http://example.com/newperson') }
|
139
|
-
|
157
|
+
|
140
158
|
context "without transactions" do
|
141
159
|
before { person.stub(:save) }
|
142
160
|
|
@@ -246,4 +264,4 @@ describe Tripod::Persistence do
|
|
246
264
|
|
247
265
|
end
|
248
266
|
|
249
|
-
end
|
267
|
+
end
|
data/tripod.gemspec
CHANGED
@@ -27,5 +27,6 @@ Gem::Specification.new do |gem|
|
|
27
27
|
gem.add_dependency "rdf-json"
|
28
28
|
gem.add_dependency "json-ld", "~> 0.9.1" # use v.0.9 for now, as v1.0 changes what is returned for dumping a resource to include other defined resources.
|
29
29
|
gem.add_dependency "guid"
|
30
|
-
gem.add_dependency "dalli", "~> 2.
|
30
|
+
gem.add_dependency "dalli", "~> 2.7.0"
|
31
|
+
gem.add_dependency "connection_pool", "~> 2.0.0"
|
31
32
|
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.9.
|
4
|
+
version: 0.9.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ric Roberts
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2014-06-
|
13
|
+
date: 2014-06-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rest-client
|
@@ -144,14 +144,28 @@ dependencies:
|
|
144
144
|
requirements:
|
145
145
|
- - "~>"
|
146
146
|
- !ruby/object:Gem::Version
|
147
|
-
version:
|
147
|
+
version: 2.7.0
|
148
148
|
type: :runtime
|
149
149
|
prerelease: false
|
150
150
|
version_requirements: !ruby/object:Gem::Requirement
|
151
151
|
requirements:
|
152
152
|
- - "~>"
|
153
153
|
- !ruby/object:Gem::Version
|
154
|
-
version:
|
154
|
+
version: 2.7.0
|
155
|
+
- !ruby/object:Gem::Dependency
|
156
|
+
name: connection_pool
|
157
|
+
requirement: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - "~>"
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: 2.0.0
|
162
|
+
type: :runtime
|
163
|
+
prerelease: false
|
164
|
+
version_requirements: !ruby/object:Gem::Requirement
|
165
|
+
requirements:
|
166
|
+
- - "~>"
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: 2.0.0
|
155
169
|
description: RDF ruby ORM
|
156
170
|
email:
|
157
171
|
- ric@swirrl.com
|
@@ -192,6 +206,7 @@ files:
|
|
192
206
|
- lib/tripod/fields.rb
|
193
207
|
- lib/tripod/fields/standard.rb
|
194
208
|
- lib/tripod/finders.rb
|
209
|
+
- lib/tripod/graphs.rb
|
195
210
|
- lib/tripod/locale/en.yml
|
196
211
|
- lib/tripod/persistence.rb
|
197
212
|
- lib/tripod/predicates.rb
|
@@ -214,6 +229,8 @@ files:
|
|
214
229
|
- spec/tripod/eager_loading_spec.rb
|
215
230
|
- spec/tripod/fields_spec.rb
|
216
231
|
- spec/tripod/finders_spec.rb
|
232
|
+
- spec/tripod/graphs_spec.rb
|
233
|
+
- spec/tripod/memcached_cache_store_spec.rb
|
217
234
|
- spec/tripod/persistence_spec.rb
|
218
235
|
- spec/tripod/predicates_spec.rb
|
219
236
|
- spec/tripod/repository_spec.rb
|
@@ -258,6 +275,8 @@ test_files:
|
|
258
275
|
- spec/tripod/eager_loading_spec.rb
|
259
276
|
- spec/tripod/fields_spec.rb
|
260
277
|
- spec/tripod/finders_spec.rb
|
278
|
+
- spec/tripod/graphs_spec.rb
|
279
|
+
- spec/tripod/memcached_cache_store_spec.rb
|
261
280
|
- spec/tripod/persistence_spec.rb
|
262
281
|
- spec/tripod/predicates_spec.rb
|
263
282
|
- spec/tripod/repository_spec.rb
|