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.
@@ -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 PublishMyData::SparqlQueryMissingVariablesException, :with => :missing_variables
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
- interpolations = request.params.reject{ |p| ['controller', 'action', 'page', 'per_page', 'id', 'commit' ,'utf8', 'query'].include?(p) }
24
- PublishMyData::SparqlQuery.new(query_text, {
23
+ @sparql_query = PublishMyData::SparqlQuery.new(query_text, {
25
24
  :request_format => request.format.to_sym,
26
- :interpolations => 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
- @sparql_query = build_sparql_query(@query_text)
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 SparqlQueryMissingVariablesException < StandardError
6
- attr_reader :missing_variables, :expected_variables
5
+ class SparqlQueryReservedVariablesException < StandardError
6
+ attr_reader :reserved_variables, :expected_variables, :interpolations
7
7
 
8
- def initialize(missing_variables, expected_variables)
9
- raise ArgumentError.new("Missing parameters should be an array") unless missing_variables.is_a?(Array)
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
- "Missing parameters for interpolation: #{@missing_variables.map(&:to_s).join(', ')}"
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-time
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
- # modify the query string, before constructing
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 interpolate_query(query_string, interpolations)
123
- i = interpolations.symbolize_keys.select{ |k,v| v && v.length > 0 }
124
- # regular expression finds words inside %{variable} tokens
125
- @expected_variables = self.class.get_expected_variables(query_string)
126
- missing_variables = @expected_variables - i.keys
127
- if missing_variables.length > 0
128
- raise SparqlQueryMissingVariablesException.new(missing_variables, @expected_variables)
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)
@@ -1,3 +1,3 @@
1
1
  module PublishMyData
2
- VERSION = "0.0.30"
2
+ VERSION = "0.0.31"
3
3
  end
@@ -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