publish_my_data 0.0.30 → 0.0.31

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.
@@ -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