odata4 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Test Coverage](https://api.codeclimate.com/v1/badges/f151944dc05b2c7268e5/test_coverage)](https://codeclimate.com/github/wrstudios/odata4/test_coverage)
|
14
14
|
[![Dependency Status](https://gemnasium.com/badges/github.com/wrstudios/odata4.svg)](https://gemnasium.com/github.com/wrstudios/odata4)
|
15
15
|
[![Documentation](http://inch-ci.org/github/wrstudios/odata4.png?branch=master)](http://www.rubydoc.info/github/wrstudios/odata4/master)
|
16
|
+
[![Gem Version](https://badge.fury.io/rb/odata4.svg)](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
|