roadforest 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/file-management.rb +7 -1
- data/lib/roadforest/application.rb +0 -2
- data/lib/roadforest/application/dispatcher.rb +20 -1
- data/lib/roadforest/model.rb +4 -4
- data/lib/roadforest/rdf/{context-fascade.rb → access-manager.rb} +96 -42
- data/lib/roadforest/rdf/focus-list.rb +1 -1
- data/lib/roadforest/rdf/graph-copier.rb +10 -5
- data/lib/roadforest/rdf/graph-focus.rb +222 -32
- data/lib/roadforest/rdf/graph-store.rb +1 -12
- data/lib/roadforest/rdf/investigation.rb +3 -1
- data/lib/roadforest/rdf/post-focus.rb +7 -15
- data/lib/roadforest/remote-host.rb +20 -8
- data/lib/roadforest/resource/rdf/read-only.rb +5 -2
- data/lib/roadforest/test-support/matchers.rb +40 -9
- data/lib/roadforest/utility/class-registry.rb +8 -1
- data/spec/focus-list.rb +7 -1
- data/spec/graph-copier.rb +27 -43
- data/spec/graph-store.rb +41 -15
- data/spec/update-focus.rb +10 -8
- metadata +63 -12
- data/lib/roadforest/rdf/graph-reading.rb +0 -200
- data/lib/roadforest/rdf/update-focus.rb +0 -18
- data/lib/roadforest/resource/handlers.rb +0 -43
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'rdf'
|
2
|
-
require 'roadforest/rdf/graph-focus'
|
3
2
|
require 'roadforest/rdf/vocabulary'
|
4
3
|
require 'roadforest/rdf/normalization'
|
5
4
|
|
@@ -47,8 +46,6 @@ module RoadForest::RDF
|
|
47
46
|
end
|
48
47
|
alias raw_quiet_impulse? quiet_impulse?
|
49
48
|
|
50
|
-
#repo cleanup - expired graphs
|
51
|
-
|
52
49
|
def reader_for(content_type, repository)
|
53
50
|
RDF::Reader.for(content_type)
|
54
51
|
end
|
@@ -100,15 +97,7 @@ module RoadForest::RDF
|
|
100
97
|
end
|
101
98
|
#puts; puts "#{__FILE__}:#{__LINE__} => \n#{(graph_dump(:nquads))}"
|
102
99
|
end
|
103
|
-
|
104
|
-
def insert_graph(context, graph)
|
105
|
-
context = normalize_context(context)
|
106
|
-
delete_statements(:context => context)
|
107
|
-
graph.each_statement do |statement|
|
108
|
-
statement.context = context
|
109
|
-
record_statement(statement)
|
110
|
-
end
|
111
|
-
end
|
100
|
+
alias insert_graph insert_reader
|
112
101
|
|
113
102
|
def add_statement(*args)
|
114
103
|
case args.length
|
@@ -74,7 +74,9 @@ module RoadForest::RDF
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def results_for_context(context)
|
77
|
-
results.find_all
|
77
|
+
results.find_all do |item|
|
78
|
+
item.context == context
|
79
|
+
end
|
78
80
|
end
|
79
81
|
|
80
82
|
#XXX Do we need the nil result if context_metadata is empty?
|
@@ -2,10 +2,7 @@ require 'roadforest/rdf/graph-focus'
|
|
2
2
|
|
3
3
|
module RoadForest::RDF
|
4
4
|
class PostFocus < GraphFocus
|
5
|
-
|
6
|
-
super(subject, graph, rigor)
|
7
|
-
@graphs = {}
|
8
|
-
end
|
5
|
+
|
9
6
|
attr_accessor :graphs
|
10
7
|
|
11
8
|
def dup
|
@@ -14,22 +11,17 @@ module RoadForest::RDF
|
|
14
11
|
other
|
15
12
|
end
|
16
13
|
|
17
|
-
def graph_transfer
|
18
|
-
source_rigor.graph_transfer
|
19
|
-
end
|
20
|
-
|
21
14
|
def post_to
|
22
15
|
graph = ::RDF::Graph.new
|
23
|
-
|
16
|
+
access = WriteManager.new
|
17
|
+
access.rigor = access_manager.rigor
|
18
|
+
access.source_graph = graph
|
19
|
+
focus = GraphFocus.new(access, subject)
|
20
|
+
|
24
21
|
graphs[subject] = graph
|
22
|
+
|
25
23
|
yield focus if block_given?
|
26
24
|
return focus
|
27
25
|
end
|
28
|
-
|
29
|
-
def send_graphs
|
30
|
-
@graphs.each_pair do |url, graph|
|
31
|
-
graph_transfer.post(url, graph)
|
32
|
-
end
|
33
|
-
end
|
34
26
|
end
|
35
27
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'roadforest/rdf/source-rigor'
|
2
2
|
require 'roadforest/rdf/source-rigor/credence-annealer'
|
3
|
+
require 'roadforest/rdf/graph-store'
|
3
4
|
require 'roadforest/http/graph-transfer'
|
4
5
|
require 'roadforest/http/adapters/excon'
|
5
|
-
require 'roadforest/rdf/graph-store'
|
6
6
|
|
7
7
|
module RoadForest
|
8
8
|
class RemoteHost
|
@@ -54,17 +54,19 @@ module RoadForest
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def putting(&block)
|
57
|
-
require 'roadforest/rdf/update-focus'
|
58
57
|
graph = build_graph_store
|
59
|
-
|
58
|
+
access = RDF::UpdateManager.new
|
59
|
+
access.rigor = source_rigor
|
60
|
+
access.source_graph = graph
|
61
|
+
updater = RDF::GraphFocus.new(access, url)
|
60
62
|
annealer = RDF::SourceRigor::CredenceAnnealer.new(graph)
|
61
63
|
|
62
64
|
annealer.resolve do
|
63
|
-
|
65
|
+
access.target_graph = ::RDF::Repository.new
|
64
66
|
yield updater
|
65
67
|
end
|
66
68
|
|
67
|
-
target_graph =
|
69
|
+
target_graph = access.target_graph
|
68
70
|
target_graph.each_context do |context|
|
69
71
|
graph = ::RDF::Graph.new(context, :data => target_graph)
|
70
72
|
graph_transfer.put(context, graph)
|
@@ -74,16 +76,26 @@ module RoadForest
|
|
74
76
|
def posting(&block)
|
75
77
|
require 'roadforest/rdf/post-focus'
|
76
78
|
graph = build_graph_store
|
77
|
-
|
79
|
+
access = RDF::PostManager.new
|
80
|
+
access.rigor = source_rigor
|
81
|
+
access.source_graph = graph
|
82
|
+
poster = RDF::PostFocus.new(access, url)
|
83
|
+
graphs = {}
|
84
|
+
poster.graphs = graphs
|
78
85
|
|
79
86
|
anneal(poster, &block)
|
80
87
|
|
81
|
-
|
88
|
+
graphs.each_pair do |url, graph|
|
89
|
+
graph_transfer.post(url, graph)
|
90
|
+
end
|
82
91
|
end
|
83
92
|
|
84
93
|
def getting(&block)
|
85
94
|
graph = build_graph_store
|
86
|
-
|
95
|
+
access = RDF::ReadOnlyManager.new
|
96
|
+
access.rigor = source_rigor
|
97
|
+
access.source_graph = graph
|
98
|
+
reader = RDF::GraphFocus.new(access, url)
|
87
99
|
|
88
100
|
anneal(reader, &block)
|
89
101
|
end
|
@@ -1,13 +1,16 @@
|
|
1
|
-
require 'roadforest/resource/handlers'
|
2
1
|
require 'roadforest/application/parameters'
|
2
|
+
require 'roadforest/utility/class-registry'
|
3
3
|
|
4
4
|
module RoadForest
|
5
5
|
module Resource
|
6
|
+
def self.registry_purpose; "resource type"; end
|
7
|
+
extend Utility::ClassRegistry::Registrar
|
8
|
+
|
6
9
|
module RDF
|
7
10
|
#Used for a resource that presents a read-only representation
|
8
11
|
class ReadOnly < Webmachine::Resource
|
9
12
|
def self.register(method_name)
|
10
|
-
|
13
|
+
RoadForest::Resource.registry.add(method_name, self)
|
11
14
|
end
|
12
15
|
|
13
16
|
register :read_only
|
@@ -1,8 +1,15 @@
|
|
1
1
|
module RoadForest
|
2
2
|
module Testing
|
3
3
|
class MatchesQuery
|
4
|
-
def initialize(&block)
|
5
|
-
|
4
|
+
def initialize(pattern = nil, &block)
|
5
|
+
pattern ||= []
|
6
|
+
if Hash === pattern
|
7
|
+
pattern = [pattern]
|
8
|
+
end
|
9
|
+
pattern = pattern.map do |item|
|
10
|
+
::RDF::Query::Pattern.from(item)
|
11
|
+
end
|
12
|
+
@query = ::RDF::Query.new(pattern, &block)
|
6
13
|
end
|
7
14
|
|
8
15
|
def matches?(actual)
|
@@ -12,7 +19,11 @@ module RoadForest
|
|
12
19
|
end
|
13
20
|
|
14
21
|
def failure_message_for_should
|
15
|
-
"expected #{@query.inspect} to return solutions on #{@actual.
|
22
|
+
"expected #{@query.patterns.inspect} to return solutions on \n#{@actual.dump(:nquads)}\n but didn't"
|
23
|
+
end
|
24
|
+
|
25
|
+
def failure_message_for_should_not
|
26
|
+
"expected #{@query.patterns.inspect} not to return solutions on \n#{@actual.dump(:nquads)}\n but does"
|
16
27
|
end
|
17
28
|
end
|
18
29
|
|
@@ -21,15 +32,33 @@ module RoadForest
|
|
21
32
|
@expected = expected
|
22
33
|
end
|
23
34
|
|
35
|
+
def subtract(one, other)
|
36
|
+
sorted = one.sort_by{|stmt| stmt.to_a}
|
37
|
+
one.find_all do |expected_stmt|
|
38
|
+
not other.any? do |actual_stmt|
|
39
|
+
actual_stmt.eql? expected_stmt
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def missing
|
45
|
+
@missing ||= subtract(@expected, @actual)
|
46
|
+
end
|
47
|
+
|
48
|
+
def surplus
|
49
|
+
@surplus ||= subtract(@actual, @expected)
|
50
|
+
end
|
51
|
+
|
24
52
|
def matches?(actual)
|
25
53
|
@actual = actual
|
26
|
-
|
27
|
-
@expected_extra = @expected - @actual
|
28
|
-
@actual_extra.empty? and @expected_extra.empty?
|
54
|
+
missing.empty? and surplus.empty?
|
29
55
|
end
|
30
56
|
|
31
57
|
def failure_message_for_should
|
32
|
-
"expected #{@actual.
|
58
|
+
"expected [\n #{@actual.map(&:to_s).join("\n ")}\n] " +
|
59
|
+
"to have the same elements as [\n #{@expected.map(&:to_s).join("\n ")}\n]\n\n" +
|
60
|
+
"missing: [\n #{missing.map(&:to_s).join("\n ")}\n]\n" +
|
61
|
+
"surplus: [\n #{surplus.map(&:to_s).join("\n ")}]"
|
33
62
|
end
|
34
63
|
end
|
35
64
|
|
@@ -41,6 +70,8 @@ module RoadForest
|
|
41
70
|
def that_match_query(query)
|
42
71
|
@graph.query(query).to_a
|
43
72
|
end
|
73
|
+
alias that_match that_match_query
|
74
|
+
alias that_match_pattern that_match_query
|
44
75
|
end
|
45
76
|
|
46
77
|
module HelperMethods
|
@@ -50,8 +81,8 @@ module RoadForest
|
|
50
81
|
end
|
51
82
|
|
52
83
|
module MatcherMethods
|
53
|
-
def match_query(&block)
|
54
|
-
MatchesQuery.new(&block)
|
84
|
+
def match_query(pattern = nil, &block)
|
85
|
+
MatchesQuery.new(pattern, &block)
|
55
86
|
end
|
56
87
|
|
57
88
|
def be_equivalent_to(list)
|
@@ -1,6 +1,12 @@
|
|
1
1
|
module RoadForest
|
2
2
|
module Utility
|
3
3
|
class ClassRegistry
|
4
|
+
#Extend a module with this in order to make it the registrar for a
|
5
|
+
#particular purpose.
|
6
|
+
#The top of a class heirarchy will make "register" immediately available
|
7
|
+
#to subclasses. Otherwise, classes can say Module::registry.add(name,
|
8
|
+
#self)
|
9
|
+
#
|
4
10
|
module Registrar
|
5
11
|
def registry
|
6
12
|
@registry ||= ClassRegistry.new(self)
|
@@ -10,9 +16,10 @@ module RoadForest
|
|
10
16
|
registrar.registry.add(name, self)
|
11
17
|
end
|
12
18
|
|
13
|
-
def
|
19
|
+
def get(name)
|
14
20
|
registrar.registry.get(name)
|
15
21
|
end
|
22
|
+
alias [] get
|
16
23
|
|
17
24
|
def self.extended(mod)
|
18
25
|
(
|
data/spec/focus-list.rb
CHANGED
@@ -7,8 +7,14 @@ describe RoadForest::RDF::FocusList do
|
|
7
7
|
RDF::Graph.new
|
8
8
|
end
|
9
9
|
|
10
|
+
let :access do
|
11
|
+
RoadForest::RDF::WriteManager.new.tap do |access|
|
12
|
+
access.source_graph = graph
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
10
16
|
let :focus do
|
11
|
-
RoadForest::RDF::GraphFocus.new("urn:root"
|
17
|
+
RoadForest::RDF::GraphFocus.new(access, "urn:root")
|
12
18
|
end
|
13
19
|
|
14
20
|
let :list do
|
data/spec/graph-copier.rb
CHANGED
@@ -1,19 +1,7 @@
|
|
1
1
|
require 'roadforest/test-support/matchers'
|
2
2
|
require 'roadforest/rdf/graph-copier'
|
3
3
|
|
4
|
-
|
5
|
-
#
|
6
|
-
#GC needs to tessellate the graph in the same way that Parceller should -
|
7
|
-
#probably should make sure that works first. Basically same resource should ==
|
8
|
-
#same subgraph copied, since otherwise client omission of a property isn't
|
9
|
-
#distinguishable from the intent to delete it. Only copy once so that you don't
|
10
|
-
#overwrite client changes.
|
11
|
-
#
|
12
|
-
#Also: "single put" involves a whole extra level of server code to accept the
|
13
|
-
#put, parcel it out, confirm IMS headers across everyone... so that's a v2
|
14
|
-
#feature
|
15
|
-
|
16
|
-
describe RoadForest::RDF::GraphCopier, :pending => "review of API" do
|
4
|
+
describe RoadForest::RDF::GraphFocus, "with a CopyManager" do
|
17
5
|
class TestVoc < ::RDF::Vocabulary("http://test.com/");end
|
18
6
|
|
19
7
|
let :start_subject do
|
@@ -27,12 +15,7 @@ describe RoadForest::RDF::GraphCopier, :pending => "review of API" do
|
|
27
15
|
let :starting_statements do
|
28
16
|
[
|
29
17
|
[start_subject, TestVoc[:a], 7],
|
30
|
-
[start_subject, TestVoc[:other], other_subject]
|
31
|
-
]
|
32
|
-
end
|
33
|
-
|
34
|
-
let :other_statements do
|
35
|
-
[
|
18
|
+
[start_subject, TestVoc[:other], other_subject],
|
36
19
|
[other_subject, TestVoc[:a], 13]
|
37
20
|
]
|
38
21
|
end
|
@@ -42,46 +25,47 @@ describe RoadForest::RDF::GraphCopier, :pending => "review of API" do
|
|
42
25
|
starting_statements.each do |stmt|
|
43
26
|
graph << stmt
|
44
27
|
end
|
45
|
-
|
46
|
-
other_statements.each do |stmt|
|
47
|
-
graph << stmt
|
48
|
-
end
|
49
28
|
end
|
50
29
|
end
|
51
30
|
|
52
|
-
let :
|
53
|
-
|
54
|
-
doc.source =
|
55
|
-
doc.body_string = source_graph.dump(:rdfa)
|
56
|
-
end
|
31
|
+
let :target_graph do
|
32
|
+
::RDF::Graph.new
|
57
33
|
end
|
58
34
|
|
59
|
-
let :
|
60
|
-
RoadForest::RDF::
|
61
|
-
|
62
|
-
|
35
|
+
let :access do
|
36
|
+
RoadForest::RDF::CopyManager.new.tap do |access|
|
37
|
+
access.source_graph = source_graph
|
38
|
+
access.target_graph = target_graph
|
63
39
|
end
|
64
40
|
end
|
65
41
|
|
66
|
-
|
67
|
-
|
42
|
+
let :copier do
|
43
|
+
RoadForest::RDF::GraphFocus.new(access, start_subject)
|
68
44
|
end
|
69
45
|
|
70
|
-
|
71
|
-
|
72
|
-
end
|
46
|
+
#copier needs URL accessor
|
47
|
+
|
73
48
|
|
74
|
-
|
75
|
-
|
49
|
+
|
50
|
+
it "should not copy statements without action" do
|
51
|
+
target_graph.should_not match_query(:subject => start_subject)
|
76
52
|
end
|
77
53
|
|
78
|
-
it "should
|
79
|
-
copier
|
54
|
+
it "should copy statements that are queried" do
|
55
|
+
copier[[:testvoc, :other]]
|
56
|
+
|
57
|
+
statements_from_graph(target_graph).that_match_query(:predicate => TestVoc[:other]).should(
|
58
|
+
be_equivalent_to(statements_from_graph(source_graph).that_match_query(:predicate => TestVoc[:other]))
|
59
|
+
)
|
60
|
+
target_graph.should_not match_query(:predicate => TestVoc[:a])
|
80
61
|
end
|
81
62
|
|
82
|
-
it "should
|
63
|
+
it "should not double copy statements that are queried twice" do
|
64
|
+
copier[[:testvoc, :other]]
|
83
65
|
copier[[:testvoc, :other]]
|
84
66
|
|
85
|
-
statements_from_graph(
|
67
|
+
statements_from_graph(target_graph).that_match_query(:predicate => TestVoc[:other]).should(
|
68
|
+
be_equivalent_to(statements_from_graph(source_graph).that_match_query(:predicate => TestVoc[:other]))
|
69
|
+
)
|
86
70
|
end
|
87
71
|
end
|
data/spec/graph-store.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'rdf'
|
2
|
-
|
2
|
+
require 'rdf/rdfa'
|
3
3
|
require 'roadforest/rdf/document'
|
4
4
|
require 'roadforest/rdf/graph-store'
|
5
|
+
require 'roadforest/rdf/graph-focus'
|
6
|
+
require 'roadforest/rdf/source-rigor'
|
5
7
|
|
6
8
|
describe RoadForest::RDF do
|
7
9
|
let :source_rigor do
|
@@ -20,7 +22,11 @@ describe RoadForest::RDF do
|
|
20
22
|
describe RoadForest::RDF::GraphStore do
|
21
23
|
let :root_body do
|
22
24
|
store = RoadForest::RDF::GraphStore.new
|
23
|
-
|
25
|
+
access = RoadForest::RDF::WriteManager.new
|
26
|
+
access.source_graph = store
|
27
|
+
access.rigor = source_rigor
|
28
|
+
step = RoadForest::RDF::GraphFocus.new(access, "http://lrdesign.com/test-rdf")
|
29
|
+
|
24
30
|
step[[:foaf, :givenname]] = "Lester"
|
25
31
|
step[[:dc, :date]] = Time.now
|
26
32
|
step = step.node_at([:dc, :related], "http://lrdesign.com/test-rdf/sub")
|
@@ -31,7 +37,11 @@ describe RoadForest::RDF do
|
|
31
37
|
|
32
38
|
let :second_body do
|
33
39
|
store = RoadForest::RDF::GraphStore.new
|
34
|
-
|
40
|
+
access = RoadForest::RDF::WriteManager.new
|
41
|
+
access.source_graph = store
|
42
|
+
access.rigor = source_rigor
|
43
|
+
step = RoadForest::RDF::GraphFocus.new(access, "http://lrdesign.com/test-rdf")
|
44
|
+
|
35
45
|
step[[:foaf, :givenname]] = "Foster"
|
36
46
|
step[[:dc, :date]] = Time.now
|
37
47
|
|
@@ -52,12 +62,18 @@ describe RoadForest::RDF do
|
|
52
62
|
end
|
53
63
|
end
|
54
64
|
|
65
|
+
let :step do
|
66
|
+
access = RoadForest::RDF::WriteManager.new
|
67
|
+
access.source_graph = graph_store
|
68
|
+
access.rigor = source_rigor
|
69
|
+
RoadForest::RDF::GraphFocus.new(access, "http://lrdesign.com/test-rdf")
|
70
|
+
end
|
71
|
+
|
55
72
|
before :each do
|
56
73
|
graph_store.insert_document(first_doc)
|
57
74
|
end
|
58
75
|
|
59
76
|
it "should transmit properties" do
|
60
|
-
step = RoadForest::RDF::GraphFocus.new("http://lrdesign.com/test-rdf", graph_store, source_rigor)
|
61
77
|
step[:dc, :date].should be_an_instance_of(Time)
|
62
78
|
end
|
63
79
|
|
@@ -65,7 +81,7 @@ describe RoadForest::RDF do
|
|
65
81
|
expect{
|
66
82
|
graph_store.insert_document(second_doc)
|
67
83
|
}.to change{
|
68
|
-
|
84
|
+
step[:foaf, :givenname]
|
69
85
|
}
|
70
86
|
end
|
71
87
|
end
|
@@ -83,16 +99,27 @@ describe RoadForest::RDF do
|
|
83
99
|
RDF::Node.new
|
84
100
|
end
|
85
101
|
|
102
|
+
let :graph_store do
|
103
|
+
RDF::Graph.new
|
104
|
+
end
|
105
|
+
|
86
106
|
before :each do
|
87
|
-
graph_store.
|
88
|
-
graph_store.
|
89
|
-
graph_store.
|
90
|
-
graph_store.
|
91
|
-
graph_store.
|
107
|
+
graph_store.insert([root, ::RDF::DC.relation, main_subject])
|
108
|
+
graph_store.insert([creator, ::RDF::FOAF.familyName, "Lester"])
|
109
|
+
graph_store.insert([creator, ::RDF::FOAF.givenname, "Judson"])
|
110
|
+
graph_store.insert([main_subject, ::RDF::DC.creator, creator])
|
111
|
+
graph_store.insert([main_subject, ::RDF::DC.date, Time.now])
|
112
|
+
end
|
113
|
+
|
114
|
+
let :access do
|
115
|
+
RoadForest::RDF::WriteManager.new.tap do |access|
|
116
|
+
access.rigor = source_rigor
|
117
|
+
access.source_graph = graph_store
|
118
|
+
end
|
92
119
|
end
|
93
120
|
|
94
121
|
let :step do
|
95
|
-
RoadForest::RDF::GraphFocus.new(
|
122
|
+
RoadForest::RDF::GraphFocus.new(access, main_subject)
|
96
123
|
end
|
97
124
|
|
98
125
|
it "should enumerate forward properties" do
|
@@ -122,7 +149,7 @@ describe RoadForest::RDF do
|
|
122
149
|
step[:dc,:creator][:foaf,:givenname].should == "Judson"
|
123
150
|
end
|
124
151
|
|
125
|
-
it "should be able to add properties with []="
|
152
|
+
it "should be able to add properties with []=" do
|
126
153
|
step[[:dc, :dateCopyrighted]] = Time.now #slightly ugly syntax
|
127
154
|
step[:dc, :dateCopyrighted].should be_an_instance_of(Time)
|
128
155
|
RDF::Query.new do |query|
|
@@ -130,13 +157,12 @@ describe RoadForest::RDF do
|
|
130
157
|
end.execute(graph_store).should_not be_empty
|
131
158
|
end
|
132
159
|
|
133
|
-
it "should be able to add properties with set"
|
160
|
+
it "should be able to add properties with set" do
|
134
161
|
step.set(:dc, :dateCopyrighted, Time.now)
|
135
162
|
step[:dc, :dateCopyrighted].should be_an_instance_of(Time)
|
136
163
|
RDF::Query.new do |query|
|
137
164
|
query.pattern [:subject, RDF::DC.dateCopyrighted, :value]
|
138
|
-
|
139
|
-
end
|
165
|
+
end.execute(graph_store).should_not be_empty
|
140
166
|
end
|
141
167
|
end
|
142
168
|
end
|