odata 0.0.8 → 0.0.9
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/.travis.yml +13 -0
- data/lib/odata.rb +4 -0
- data/lib/odata/entity.rb +68 -0
- data/lib/odata/entity_set.rb +68 -0
- data/lib/odata/model.rb +10 -0
- data/lib/odata/properties.rb +4 -0
- data/lib/odata/properties/date_time.rb +6 -2
- data/lib/odata/properties/decimal.rb +4 -5
- data/lib/odata/properties/float.rb +2 -6
- data/lib/odata/properties/integer.rb +4 -8
- data/lib/odata/properties/number.rb +13 -0
- data/lib/odata/properties/string.rb +48 -0
- data/lib/odata/property.rb +0 -32
- data/lib/odata/railtie.rb +5 -2
- data/lib/odata/service.rb +59 -2
- data/lib/odata/version.rb +1 -1
- data/odata.gemspec +1 -0
- data/spec/fixtures/sample_service/products_skip0_top5.xml +171 -0
- data/spec/fixtures/sample_service/products_skip10_top5.xml +51 -0
- data/spec/fixtures/sample_service/products_skip5_top5.xml +179 -0
- data/spec/odata/entity_set_spec.rb +40 -0
- data/spec/odata/entity_spec.rb +43 -0
- data/spec/odata/properties/decimal_spec.rb +3 -2
- data/spec/odata/properties/string_spec.rb +33 -0
- data/spec/odata/property_spec.rb +0 -32
- data/spec/odata/service_registry_spec.rb +0 -6
- data/spec/odata/service_spec.rb +17 -4
- data/spec/spec_helper.rb +31 -7
- metadata +29 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0999c3b85269d2ad6c9855aa813ed5e6e10a24e
|
4
|
+
data.tar.gz: ee7cf848b1c47f15375c2e9cbd6e7cb5a2cbc89f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 516fa042cb00120bd214aeb52e9c12dbede85614562ccd760cbf4b41d1b6aed5571c82589949f795b42a3e9d4d61c687fb485db4f4bafc36d83c3666dfeb5921
|
7
|
+
data.tar.gz: 0654fbc52376a5446c86fb8303f6b5ca267b7eae694d87f3bcac4644cf824a953b3ed347a0f40864c022039947d312de4b9038a2775679a32140d4a1e1024186
|
data/.travis.yml
CHANGED
@@ -11,6 +11,9 @@ jdk:
|
|
11
11
|
- openjdk7
|
12
12
|
- oraclejdk7
|
13
13
|
- oraclejdk8
|
14
|
+
env:
|
15
|
+
- REAL_HTTP=true
|
16
|
+
- REAL_HTTP=false
|
14
17
|
branches:
|
15
18
|
only:
|
16
19
|
- master
|
@@ -22,30 +25,40 @@ matrix:
|
|
22
25
|
jdk: oraclejdk7
|
23
26
|
- rvm: 1.9.3
|
24
27
|
jdk: oraclejdk8
|
28
|
+
- rvm: 1.9.3
|
29
|
+
env: REAL_HTTP=true
|
25
30
|
- rvm: 2.0.0
|
26
31
|
jdk: openjdk6
|
27
32
|
- rvm: 2.0.0
|
28
33
|
jdk: oraclejdk7
|
29
34
|
- rvm: 2.0.0
|
30
35
|
jdk: oraclejdk8
|
36
|
+
- rvm: 2.0.0
|
37
|
+
env: REAL_HTTP=true
|
31
38
|
- rvm: 2.1.0
|
32
39
|
jdk: openjdk6
|
33
40
|
- rvm: 2.1.0
|
34
41
|
jdk: oraclejdk7
|
35
42
|
- rvm: 2.1.0
|
36
43
|
jdk: oraclejdk8
|
44
|
+
- rvm: 2.1.0
|
45
|
+
env: REAL_HTTP=true
|
37
46
|
- rvm: 2.1.1
|
38
47
|
jdk: openjdk6
|
39
48
|
- rvm: 2.1.1
|
40
49
|
jdk: oraclejdk7
|
41
50
|
- rvm: 2.1.1
|
42
51
|
jdk: oraclejdk8
|
52
|
+
- rvm: 2.1.1
|
53
|
+
env: REAL_HTTP=true
|
43
54
|
- rvm: 2.1.2
|
44
55
|
jdk: openjdk6
|
45
56
|
- rvm: 2.1.2
|
46
57
|
jdk: oraclejdk7
|
47
58
|
- rvm: 2.1.2
|
48
59
|
jdk: oraclejdk8
|
60
|
+
- rvm: jruby
|
61
|
+
env: REAL_HTTP=true
|
49
62
|
addons:
|
50
63
|
code_climate:
|
51
64
|
repo_token: 323644d852f6ba54213f25446d6f4276dbec0adb74fefce770b083cd3e83ea1e
|
data/lib/odata.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'backports/2.1.0/enumerable/to_h'
|
2
|
+
|
1
3
|
require 'date'
|
2
4
|
require 'nokogiri'
|
3
5
|
require 'typhoeus'
|
@@ -7,6 +9,8 @@ require 'active_support/core_ext'
|
|
7
9
|
require 'active_support/concern'
|
8
10
|
|
9
11
|
require 'odata/version'
|
12
|
+
require 'odata/entity'
|
13
|
+
require 'odata/entity_set'
|
10
14
|
require 'odata/service'
|
11
15
|
require 'odata/service_registry'
|
12
16
|
require 'odata/model'
|
data/lib/odata/entity.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
module OData
|
2
|
+
class Entity
|
3
|
+
attr_reader :type, :namespace
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@type = options[:type]
|
7
|
+
@namespace = options[:namespace]
|
8
|
+
@properties = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
@name ||= type.gsub(/#{namespace}\./, '')
|
13
|
+
end
|
14
|
+
|
15
|
+
def [](property_name)
|
16
|
+
@properties[property_name.to_s].value
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.from_xml(xml_doc, options = {})
|
20
|
+
entity = OData::Entity.new(options)
|
21
|
+
entity.instance_eval do
|
22
|
+
xml_doc.xpath('//content/properties/*').each do |property_xml|
|
23
|
+
property_name = property_xml.name
|
24
|
+
if property_xml.attributes['null'] &&
|
25
|
+
property_xml.attributes['null'].value == 'true'
|
26
|
+
value = nil
|
27
|
+
value_type = service.get_property_type(name, property_name)
|
28
|
+
else
|
29
|
+
value_type = property_xml.attributes['type'].value
|
30
|
+
value = property_xml.content
|
31
|
+
end
|
32
|
+
klass_name = value_type.gsub(/^Edm\./, '')
|
33
|
+
property = "OData::Properties::#{klass_name}".constantize.new(property_name, value)
|
34
|
+
set_property(property_name, property)
|
35
|
+
end
|
36
|
+
|
37
|
+
begin
|
38
|
+
title_value = xml_doc.xpath('//title').first.content
|
39
|
+
property_name = service.get_title_property_name(name)
|
40
|
+
value_type = service.get_property_type(name, property_name)
|
41
|
+
klass_name = value_type.gsub(/^Edm\./, '')
|
42
|
+
property = "OData::Properties::#{klass_name}".constantize.new(property_name, title_value)
|
43
|
+
set_property(property_name, property)
|
44
|
+
end
|
45
|
+
|
46
|
+
begin
|
47
|
+
summary_value = xml_doc.xpath('//summary').first.content
|
48
|
+
property_name = service.get_summary_property_name(name)
|
49
|
+
value_type = service.get_property_type(name, property_name)
|
50
|
+
klass_name = value_type.gsub(/^Edm\./, '')
|
51
|
+
property = "OData::Properties::#{klass_name}".constantize.new(property_name, summary_value)
|
52
|
+
set_property(property_name, property)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
entity
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def service
|
61
|
+
@service ||= OData::ServiceRegistry[namespace]
|
62
|
+
end
|
63
|
+
|
64
|
+
def set_property(name, odata_property)
|
65
|
+
@properties[name.to_s] = odata_property.dup
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module OData
|
2
|
+
# This class represents a set of entities within an OData service. It is
|
3
|
+
# instantiated whenever an OData::Service is asked for an EntitySet via the
|
4
|
+
# OData::Service#[] method call. It also provides Enumerable behavior so that
|
5
|
+
# you can interact with the entities within a set in a very comfortable way.
|
6
|
+
#
|
7
|
+
# This class also implements a query interface for finding certain entities
|
8
|
+
# based on query criteria or limiting the result set returned by the set. This
|
9
|
+
# functionality is implemented through transparent proxy objects.
|
10
|
+
class EntitySet
|
11
|
+
include Enumerable
|
12
|
+
|
13
|
+
attr_reader :name, :type, :namespace, :container
|
14
|
+
|
15
|
+
# Sets up the EntitySet to permit querying for the resources in the set.
|
16
|
+
#
|
17
|
+
# @param options [Hash] the options to setup the EntitySet
|
18
|
+
# @return [OData::EntitySet] an instance of the EntitySet
|
19
|
+
def initialize(options = {})
|
20
|
+
@name = options[:name]
|
21
|
+
@type = options[:type]
|
22
|
+
@namespace = options[:namespace]
|
23
|
+
@container = options[:container]
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
# Provided for Enumerable functionality
|
28
|
+
#
|
29
|
+
# @param block [block] a block to evaluate
|
30
|
+
# @return [OData::Entity] each entity in turn from this set
|
31
|
+
def each(&block)
|
32
|
+
per_page = 5; page = 0; page_position = 0; counter = 0
|
33
|
+
total, entities = get_paginated_entities(per_page, page)
|
34
|
+
|
35
|
+
until counter == total
|
36
|
+
if page_position >= per_page
|
37
|
+
page += 1
|
38
|
+
_, entities = get_paginated_entities(per_page, page)
|
39
|
+
page_position = 0
|
40
|
+
end
|
41
|
+
|
42
|
+
entity = OData::Entity.from_xml(entities[page_position], namespace: namespace, type: type)
|
43
|
+
block_given? ? block.call(entity) : yield(entity)
|
44
|
+
|
45
|
+
counter += 1
|
46
|
+
page_position += 1
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the number of entities within the set
|
51
|
+
def count
|
52
|
+
service.execute("#{name}/$count").body.to_i
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def service
|
58
|
+
@service ||= OData::ServiceRegistry[namespace]
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_paginated_entities(per_page, page)
|
62
|
+
result = service.execute("#{name}?$inlinecount=allpages&$skip=#{per_page * page}&$top=#{per_page}")
|
63
|
+
entities = service.find_entities(result)
|
64
|
+
total = service.find_node(result, 'count').content.to_i
|
65
|
+
return total, entities
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/odata/model.rb
CHANGED
@@ -24,6 +24,11 @@ module OData
|
|
24
24
|
EOS
|
25
25
|
end
|
26
26
|
|
27
|
+
# Converts supplied value based on its type
|
28
|
+
#
|
29
|
+
# @param value [*] usually a string representation of the value
|
30
|
+
# @param type [String] OData type name as string
|
31
|
+
# @return [*]
|
27
32
|
def convert_value_for_type(value, type)
|
28
33
|
return nil if value.nil? || type.nil?
|
29
34
|
if type =~ /Int(16|32|64)$/
|
@@ -50,6 +55,11 @@ module OData
|
|
50
55
|
model_name.pluralize
|
51
56
|
end
|
52
57
|
|
58
|
+
# Instantiates an OData::Model instance from a hash of attributes and
|
59
|
+
# their details.
|
60
|
+
#
|
61
|
+
# @param feed_hash [Hash] attribute names as keys, and details as values
|
62
|
+
# @return [OData::Model]
|
53
63
|
def load_from_feed(feed_hash)
|
54
64
|
loaded_instance = self.new
|
55
65
|
feed_hash.each do |attribute_name, details|
|
data/lib/odata/properties.rb
CHANGED
@@ -2,10 +2,14 @@ module OData
|
|
2
2
|
module Properties
|
3
3
|
class DateTime < OData::Property
|
4
4
|
def value
|
5
|
-
if @value.nil? &&
|
5
|
+
if @value.nil? && allows_nil?
|
6
6
|
nil
|
7
7
|
else
|
8
|
-
|
8
|
+
begin
|
9
|
+
::DateTime.strptime(@value, '%Y-%m-%dT%H:%M:%S.%L')
|
10
|
+
rescue ArgumentError
|
11
|
+
::DateTime.parse(@value)
|
12
|
+
end
|
9
13
|
end
|
10
14
|
end
|
11
15
|
|
@@ -21,18 +21,17 @@ module OData
|
|
21
21
|
private
|
22
22
|
|
23
23
|
def validate(value)
|
24
|
-
if
|
25
|
-
|
26
|
-
raise ::ArgumentError, "Value is outside accepted range: #{min_value} to #{max_value}, or has more than 29 significant digits"
|
24
|
+
if value > max_value || value < min_value || value.precs.first > 29
|
25
|
+
raise ArgumentError, "Value is outside accepted range: #{min_value} to #{max_value}, or has more than 29 significant digits"
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
29
|
def min_value
|
31
|
-
@min ||= -
|
30
|
+
@min ||= BigDecimal(-7.9 * (10**28), 2)
|
32
31
|
end
|
33
32
|
|
34
33
|
def max_value
|
35
|
-
@max ||= (7.9 * (10**28))
|
34
|
+
@max ||= BigDecimal(7.9 * (10**28), 2)
|
36
35
|
end
|
37
36
|
end
|
38
37
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module OData
|
2
2
|
module Properties
|
3
3
|
class Float < OData::Property
|
4
|
+
include OData::Properties::Number
|
5
|
+
|
4
6
|
def value
|
5
7
|
if @value.nil? && allows_nil?
|
6
8
|
nil
|
@@ -20,12 +22,6 @@ module OData
|
|
20
22
|
|
21
23
|
private
|
22
24
|
|
23
|
-
def validate(value)
|
24
|
-
if value > max_value || value < min_value
|
25
|
-
raise ::ArgumentError, "Value is outside accepted range: #{min_value} to #{max_value}"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
25
|
def min_value
|
30
26
|
@min ||= -(1.7 * (10**308))
|
31
27
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module OData
|
2
2
|
module Properties
|
3
3
|
class Integer < OData::Property
|
4
|
+
include OData::Properties::Number
|
5
|
+
|
4
6
|
def value
|
5
7
|
if @value.nil? && allows_nil?
|
6
8
|
nil
|
@@ -20,12 +22,6 @@ module OData
|
|
20
22
|
|
21
23
|
private
|
22
24
|
|
23
|
-
def validate(value)
|
24
|
-
if value > max_value || value < min_value
|
25
|
-
raise ::ArgumentError, "Value is outside accepted range: #{min_value} to #{max_value}"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
25
|
def min_value
|
30
26
|
@min ||= -(2**63)
|
31
27
|
end
|
@@ -59,11 +55,11 @@ module OData
|
|
59
55
|
private
|
60
56
|
|
61
57
|
def min_value
|
62
|
-
@min ||= -(2**
|
58
|
+
@min ||= -(2**31)
|
63
59
|
end
|
64
60
|
|
65
61
|
def max_value
|
66
|
-
@max ||= (2**
|
62
|
+
@max ||= (2**31)-1
|
67
63
|
end
|
68
64
|
end
|
69
65
|
|
@@ -1,9 +1,57 @@
|
|
1
1
|
module OData
|
2
2
|
module Properties
|
3
3
|
class String < OData::Property
|
4
|
+
def value
|
5
|
+
if @value.nil? && allows_nil?
|
6
|
+
nil
|
7
|
+
else
|
8
|
+
encode_value(@value)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def value=(new_value)
|
13
|
+
validate(new_value)
|
14
|
+
@value = new_value.nil? ? nil : encode_value(new_value.to_s)
|
15
|
+
end
|
16
|
+
|
4
17
|
def type
|
5
18
|
'Edm.String'
|
6
19
|
end
|
20
|
+
|
21
|
+
def is_unicode?
|
22
|
+
options[:unicode]
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_default_value?
|
26
|
+
not(options[:default_value].nil?)
|
27
|
+
end
|
28
|
+
|
29
|
+
def default_value
|
30
|
+
options[:default_value]
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def default_options
|
36
|
+
super.merge({
|
37
|
+
unicode: true,
|
38
|
+
default_value: nil
|
39
|
+
})
|
40
|
+
end
|
41
|
+
|
42
|
+
def validate(new_value)
|
43
|
+
if new_value.nil? && !allows_nil?
|
44
|
+
raise ArgumentError, 'This property does not allow for nil values to be set'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def encode_value(new_value)
|
49
|
+
if options[:unicode]
|
50
|
+
new_value.encode(Encoding::UTF_8)
|
51
|
+
else
|
52
|
+
new_value.encode(Encoding::ASCII)
|
53
|
+
end
|
54
|
+
end
|
7
55
|
end
|
8
56
|
end
|
9
57
|
end
|
data/lib/odata/property.rb
CHANGED
@@ -21,38 +21,6 @@ module OData
|
|
21
21
|
@allows_nil ||= options[:allows_nil]
|
22
22
|
end
|
23
23
|
|
24
|
-
def max_length
|
25
|
-
raise NotImplementedError
|
26
|
-
end
|
27
|
-
|
28
|
-
def fixed_length
|
29
|
-
raise NotImplementedError
|
30
|
-
end
|
31
|
-
|
32
|
-
def precision
|
33
|
-
raise NotImplementedError
|
34
|
-
end
|
35
|
-
|
36
|
-
def scale
|
37
|
-
raise NotImplementedError
|
38
|
-
end
|
39
|
-
|
40
|
-
def is_unicode?
|
41
|
-
raise NotImplementedError
|
42
|
-
end
|
43
|
-
|
44
|
-
def collation
|
45
|
-
raise NotImplementedError
|
46
|
-
end
|
47
|
-
|
48
|
-
def srid
|
49
|
-
raise NotImplementedError
|
50
|
-
end
|
51
|
-
|
52
|
-
def default_value
|
53
|
-
raise NotImplementedError
|
54
|
-
end
|
55
|
-
|
56
24
|
def concurrency_mode
|
57
25
|
@concurrecy_mode ||= options[:concurrency_mode]
|
58
26
|
end
|