odata4 0.8.0 → 0.8.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +1 -0
- data/lib/odata4/entity.rb +13 -5
- data/lib/odata4/properties/collection.rb +50 -0
- data/lib/odata4/properties.rb +1 -0
- data/lib/odata4/query.rb +7 -5
- data/lib/odata4/schema.rb +8 -2
- data/lib/odata4/service/request.rb +81 -0
- data/lib/odata4/{query/result → service/response}/atom.rb +9 -10
- data/lib/odata4/{query/result → service/response}/json.rb +9 -10
- data/lib/odata4/service/response/plain.rb +36 -0
- data/lib/odata4/service/response/xml.rb +40 -0
- data/lib/odata4/service/response.rb +160 -0
- data/lib/odata4/service.rb +12 -80
- data/lib/odata4/version.rb +1 -1
- data/lib/odata4.rb +0 -3
- data/spec/fixtures/files/entity_to_xml.xml +1 -1
- data/spec/fixtures/files/error.xml +5 -0
- data/spec/fixtures/vcr_cassettes/service/request_specs.yml +193 -0
- data/spec/odata4/properties/collection_spec.rb +44 -0
- data/spec/odata4/query_spec.rb +2 -2
- data/spec/odata4/service/request_spec.rb +49 -0
- data/spec/odata4/service/response_spec.rb +77 -0
- metadata +19 -7
- data/lib/odata4/query/result.rb +0 -84
- data/spec/odata4/query/result_spec.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9adfc90966866d69ec4082404f10a60cd8404563
|
4
|
+
data.tar.gz: 293c604e274b209c738496e41318f2441d41e159
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52bad8a865f20e227aa331f09e680d857caaaa3da8e70df5be873d78477d96b7e4451506e1a70efec9239034c4e98693c0f7b5600f78e5f383fcb56249e6085c
|
7
|
+
data.tar.gz: c1868354a432bed72b9b6db7b0e76d6194fd221e05827d3077cdaf9d258687e46bd489a444132154eb95a4835f959ca18e7f64c22dbaf49a41a1299f6d3be382
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 0.8.1
|
4
|
+
|
5
|
+
* [New Feature] Basic support for `Collection` property type
|
6
|
+
* [Refactor] Moved all HTTP-related code into `Service::Request`,
|
7
|
+
renamed `Query::Result` to `Service::Response`
|
8
|
+
* [Bugfix] Fixed incorrect `OData-Version` header being sent
|
9
|
+
* [Bugfix] Fixed duplicate namespace in Atom serialization
|
10
|
+
|
3
11
|
## 0.8.0
|
4
12
|
|
5
13
|
* [New Feature] Support for multiple schemas
|
data/README.md
CHANGED
@@ -13,6 +13,7 @@ If you need a gem to integration with OData Version 3, you can use James Thompso
|
|
13
13
|
[](https://codeclimate.com/github/wrstudios/odata4/test_coverage)
|
14
14
|
[](https://gemnasium.com/github.com/wrstudios/odata4)
|
15
15
|
[](http://www.rubydoc.info/github/wrstudios/odata4/master)
|
16
|
+
[](https://badge.fury.io/rb/odata4)
|
16
17
|
|
17
18
|
## Installation
|
18
19
|
|
data/lib/odata4/entity.rb
CHANGED
@@ -169,7 +169,7 @@ module OData4
|
|
169
169
|
namespaces = XML_NAMESPACES.merge('xml:base' => service.service_url)
|
170
170
|
builder = Nokogiri::XML::Builder.new do |xml|
|
171
171
|
xml.entry(namespaces) do
|
172
|
-
xml.category(term:
|
172
|
+
xml.category(term: type,
|
173
173
|
scheme: 'http://docs.oasis-open.org/odata/ns/scheme')
|
174
174
|
xml.author { xml.name }
|
175
175
|
|
@@ -236,13 +236,21 @@ module OData4
|
|
236
236
|
private
|
237
237
|
|
238
238
|
def instantiate_property(property_name, value_xml)
|
239
|
-
|
240
|
-
|
239
|
+
prop_type = schema.get_property_type(name, property_name)
|
240
|
+
prop_type, value_type = prop_type.split(/\(|\)/)
|
241
|
+
|
242
|
+
if prop_type == 'Collection'
|
243
|
+
klass = ::OData4::Properties::Collection
|
244
|
+
options = { value_type: value_type }
|
245
|
+
else
|
246
|
+
klass = ::OData4::PropertyRegistry[prop_type]
|
247
|
+
options = {}
|
248
|
+
end
|
241
249
|
|
242
250
|
if klass.nil?
|
243
|
-
raise RuntimeError, "Unknown property type: #{
|
251
|
+
raise RuntimeError, "Unknown property type: #{prop_type}"
|
244
252
|
else
|
245
|
-
klass.from_xml(value_xml, service: service)
|
253
|
+
klass.from_xml(value_xml, options.merge(service: service))
|
246
254
|
end
|
247
255
|
end
|
248
256
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module OData4
|
2
|
+
module Properties
|
3
|
+
# Defines the Collection OData4 type.
|
4
|
+
class Collection < OData4::Property
|
5
|
+
# Overriding default constructor to avoid converting
|
6
|
+
# value to string.
|
7
|
+
# TODO: Make this the default for all property types?
|
8
|
+
def initialize(name, value, options = {})
|
9
|
+
super(name, value, options)
|
10
|
+
self.value = value
|
11
|
+
end
|
12
|
+
|
13
|
+
def value
|
14
|
+
if @value.nil?
|
15
|
+
nil
|
16
|
+
else
|
17
|
+
@value.map(&:value)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def value=(value)
|
22
|
+
if value.nil? && allows_nil?
|
23
|
+
@value = nil
|
24
|
+
elsif value.respond_to?(:map)
|
25
|
+
@value = value.map.with_index do |element, index|
|
26
|
+
type_class.new("#{name}[#{index}]", element)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
validation_error 'Value must be an array'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def url_value
|
34
|
+
'[' + @value.map(&:url_value).join(',') + ']'
|
35
|
+
end
|
36
|
+
|
37
|
+
def type
|
38
|
+
"Collection(#{value_type})"
|
39
|
+
end
|
40
|
+
|
41
|
+
def value_type
|
42
|
+
options[:value_type] || 'Edm.String'
|
43
|
+
end
|
44
|
+
|
45
|
+
def type_class
|
46
|
+
OData4::PropertyRegistry[value_type]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/odata4/properties.rb
CHANGED
@@ -4,6 +4,7 @@ require 'odata4/properties/number'
|
|
4
4
|
# Implementations
|
5
5
|
require 'odata4/properties/binary'
|
6
6
|
require 'odata4/properties/boolean'
|
7
|
+
require 'odata4/properties/collection'
|
7
8
|
require 'odata4/properties/date'
|
8
9
|
require 'odata4/properties/date_time'
|
9
10
|
require 'odata4/properties/date_time_offset'
|
data/lib/odata4/query.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'odata4/query/criteria'
|
2
|
+
require 'odata4/query/in_batches'
|
3
|
+
|
1
4
|
module OData4
|
2
5
|
# OData4::Query provides the query interface for requesting Entities matching
|
3
6
|
# specific criteria from an OData4::EntitySet. This class should not be
|
@@ -133,17 +136,16 @@ module OData4
|
|
133
136
|
end
|
134
137
|
|
135
138
|
# Execute the query.
|
136
|
-
# @return [OData4::
|
137
|
-
def execute(
|
138
|
-
|
139
|
-
OData4::Query::Result.new(self, response)
|
139
|
+
# @return [OData4::Service::Response]
|
140
|
+
def execute(url_chunk = self.to_s)
|
141
|
+
service.execute(url_chunk, options.merge(query: self))
|
140
142
|
end
|
141
143
|
|
142
144
|
# Executes the query to get a count of entities.
|
143
145
|
# @return [Integer]
|
144
146
|
def count
|
145
147
|
url_chunk = ["#{entity_set.name}/$count", assemble_criteria].compact.join('?')
|
146
|
-
response =
|
148
|
+
response = self.execute(url_chunk)
|
147
149
|
# Some servers (*cough* Microsoft *cough*) seem to
|
148
150
|
# return extraneous characters in the response.
|
149
151
|
response.body.scan(/\d+/).first.to_i
|
data/lib/odata4/schema.rb
CHANGED
@@ -128,10 +128,16 @@ module OData4
|
|
128
128
|
|
129
129
|
def process_property_from_xml(property_xml)
|
130
130
|
property_name = property_xml.attributes['Name'].value
|
131
|
-
|
131
|
+
property_type = property_xml.attributes['Type'].value
|
132
132
|
property_options = { service: service }
|
133
133
|
|
134
|
-
|
134
|
+
property_type, value_type = property_type.split(/\(|\)/)
|
135
|
+
if property_type == 'Collection'
|
136
|
+
klass = ::OData4::Properties::Collection
|
137
|
+
property_options.merge(value_type: value_type)
|
138
|
+
else
|
139
|
+
klass = ::OData4::PropertyRegistry[property_type]
|
140
|
+
end
|
135
141
|
|
136
142
|
if klass.nil?
|
137
143
|
raise RuntimeError, "Unknown property type: #{value_type}"
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module OData4
|
2
|
+
class Service
|
3
|
+
# Encapsulates a single request to an OData service.
|
4
|
+
class Request
|
5
|
+
# The OData service against which the request is performed
|
6
|
+
attr_reader :service
|
7
|
+
# The OData4::Query that generated this request (optional)
|
8
|
+
attr_reader :query
|
9
|
+
# The HTTP method for this request
|
10
|
+
attr_accessor :method
|
11
|
+
# The request format (`:atom`, `:json`, or `:auto`)
|
12
|
+
attr_accessor :format
|
13
|
+
|
14
|
+
# Create a new request
|
15
|
+
# @param service [OData4::Service] Where the request will be sent
|
16
|
+
# @param url_chunk [String] Request path, relative to the service URL, including query params
|
17
|
+
# @param options [Hash] Additional request options
|
18
|
+
def initialize(service, url_chunk, options = {})
|
19
|
+
@service = service
|
20
|
+
@url_chunk = url_chunk
|
21
|
+
@method = options[:method] || :get
|
22
|
+
@format = options[:format] || :auto
|
23
|
+
@query = options[:query]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Return the full request URL (including service base)
|
27
|
+
# @return [String]
|
28
|
+
def url
|
29
|
+
::URI.join("#{service.service_url}/", ::URI.escape(url_chunk)).to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
# The content type for this request. Depends on format.
|
33
|
+
# @return [String]
|
34
|
+
def content_type
|
35
|
+
if format == :auto
|
36
|
+
MIME_TYPES.values.join(',')
|
37
|
+
elsif MIME_TYPES.has_key? format
|
38
|
+
MIME_TYPES[format]
|
39
|
+
else
|
40
|
+
raise ArgumentError, "Unknown format '#{format}'"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Execute the request
|
45
|
+
#
|
46
|
+
# @param additional_options [Hash] options to pass to Typhoeus
|
47
|
+
# @return [OData4::Service::Response]
|
48
|
+
def execute(additional_options = {})
|
49
|
+
options = request_options(additional_options)
|
50
|
+
request = ::Typhoeus::Request.new(url, options)
|
51
|
+
logger.info "Requesting #{method.to_s.upcase} #{url}..."
|
52
|
+
request.run
|
53
|
+
|
54
|
+
Response.new(service, request.response, query)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
attr_reader :url_chunk
|
60
|
+
|
61
|
+
def logger
|
62
|
+
service.logger
|
63
|
+
end
|
64
|
+
|
65
|
+
def request_options(additional_options = {})
|
66
|
+
options = service.options[:typhoeus]
|
67
|
+
.merge({ method: method })
|
68
|
+
.merge(additional_options)
|
69
|
+
|
70
|
+
# Don't overwrite Accept header if already present
|
71
|
+
unless options[:headers]['Accept']
|
72
|
+
options[:headers] = options[:headers].merge({
|
73
|
+
'Accept' => content_type
|
74
|
+
})
|
75
|
+
end
|
76
|
+
|
77
|
+
options
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -1,14 +1,9 @@
|
|
1
1
|
module OData4
|
2
|
-
class
|
3
|
-
class
|
4
|
-
# Represents the results of executing a OData4::Query.
|
5
|
-
# @api private
|
2
|
+
class Service
|
3
|
+
class Response
|
6
4
|
module Atom
|
7
|
-
def
|
8
|
-
|
9
|
-
entity = OData4::Entity.from_xml(entity_xml, entity_options)
|
10
|
-
block_given? ? block.call(entity) : yield(entity)
|
11
|
-
end
|
5
|
+
def parse_entity(entity_xml, entity_options)
|
6
|
+
OData4::Entity.from_xml(entity_xml, entity_options)
|
12
7
|
end
|
13
8
|
|
14
9
|
def next_page
|
@@ -23,10 +18,14 @@ module OData4
|
|
23
18
|
result_xml.xpath('//error/message').first.andand.text
|
24
19
|
end
|
25
20
|
|
21
|
+
def parsed_body
|
22
|
+
result_xml
|
23
|
+
end
|
24
|
+
|
26
25
|
private
|
27
26
|
|
28
27
|
def result_xml
|
29
|
-
@result_xml ||= ::Nokogiri::XML(
|
28
|
+
@result_xml ||= ::Nokogiri::XML(response.body).remove_namespaces!
|
30
29
|
end
|
31
30
|
|
32
31
|
# Find entity entries in a result set
|
@@ -1,14 +1,9 @@
|
|
1
1
|
module OData4
|
2
|
-
class
|
3
|
-
class
|
4
|
-
# Represents the results of executing a OData4::Query.
|
5
|
-
# @api private
|
2
|
+
class Service
|
3
|
+
class Response
|
6
4
|
module JSON
|
7
|
-
def
|
8
|
-
|
9
|
-
entity = OData4::Entity.from_json(entity_json, entity_options)
|
10
|
-
block_given? ? block.call(entity) : yield(entity)
|
11
|
-
end
|
5
|
+
def parse_entity(entity_json, entity_options)
|
6
|
+
OData4::Entity.from_json(entity_json, entity_options)
|
12
7
|
end
|
13
8
|
|
14
9
|
def next_page
|
@@ -23,10 +18,14 @@ module OData4
|
|
23
18
|
result_json['error'].andand['message']
|
24
19
|
end
|
25
20
|
|
21
|
+
def parsed_body
|
22
|
+
result_json
|
23
|
+
end
|
24
|
+
|
26
25
|
private
|
27
26
|
|
28
27
|
def result_json
|
29
|
-
@result_json ||= ::JSON.parse(
|
28
|
+
@result_json ||= ::JSON.parse(response.body)
|
30
29
|
end
|
31
30
|
|
32
31
|
def single_entity?
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module OData4
|
2
|
+
class Service
|
3
|
+
class Response
|
4
|
+
module Plain
|
5
|
+
def parse_entity(entity_data, entity_options)
|
6
|
+
raise NotImplementedError, 'Not Available'
|
7
|
+
end
|
8
|
+
|
9
|
+
def next_page
|
10
|
+
raise NotImplementedError, 'Not available'
|
11
|
+
end
|
12
|
+
|
13
|
+
def next_page_url
|
14
|
+
raise NotImplementedError, 'Not available'
|
15
|
+
end
|
16
|
+
|
17
|
+
def error_message
|
18
|
+
response.body
|
19
|
+
end
|
20
|
+
|
21
|
+
def parsed_body
|
22
|
+
response.body
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Find entity entries in a response set
|
28
|
+
#
|
29
|
+
# @return [Array]
|
30
|
+
def find_entities
|
31
|
+
[]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module OData4
|
2
|
+
class Service
|
3
|
+
class Response
|
4
|
+
module XML
|
5
|
+
def parse_entity(entity_data, entity_options)
|
6
|
+
raise NotImplementedError, 'Not Available'
|
7
|
+
end
|
8
|
+
|
9
|
+
def next_page
|
10
|
+
raise NotImplementedError, 'Not Available'
|
11
|
+
end
|
12
|
+
|
13
|
+
def next_page_url
|
14
|
+
raise NotImplementedError, 'Not Available'
|
15
|
+
end
|
16
|
+
|
17
|
+
def error_message
|
18
|
+
response_xml.xpath('//error/message').first.andand.text
|
19
|
+
end
|
20
|
+
|
21
|
+
def parsed_body
|
22
|
+
response_xml
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def response_xml
|
28
|
+
@response_xml ||= ::Nokogiri::XML(response.body).remove_namespaces!
|
29
|
+
end
|
30
|
+
|
31
|
+
# Find entity entries in a response set
|
32
|
+
#
|
33
|
+
# @return [Array]
|
34
|
+
def find_entities
|
35
|
+
[]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'odata4/service/response/atom'
|
2
|
+
require 'odata4/service/response/json'
|
3
|
+
require 'odata4/service/response/plain'
|
4
|
+
require 'odata4/service/response/xml'
|
5
|
+
|
6
|
+
module OData4
|
7
|
+
class Service
|
8
|
+
# The result of executing a OData4::Service::Request.
|
9
|
+
class Response
|
10
|
+
include Enumerable
|
11
|
+
|
12
|
+
# The service that generated this response
|
13
|
+
attr_reader :service
|
14
|
+
# The underlying (raw) response
|
15
|
+
attr_reader :response
|
16
|
+
# The query that generated the response (optional)
|
17
|
+
attr_reader :query
|
18
|
+
|
19
|
+
# Create a new response given a service and a raw response.
|
20
|
+
# @param service [OData4::Service]
|
21
|
+
# @param response [Typhoeus::Result]
|
22
|
+
def initialize(service, response, query = nil)
|
23
|
+
@service = service
|
24
|
+
@response = response
|
25
|
+
@query = query
|
26
|
+
check_content_type
|
27
|
+
validate!
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns the HTTP status code.
|
31
|
+
def status
|
32
|
+
response.code
|
33
|
+
end
|
34
|
+
|
35
|
+
# Whether the request was successful.
|
36
|
+
def success?
|
37
|
+
200 <= status && status < 300
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns the content type of the resonse.
|
41
|
+
def content_type
|
42
|
+
response.headers['Content-Type'] || ''
|
43
|
+
end
|
44
|
+
|
45
|
+
def is_atom?
|
46
|
+
content_type =~ /#{Regexp.escape OData4::Service::MIME_TYPES[:atom]}/
|
47
|
+
end
|
48
|
+
|
49
|
+
def is_json?
|
50
|
+
content_type =~ /#{Regexp.escape OData4::Service::MIME_TYPES[:json]}/
|
51
|
+
end
|
52
|
+
|
53
|
+
def is_plain?
|
54
|
+
content_type =~ /#{Regexp.escape OData4::Service::MIME_TYPES[:plain]}/
|
55
|
+
end
|
56
|
+
|
57
|
+
def is_xml?
|
58
|
+
content_type =~ /#{Regexp.escape OData4::Service::MIME_TYPES[:xml]}/
|
59
|
+
end
|
60
|
+
|
61
|
+
# Whether the response contained any entities.
|
62
|
+
# @return [Boolean]
|
63
|
+
def empty?
|
64
|
+
@empty ||= find_entities.empty?
|
65
|
+
end
|
66
|
+
|
67
|
+
# Whether the response failed due to a timeout
|
68
|
+
def timed_out?
|
69
|
+
response.timed_out?
|
70
|
+
end
|
71
|
+
|
72
|
+
# Iterates over all entities in the response, using
|
73
|
+
# automatic paging if necessary.
|
74
|
+
# Provided for Enumerable functionality.
|
75
|
+
# @param block [block] a block to evaluate
|
76
|
+
# @return [OData4::Entity] each entity in turn for the query result
|
77
|
+
def each(&block)
|
78
|
+
unless empty?
|
79
|
+
process_results(&block)
|
80
|
+
unless next_page.nil?
|
81
|
+
# ensure request gets executed with the same options
|
82
|
+
query.execute(URI.decode next_page_url).each(&block)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns the response body.
|
88
|
+
def body
|
89
|
+
response.body
|
90
|
+
end
|
91
|
+
|
92
|
+
# Validates the response. Throws an exception with
|
93
|
+
# an appropriate message if a 4xx or 5xx status code
|
94
|
+
# occured.
|
95
|
+
#
|
96
|
+
# @return [self]
|
97
|
+
def validate!
|
98
|
+
raise "Bad Request. #{error_message(response)}" if response.code == 400
|
99
|
+
raise "Access Denied" if response.code == 401
|
100
|
+
raise "Forbidden" if response.code == 403
|
101
|
+
raise "Not Found" if [0,404].include?(response.code)
|
102
|
+
raise "Method Not Allowed" if response.code == 405
|
103
|
+
raise "Not Acceptable" if response.code == 406
|
104
|
+
raise "Request Entity Too Large" if response.code == 413
|
105
|
+
raise "Internal Server Error" if response.code == 500
|
106
|
+
raise "Service Unavailable" if response.code == 503
|
107
|
+
self
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def logger
|
113
|
+
service.logger
|
114
|
+
end
|
115
|
+
|
116
|
+
def check_content_type
|
117
|
+
logger.debug <<-EOS
|
118
|
+
[OData4: #{service.name}] Received response:
|
119
|
+
Headers: #{response.headers}
|
120
|
+
Body: #{response.body}
|
121
|
+
EOS
|
122
|
+
# Dynamically extend instance with methods for
|
123
|
+
# processing the current result type
|
124
|
+
if is_atom?
|
125
|
+
extend OData4::Service::Response::Atom
|
126
|
+
elsif is_json?
|
127
|
+
extend OData4::Service::Response::JSON
|
128
|
+
elsif is_xml?
|
129
|
+
extend OData4::Service::Response::XML
|
130
|
+
elsif is_plain?
|
131
|
+
extend OData4::Service::Response::Plain
|
132
|
+
elsif response.body.empty?
|
133
|
+
# Some services (*cough* Microsoft *cough*) return
|
134
|
+
# an empty response with no `Content-Type` header set.
|
135
|
+
# We catch that here and bypass content type detection.
|
136
|
+
@empty = true
|
137
|
+
else
|
138
|
+
raise ArgumentError, "Invalid response type '#{content_type}'"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def entity_options
|
143
|
+
if query
|
144
|
+
query.entity_set.entity_options
|
145
|
+
else
|
146
|
+
{
|
147
|
+
service_name: service.name,
|
148
|
+
}
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def process_results(&block)
|
153
|
+
find_entities.each do |entity_data|
|
154
|
+
entity = parse_entity(entity_data, entity_options)
|
155
|
+
block_given? ? block.call(entity) : yield(entity)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|