odata 0.3.1 → 0.3.2
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 +0 -13
- data/CHANGELOG.md +4 -0
- data/lib/odata.rb +2 -2
- data/lib/odata/entity.rb +64 -47
- data/lib/odata/entity_set.rb +17 -20
- data/lib/odata/properties/boolean.rb +5 -0
- data/lib/odata/properties/integer.rb +16 -24
- data/lib/odata/property.rb +22 -0
- data/lib/odata/query.rb +105 -41
- data/lib/odata/query/criteria.rb +54 -48
- data/lib/odata/service.rb +2 -2
- data/lib/odata/version.rb +1 -1
- data/odata.gemspec +1 -2
- data/spec/fixtures/vcr_cassettes/entity_set_specs.yml +952 -0
- data/spec/fixtures/vcr_cassettes/entity_set_specs/bad_entry.yml +220 -0
- data/spec/fixtures/vcr_cassettes/entity_set_specs/existing_entry.yml +313 -0
- data/spec/fixtures/vcr_cassettes/entity_set_specs/new_entry.yml +226 -0
- data/spec/fixtures/vcr_cassettes/entity_specs.yml +164 -0
- data/spec/fixtures/vcr_cassettes/query_specs.yml +164 -0
- data/spec/fixtures/vcr_cassettes/service_registry_specs.yml +164 -0
- data/spec/fixtures/vcr_cassettes/service_specs.yml +164 -0
- data/spec/odata/entity_set_spec.rb +22 -40
- data/spec/odata/entity_spec.rb +5 -5
- data/spec/odata/query/criteria_spec.rb +57 -24
- data/spec/odata/query_spec.rb +79 -40
- data/spec/odata/service_registry_spec.rb +1 -1
- data/spec/odata/service_spec.rb +1 -7
- data/spec/spec_helper.rb +9 -46
- metadata +21 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 899ee301dd62dc8969c8a8d8191adc586b287527
|
4
|
+
data.tar.gz: 9d9122c36019cfa78a3e4567b9739e8353b07db3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 422c217129c1f82e13d3641d8468cc3ff6bc65224db8da0c17cc1e1c1c012d093e1b5e0f891c48224088f1ae01fa132b89e6bb5edc44b8c4c3b3663e88792023
|
7
|
+
data.tar.gz: 262866a54904f052099030cf1393359b2e9ba7dd06fc4bfbd56a18ea004ba6262fcc6994ea2383b175abe0d01225785661556e2dc24ec2c45695b5d91316f7f2
|
data/.travis.yml
CHANGED
@@ -11,9 +11,6 @@ jdk:
|
|
11
11
|
- openjdk7
|
12
12
|
- oraclejdk7
|
13
13
|
- oraclejdk8
|
14
|
-
env:
|
15
|
-
- REAL_HTTP=true
|
16
|
-
- REAL_HTTP=false
|
17
14
|
branches:
|
18
15
|
only:
|
19
16
|
- master
|
@@ -25,40 +22,30 @@ matrix:
|
|
25
22
|
jdk: oraclejdk7
|
26
23
|
- rvm: 1.9.3
|
27
24
|
jdk: oraclejdk8
|
28
|
-
- rvm: 1.9.3
|
29
|
-
env: REAL_HTTP=true
|
30
25
|
- rvm: 2.0.0
|
31
26
|
jdk: openjdk6
|
32
27
|
- rvm: 2.0.0
|
33
28
|
jdk: oraclejdk7
|
34
29
|
- rvm: 2.0.0
|
35
30
|
jdk: oraclejdk8
|
36
|
-
- rvm: 2.0.0
|
37
|
-
env: REAL_HTTP=true
|
38
31
|
- rvm: 2.1.0
|
39
32
|
jdk: openjdk6
|
40
33
|
- rvm: 2.1.0
|
41
34
|
jdk: oraclejdk7
|
42
35
|
- rvm: 2.1.0
|
43
36
|
jdk: oraclejdk8
|
44
|
-
- rvm: 2.1.0
|
45
|
-
env: REAL_HTTP=true
|
46
37
|
- rvm: 2.1.1
|
47
38
|
jdk: openjdk6
|
48
39
|
- rvm: 2.1.1
|
49
40
|
jdk: oraclejdk7
|
50
41
|
- rvm: 2.1.1
|
51
42
|
jdk: oraclejdk8
|
52
|
-
- rvm: 2.1.1
|
53
|
-
env: REAL_HTTP=true
|
54
43
|
- rvm: 2.1.2
|
55
44
|
jdk: openjdk6
|
56
45
|
- rvm: 2.1.2
|
57
46
|
jdk: oraclejdk7
|
58
47
|
- rvm: 2.1.2
|
59
48
|
jdk: oraclejdk8
|
60
|
-
- rvm: jruby
|
61
|
-
env: REAL_HTTP=true
|
62
49
|
addons:
|
63
50
|
code_climate:
|
64
51
|
repo_token: 56e2763b5bfe138f566c5f2bf23c14deee4f8990324436dbde07ee2a34bb87f8
|
data/CHANGELOG.md
CHANGED
data/lib/odata.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
require 'backports/2.1.0/enumerable/to_h'
|
2
|
-
|
3
1
|
require 'uri'
|
4
2
|
require 'date'
|
3
|
+
require 'bigdecimal'
|
5
4
|
require 'nokogiri'
|
6
5
|
require 'typhoeus'
|
7
6
|
|
@@ -14,6 +13,7 @@ require 'odata/property'
|
|
14
13
|
require 'odata/properties'
|
15
14
|
require 'odata/entity'
|
16
15
|
require 'odata/entity_set'
|
16
|
+
require 'odata/query/criteria'
|
17
17
|
require 'odata/query'
|
18
18
|
require 'odata/service'
|
19
19
|
require 'odata/service_registry'
|
data/lib/odata/entity.rb
CHANGED
@@ -1,16 +1,31 @@
|
|
1
1
|
module OData
|
2
|
+
# An OData::Entity represents a single record returned by the service. All
|
3
|
+
# Entities have a type and belong to a specific namespace. They are written
|
4
|
+
# back to the service via the EntitySet they came from. OData::Entity
|
5
|
+
# instances should not be instantiated directly; instead, they should either
|
6
|
+
# be read or instantiated from their respective OData::EntitySet.
|
2
7
|
class Entity
|
3
|
-
|
8
|
+
# The Entity type name
|
9
|
+
attr_reader :type
|
10
|
+
# The OData::Service namespace
|
11
|
+
attr_reader :namespace
|
4
12
|
|
13
|
+
# Initializes a bare Entity
|
14
|
+
# @param options [Hash]
|
5
15
|
def initialize(options = {})
|
6
16
|
@type = options[:type]
|
7
17
|
@namespace = options[:namespace]
|
8
18
|
end
|
9
19
|
|
20
|
+
# Returns name of Entity from Service specified type.
|
21
|
+
# @return [String]
|
10
22
|
def name
|
11
23
|
@name ||= type.gsub(/#{namespace}\./, '')
|
12
24
|
end
|
13
25
|
|
26
|
+
# Get property value
|
27
|
+
# @param property_name [to_s]
|
28
|
+
# @return [*]
|
14
29
|
def [](property_name)
|
15
30
|
begin
|
16
31
|
properties[property_name.to_s].value
|
@@ -19,6 +34,9 @@ module OData
|
|
19
34
|
end
|
20
35
|
end
|
21
36
|
|
37
|
+
# Set property value
|
38
|
+
# @param property_name [to_s]
|
39
|
+
# @param value [*]
|
22
40
|
def []=(property_name, value)
|
23
41
|
begin
|
24
42
|
properties[property_name.to_s].value = value
|
@@ -27,6 +45,10 @@ module OData
|
|
27
45
|
end
|
28
46
|
end
|
29
47
|
|
48
|
+
# Create Entity with provided properties and options.
|
49
|
+
# @param new_properties [Hash]
|
50
|
+
# @param options [Hash]
|
51
|
+
# @param [OData::Entity]
|
30
52
|
def self.with_properties(new_properties = {}, options = {})
|
31
53
|
entity = OData::Entity.new(options)
|
32
54
|
entity.instance_eval do
|
@@ -35,52 +57,27 @@ module OData
|
|
35
57
|
end
|
36
58
|
|
37
59
|
new_properties.each do |property_name, property_value|
|
38
|
-
self[property_name] = property_value
|
60
|
+
self[property_name.to_s] = property_value
|
39
61
|
end
|
40
62
|
end
|
41
63
|
entity
|
42
64
|
end
|
43
65
|
|
66
|
+
# Create Entity from XML document with provided options.
|
67
|
+
# @param xml_doc [Nokogiri::XML]
|
68
|
+
# @param options [Hash]
|
69
|
+
# @return [OData::Entity]
|
44
70
|
def self.from_xml(xml_doc, options = {})
|
45
71
|
return nil if xml_doc.nil?
|
46
72
|
entity = OData::Entity.new(options)
|
47
|
-
entity
|
48
|
-
|
49
|
-
|
50
|
-
if property_xml.attributes['null'] &&
|
51
|
-
property_xml.attributes['null'].value == 'true'
|
52
|
-
value = nil
|
53
|
-
value_type = service.get_property_type(name, property_name)
|
54
|
-
else
|
55
|
-
value_type = property_xml.attributes['type'].value
|
56
|
-
value = property_xml.content
|
57
|
-
end
|
58
|
-
klass_name = value_type.gsub(/^Edm\./, '')
|
59
|
-
property = get_property_class(klass_name).new(property_name, value)
|
60
|
-
set_property(property_name, property)
|
61
|
-
end
|
62
|
-
|
63
|
-
begin
|
64
|
-
title_value = xml_doc.xpath('//title').first.content
|
65
|
-
property_name = service.get_title_property_name(name)
|
66
|
-
value_type = service.get_property_type(name, property_name)
|
67
|
-
klass_name = value_type.gsub(/^Edm\./, '')
|
68
|
-
property = get_property_class(klass_name).new(property_name, title_value)
|
69
|
-
set_property(property_name, property)
|
70
|
-
end
|
71
|
-
|
72
|
-
begin
|
73
|
-
summary_value = xml_doc.xpath('//summary').first.content
|
74
|
-
property_name = service.get_summary_property_name(name)
|
75
|
-
value_type = service.get_property_type(name, property_name)
|
76
|
-
klass_name = value_type.gsub(/^Edm\./, '')
|
77
|
-
property = get_property_class(klass_name).new(property_name, summary_value)
|
78
|
-
set_property(property_name, property)
|
79
|
-
end
|
80
|
-
end
|
73
|
+
process_properties(entity, xml_doc)
|
74
|
+
process_feed_property(entity, xml_doc, 'title')
|
75
|
+
process_feed_property(entity, xml_doc, 'summary')
|
81
76
|
entity
|
82
77
|
end
|
83
78
|
|
79
|
+
# Converts Entity to its XML representation.
|
80
|
+
# @return [String]
|
84
81
|
def to_xml
|
85
82
|
builder = Nokogiri::XML::Builder.new do |xml|
|
86
83
|
xml.entry('xmlns' => 'http://www.w3.org/2005/Atom',
|
@@ -97,16 +94,7 @@ module OData
|
|
97
94
|
xml['metadata'].properties do
|
98
95
|
properties.each do |name, property|
|
99
96
|
next if name == primary_key
|
100
|
-
|
101
|
-
'metadata:type' => property.type,
|
102
|
-
}
|
103
|
-
|
104
|
-
if property.value.nil?
|
105
|
-
attributes['metadata:null'] = 'true'
|
106
|
-
xml['data'].send(name.to_sym, attributes)
|
107
|
-
else
|
108
|
-
xml['data'].send(name.to_sym, attributes, property.xml_value)
|
109
|
-
end
|
97
|
+
property.to_xml(xml)
|
110
98
|
end
|
111
99
|
end
|
112
100
|
end
|
@@ -115,13 +103,17 @@ module OData
|
|
115
103
|
builder.to_xml
|
116
104
|
end
|
117
105
|
|
106
|
+
# Returns the primary key for the Entity.
|
107
|
+
# @return [String]
|
118
108
|
def primary_key
|
119
109
|
service.primary_key_for(name)
|
120
110
|
end
|
121
111
|
|
122
112
|
private
|
123
113
|
|
124
|
-
def get_property_class(
|
114
|
+
def get_property_class(property_name)
|
115
|
+
value_type = service.get_property_type(name, property_name)
|
116
|
+
klass_name = value_type.gsub(/^Edm\./, '')
|
125
117
|
::OData::Properties.const_get(klass_name)
|
126
118
|
end
|
127
119
|
|
@@ -136,5 +128,30 @@ module OData
|
|
136
128
|
def set_property(name, odata_property)
|
137
129
|
properties[name.to_s] = odata_property.dup
|
138
130
|
end
|
131
|
+
|
132
|
+
def self.process_properties(entity, xml_doc)
|
133
|
+
entity.instance_eval do
|
134
|
+
xml_doc.xpath('//content/properties/*').each do |property_xml|
|
135
|
+
property_name = property_xml.name
|
136
|
+
if property_xml.attributes['null'] &&
|
137
|
+
property_xml.attributes['null'].value == 'true'
|
138
|
+
value = nil
|
139
|
+
else
|
140
|
+
value = property_xml.content
|
141
|
+
end
|
142
|
+
property = get_property_class(property_name).new(property_name, value)
|
143
|
+
set_property(property_name, property)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.process_feed_property(entity, xml_doc, property_name)
|
149
|
+
entity.instance_eval do
|
150
|
+
property_value = xml_doc.xpath("//#{property_name}").first.content
|
151
|
+
property_name = service.send("get_#{property_name}_property_name", name)
|
152
|
+
property = get_property_class(property_name).new(property_name, property_value)
|
153
|
+
set_property(property_name, property)
|
154
|
+
end
|
155
|
+
end
|
139
156
|
end
|
140
157
|
end
|
data/lib/odata/entity_set.rb
CHANGED
@@ -10,7 +10,14 @@ module OData
|
|
10
10
|
class EntitySet
|
11
11
|
include Enumerable
|
12
12
|
|
13
|
-
|
13
|
+
# The name of the EntitySet
|
14
|
+
attr_reader :name
|
15
|
+
# The Entity type for the EntitySet
|
16
|
+
attr_reader :type
|
17
|
+
# The OData::Service namespace
|
18
|
+
attr_reader :namespace
|
19
|
+
# The EntitySet's container name
|
20
|
+
attr_reader :container
|
14
21
|
|
15
22
|
# Sets up the EntitySet to permit querying for the resources in the set.
|
16
23
|
#
|
@@ -50,9 +57,7 @@ module OData
|
|
50
57
|
# Return the first Entity for the set.
|
51
58
|
# @return [OData::EntitySet]
|
52
59
|
def first
|
53
|
-
query = OData::Query.new(
|
54
|
-
query << OData::Query::Criteria.new(operation: 'skip', argument: 0)
|
55
|
-
query << OData::Query::Criteria.new(operation: 'top', argument: 1)
|
60
|
+
query = OData::Query.new(self).limit(1)
|
56
61
|
result = service.execute(query)
|
57
62
|
entities = service.find_entities(result)
|
58
63
|
OData::Entity.from_xml(entities[0], entity_options)
|
@@ -71,19 +76,13 @@ module OData
|
|
71
76
|
OData::Entity.with_properties(properties, entity_options)
|
72
77
|
end
|
73
78
|
|
74
|
-
#
|
75
|
-
# @
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
result = service.execute("#{name}?$filter=#{filter}")
|
79
|
+
# Returns a query targetted at the current EntitySet.
|
80
|
+
# @return [OData::Query]
|
81
|
+
def query
|
82
|
+
OData::Query.new(self)
|
83
|
+
end
|
80
84
|
|
81
|
-
service.find_entities(result).each do |entity_xml|
|
82
|
-
entities << OData::Entity.from_xml(entity_xml, entity_options)
|
83
|
-
end
|
84
85
|
|
85
|
-
entities
|
86
|
-
end
|
87
86
|
|
88
87
|
# Find the Entity with the supplied key value.
|
89
88
|
# @param key [to_s] primary key to lookup
|
@@ -107,7 +106,7 @@ module OData
|
|
107
106
|
method: :post,
|
108
107
|
body: entity.to_xml.gsub(/\n\s+/, ''),
|
109
108
|
headers: {
|
110
|
-
Accept
|
109
|
+
'Accept' => 'application/atom+xml',
|
111
110
|
'Content-Type' => 'application/atom+xml'
|
112
111
|
}
|
113
112
|
}
|
@@ -138,10 +137,8 @@ module OData
|
|
138
137
|
end
|
139
138
|
|
140
139
|
def get_paginated_entities(per_page, page)
|
141
|
-
query = OData::Query.new(
|
142
|
-
query
|
143
|
-
query << OData::Query::Criteria.new(operation: 'skip', argument: (per_page * page))
|
144
|
-
query << OData::Query::Criteria.new(operation: 'top', argument: per_page)
|
140
|
+
query = OData::Query.new(self)
|
141
|
+
query.include_count.skip(per_page * page).limit(per_page)
|
145
142
|
result = service.execute(query)
|
146
143
|
entities = service.find_entities(result)
|
147
144
|
total = service.find_node(result, 'count').content.to_i
|
@@ -2,6 +2,8 @@ module OData
|
|
2
2
|
module Properties
|
3
3
|
# Defines the Boolean OData type.
|
4
4
|
class Boolean < OData::Property
|
5
|
+
# Returns the property value, properly typecast
|
6
|
+
# @return [Boolean, nil]
|
5
7
|
def value
|
6
8
|
if @value.nil? && allows_nil?
|
7
9
|
nil
|
@@ -10,11 +12,14 @@ module OData
|
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
15
|
+
# Sets the property value
|
16
|
+
# @params new_value [Boolean]
|
13
17
|
def value=(new_value)
|
14
18
|
validate(new_value)
|
15
19
|
@value = new_value.to_s
|
16
20
|
end
|
17
21
|
|
22
|
+
# The OData type name
|
18
23
|
def type
|
19
24
|
'Edm.Boolean'
|
20
25
|
end
|
@@ -28,12 +28,16 @@ module OData
|
|
28
28
|
|
29
29
|
private
|
30
30
|
|
31
|
+
def exponent_size
|
32
|
+
63
|
33
|
+
end
|
34
|
+
|
31
35
|
def min_value
|
32
|
-
@min ||= -(2**
|
36
|
+
@min ||= -(2**exponent_size)
|
33
37
|
end
|
34
38
|
|
35
39
|
def max_value
|
36
|
-
@max ||= (2**
|
40
|
+
@max ||= (2**exponent_size)-1
|
37
41
|
end
|
38
42
|
end
|
39
43
|
|
@@ -46,12 +50,8 @@ module OData
|
|
46
50
|
|
47
51
|
private
|
48
52
|
|
49
|
-
def
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
def max_value
|
54
|
-
@max ||= (2**15)-1
|
53
|
+
def exponent_size
|
54
|
+
15
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -64,12 +64,8 @@ module OData
|
|
64
64
|
|
65
65
|
private
|
66
66
|
|
67
|
-
def
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
def max_value
|
72
|
-
@max ||= (2**31)-1
|
67
|
+
def exponent_size
|
68
|
+
31
|
73
69
|
end
|
74
70
|
end
|
75
71
|
|
@@ -85,12 +81,12 @@ module OData
|
|
85
81
|
|
86
82
|
private
|
87
83
|
|
88
|
-
def
|
89
|
-
|
84
|
+
def exponent_size
|
85
|
+
8
|
90
86
|
end
|
91
87
|
|
92
|
-
def
|
93
|
-
|
88
|
+
def min_value
|
89
|
+
0
|
94
90
|
end
|
95
91
|
end
|
96
92
|
|
@@ -103,12 +99,8 @@ module OData
|
|
103
99
|
|
104
100
|
private
|
105
101
|
|
106
|
-
def
|
107
|
-
|
108
|
-
end
|
109
|
-
|
110
|
-
def max_value
|
111
|
-
@max ||= (2**7)-1
|
102
|
+
def exponent_size
|
103
|
+
7
|
112
104
|
end
|
113
105
|
end
|
114
106
|
end
|