publish_my_data 0.0.30 → 0.0.31
Sign up to get free protection for your applications and to get access to all the features.
- data/app/controllers/concerns/publish_my_data/sparql_processing.rb +19 -5
- data/app/controllers/publish_my_data/sparql_controller.rb +1 -1
- data/lib/publish_my_data/sparql_query.rb +22 -26
- data/lib/publish_my_data/version.rb +1 -1
- data/spec/controllers/publish_my_data/sparql_controller_spec.rb +99 -0
- data/spec/dummy/log/test.log +142118 -0
- data/spec/lib/publish_my_data/sparql_query_spec.rb +2 -2
- metadata +16 -16
@@ -5,8 +5,8 @@ module PublishMyData
|
|
5
5
|
included do
|
6
6
|
|
7
7
|
rescue_from PublishMyData::SparqlQueryExecutionException, :with => :show_sparql_execution_message
|
8
|
-
|
9
|
-
rescue_from
|
8
|
+
rescue_from PublishMyData::SparqlQueryReservedVariablesException, :with => :reserved_variables
|
9
|
+
rescue_from Tripod::SparqlQueryMissingVariables, :with => :missing_variables
|
10
10
|
|
11
11
|
respond_to :html, :csv, :text, :nt, :ttl, :xml, :rdf, :json
|
12
12
|
|
@@ -20,11 +20,14 @@ module PublishMyData
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def build_sparql_query(query_text)
|
23
|
-
|
24
|
-
PublishMyData::SparqlQuery.new(query_text, {
|
23
|
+
@sparql_query = PublishMyData::SparqlQuery.new(query_text, {
|
25
24
|
:request_format => request.format.to_sym,
|
26
|
-
:interpolations =>
|
25
|
+
:interpolations => request.params.clone
|
27
26
|
})
|
27
|
+
|
28
|
+
@expected_variables = @sparql_query.expected_variables
|
29
|
+
@interpolations = @sparql_query.interpolations
|
30
|
+
# note: if there are missing variables, then this will be caught by them missing_variables error handler
|
28
31
|
end
|
29
32
|
|
30
33
|
# process the sparql query, paginating if appropriate
|
@@ -60,6 +63,17 @@ module PublishMyData
|
|
60
63
|
end
|
61
64
|
|
62
65
|
def missing_variables(e)
|
66
|
+
@missing_variables = e.missing_variables
|
67
|
+
@expected_variables = e.expected_variables
|
68
|
+
@interpolations = e.received_variables
|
69
|
+
@error_message = e.message
|
70
|
+
respond_with_error
|
71
|
+
end
|
72
|
+
|
73
|
+
def reserved_variables(e)
|
74
|
+
@reserved_variables_used = e.reserved_variables
|
75
|
+
@expected_variables = e.expected_variables
|
76
|
+
@interpolations = e.interpolations
|
63
77
|
@error_message = e.message
|
64
78
|
respond_with_error
|
65
79
|
end
|
@@ -16,7 +16,7 @@ module PublishMyData
|
|
16
16
|
render :text => "no query supplied", :status => 400
|
17
17
|
end
|
18
18
|
else
|
19
|
-
|
19
|
+
build_sparql_query(@query_text)
|
20
20
|
@sparql_query_result = process_sparql_query(@sparql_query)
|
21
21
|
respond_with(@sparql_query_result)
|
22
22
|
end
|
@@ -2,27 +2,29 @@ module PublishMyData
|
|
2
2
|
|
3
3
|
class SparqlQueryExecutionException < StandardError; end
|
4
4
|
|
5
|
-
class
|
6
|
-
attr_reader :
|
5
|
+
class SparqlQueryReservedVariablesException < StandardError
|
6
|
+
attr_reader :reserved_variables, :expected_variables, :interpolations
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
|
10
|
-
@missing_variables = missing_variables
|
8
|
+
def initialize(reserved_variables, expected_variables, interpolations)
|
9
|
+
@reserved_variables = reserved_variables
|
11
10
|
@expected_variables = expected_variables
|
11
|
+
@interpolations = interpolations
|
12
12
|
end
|
13
13
|
|
14
14
|
def to_s
|
15
|
-
"
|
15
|
+
"Reserved tokens used: #{@reserved_variables.map(&:to_s).join(', ')}"
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
class SparqlQuery < Tripod::SparqlQuery
|
20
20
|
|
21
|
+
@@reserved_variables = [:controller, :action, :page, :per_page, :id, :commit ,:utf8, :query]
|
22
|
+
cattr_reader :reserved_variables
|
23
|
+
|
21
24
|
attr_reader :request_format # symbol representing the format of the original request
|
22
25
|
attr_reader :parent_query # set if this query originated from another (e.g. pagination or count)
|
23
|
-
|
24
|
-
attr_reader :interpolations # interpolations supplied at construct
|
25
|
-
attr_reader :expected_variables # list of variables used in the query,
|
26
|
+
attr_reader :expected_variables # tokens that appear in the query
|
27
|
+
attr_reader :interpolations # interpolations supplied at construct time
|
26
28
|
|
27
29
|
# options
|
28
30
|
# :request_format (symbol, e.g. :html, :json )
|
@@ -31,12 +33,11 @@ module PublishMyData
|
|
31
33
|
def initialize(query_string, opts={})
|
32
34
|
@opts = opts # save off the original opts
|
33
35
|
|
34
|
-
@interpolations = opts[:interpolations] || {}
|
35
|
-
|
36
|
-
|
37
|
-
query_string = interpolate_query(query_string, self.interpolations)
|
36
|
+
@interpolations = (opts[:interpolations] || {}).delete_if{ |k,v| self.class.reserved_variables.include?(k.to_sym) }
|
37
|
+
@expected_variables = self.class.get_expected_variables(query_string)
|
38
|
+
check_reserved_variables!
|
38
39
|
|
39
|
-
super(query_string)
|
40
|
+
super(query_string, @interpolations)
|
40
41
|
|
41
42
|
@parent_query = opts[:parent_query]
|
42
43
|
@request_format = opts[:request_format] || :html
|
@@ -113,21 +114,16 @@ LIMIT #{limit} OFFSET #{offset}"
|
|
113
114
|
PublishMyData::SparqlQuery.new(paginated_query, {:request_format => self.request_format, :parent_query => self}) # pass in the original query
|
114
115
|
end
|
115
116
|
|
116
|
-
def self.get_expected_variables(query_string)
|
117
|
-
query_string.scan(/[.]?\%\{(\w+)\}[.]?/).flatten.uniq.map &:to_sym
|
118
|
-
end
|
119
|
-
|
120
117
|
private
|
121
118
|
|
122
|
-
def
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
119
|
+
def check_reserved_variables!
|
120
|
+
if @expected_variables && @expected_variables.any? # this will be set by the base class
|
121
|
+
|
122
|
+
reserved_variables_used = (@expected_variables & SparqlQuery.reserved_variables)
|
123
|
+
if reserved_variables_used.any?
|
124
|
+
raise SparqlQueryReservedVariablesException.new(reserved_variables_used, @expected_variables, @interpolations)
|
125
|
+
end
|
129
126
|
end
|
130
|
-
query_string % i # do the interpolating
|
131
127
|
end
|
132
128
|
|
133
129
|
def process_sparql_parse_failed_exception_message(bad_sparql_request)
|
@@ -74,6 +74,105 @@ module PublishMyData
|
|
74
74
|
|
75
75
|
end
|
76
76
|
|
77
|
+
context "where the query expects parameters" do
|
78
|
+
let(:query) {"select * where {?s ?%{p} ?%{o}}"}
|
79
|
+
|
80
|
+
it "should assign the expected_variables" do
|
81
|
+
get :endpoint, query: query, use_route: :publish_my_data
|
82
|
+
assigns['expected_variables'].should == [:p, :o]
|
83
|
+
end
|
84
|
+
|
85
|
+
context "when a reserved parameter is used" do
|
86
|
+
|
87
|
+
# page is reserved.
|
88
|
+
let(:query) {"select * where {?s ?%{page} ?%{o}}"}
|
89
|
+
let (:parameters) { {:query => query, :o => 'oh', :page => 1, use_route: :publish_my_data} }
|
90
|
+
|
91
|
+
it "should assign the reserved_variables_used" do
|
92
|
+
get :endpoint, parameters
|
93
|
+
assigns['reserved_variables_used'].should == [:page]
|
94
|
+
end
|
95
|
+
|
96
|
+
context "for html format" do
|
97
|
+
before { get :endpoint, parameters }
|
98
|
+
|
99
|
+
it 'should respond with success' do
|
100
|
+
response.should be_success
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should assign the error message' do
|
104
|
+
assigns['error_message'].should == "Reserved tokens used: page"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "for non-html format" do
|
109
|
+
before { get :endpoint, parameters.merge(format:'json') }
|
110
|
+
|
111
|
+
it 'should respond with a 400' do
|
112
|
+
response.code.should == "400"
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should include a message in the body' do
|
116
|
+
response.body.should == "Reserved tokens used: page"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
context "when all parameters supplied" do
|
123
|
+
let (:parameters) { {:query => query, :o => 'oh', :p => 'pee', use_route: :publish_my_data} }
|
124
|
+
|
125
|
+
it "should set the interpolations" do
|
126
|
+
get :endpoint, parameters
|
127
|
+
assigns['interpolations'].should == {"o" => 'oh', "p" => 'pee'}
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should respond successfully" do
|
131
|
+
get :endpoint, parameters
|
132
|
+
response.should be_success
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "when some parameters missing" do
|
137
|
+
let (:parameters) { {:query => query, :o => 'oh', use_route: :publish_my_data} }
|
138
|
+
|
139
|
+
it "should set the missing_variables" do
|
140
|
+
get :endpoint, parameters
|
141
|
+
assigns['missing_variables'].should == [:p]
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should set the interpolations" do
|
145
|
+
get :endpoint, parameters
|
146
|
+
assigns['interpolations'].should == {"o" => 'oh'}
|
147
|
+
end
|
148
|
+
|
149
|
+
context "for html format" do
|
150
|
+
before { get :endpoint, parameters }
|
151
|
+
it 'should respond with success' do
|
152
|
+
response.should be_success
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should assign the error message' do
|
156
|
+
assigns['error_message'] = "Missing parameters: p"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context "for non-html format" do
|
161
|
+
before { get :endpoint, parameters.merge(format:'json') }
|
162
|
+
|
163
|
+
it 'should respond with a 400' do
|
164
|
+
response.code.should == "400"
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should include a message in the body' do
|
168
|
+
response.body.should == "Missing parameters: p"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
77
176
|
context "non-html queries" do
|
78
177
|
context 'for SELECTs' do
|
79
178
|
|