odata4 0.7.0 → 0.8.0
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 +9 -0
- data/README.md +90 -9
- data/lib/odata4.rb +2 -0
- data/lib/odata4/complex_type.rb +8 -5
- data/lib/odata4/entity.rb +16 -11
- data/lib/odata4/entity_container.rb +75 -0
- data/lib/odata4/entity_set.rb +0 -1
- data/lib/odata4/enum_type.rb +3 -3
- data/lib/odata4/enum_type/property.rb +1 -1
- data/lib/odata4/navigation_property/proxy.rb +5 -1
- data/lib/odata4/properties/binary.rb +2 -2
- data/lib/odata4/properties/boolean.rb +1 -1
- data/lib/odata4/properties/date_time.rb +1 -1
- data/lib/odata4/properties/decimal.rb +2 -2
- data/lib/odata4/properties/number.rb +2 -2
- data/lib/odata4/properties/string.rb +2 -2
- data/lib/odata4/properties/time.rb +1 -1
- data/lib/odata4/property.rb +29 -8
- data/lib/odata4/schema.rb +146 -0
- data/lib/odata4/service.rb +74 -98
- data/lib/odata4/version.rb +1 -1
- data/odata4.gemspec +11 -11
- data/spec/odata4/complex_type_spec.rb +1 -21
- data/spec/odata4/entity_container_spec.rb +38 -0
- data/spec/odata4/entity_set_spec.rb +2 -2
- data/spec/odata4/enum_type_spec.rb +17 -39
- data/spec/odata4/properties/decimal_spec.rb +37 -10
- data/spec/odata4/property_spec.rb +57 -18
- data/spec/odata4/query/result_spec.rb +1 -1
- data/spec/odata4/query_spec.rb +7 -4
- data/spec/odata4/schema_spec.rb +97 -0
- data/spec/odata4/service_spec.rb +87 -37
- data/spec/odata4/usage_example_spec.rb +22 -22
- metadata +30 -24
@@ -46,7 +46,7 @@ module OData4
|
|
46
46
|
elsif members.values.include?(value)
|
47
47
|
value
|
48
48
|
else
|
49
|
-
|
49
|
+
validation_error "Value must be one of #{members.to_a}, but was: '#{value}'"
|
50
50
|
end
|
51
51
|
end.compact
|
52
52
|
end
|
@@ -34,6 +34,10 @@ module OData4
|
|
34
34
|
@namespace ||= service.namespace
|
35
35
|
end
|
36
36
|
|
37
|
+
def schema
|
38
|
+
@schema ||= service.schemas[namespace]
|
39
|
+
end
|
40
|
+
|
37
41
|
def entity_type
|
38
42
|
@entity_type ||= entity.name
|
39
43
|
end
|
@@ -43,7 +47,7 @@ module OData4
|
|
43
47
|
end
|
44
48
|
|
45
49
|
def nav_property
|
46
|
-
|
50
|
+
schema.navigation_properties[entity_type][nav_name]
|
47
51
|
end
|
48
52
|
|
49
53
|
def fetch_result
|
@@ -42,9 +42,9 @@ module OData4
|
|
42
42
|
|
43
43
|
def validate(value)
|
44
44
|
unless [0,1,'0','1',true,false].include?(value)
|
45
|
-
|
45
|
+
validation_error 'Value is outside accepted range: 0 or 1'
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
50
|
-
end
|
50
|
+
end
|
@@ -29,7 +29,7 @@ module OData4
|
|
29
29
|
def validate(value)
|
30
30
|
return if value.nil? && allows_nil?
|
31
31
|
unless [0,1,'0','1','true','false',true,false].include?(value)
|
32
|
-
|
32
|
+
validation_error 'Value is outside accepted range: true or false'
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -65,7 +65,7 @@ module OData4
|
|
65
65
|
return if value.is_a?(date_class)
|
66
66
|
date_class.parse(value)
|
67
67
|
rescue
|
68
|
-
|
68
|
+
validation_error "Value '#{value}' is not a date time format that can be parsed"
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
@@ -27,14 +27,14 @@ module OData4
|
|
27
27
|
# Value to be used in URLs.
|
28
28
|
# @return [String]
|
29
29
|
def url_value
|
30
|
-
"#{value.to_f}
|
30
|
+
"#{value.to_f}"
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
34
34
|
|
35
35
|
def validate(value)
|
36
36
|
if value > max_value || value < min_value || value.precs.first > 29
|
37
|
-
|
37
|
+
validation_error "Value is outside accepted range: #{min_value} to #{max_value}, or has more than 29 significant digits"
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -6,9 +6,9 @@ module OData4
|
|
6
6
|
|
7
7
|
def validate(value)
|
8
8
|
if value > max_value || value < min_value
|
9
|
-
|
9
|
+
validation_error "Value is outside accepted range: #{min_value} to #{max_value}"
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
14
|
-
end
|
14
|
+
end
|
@@ -56,7 +56,7 @@ module OData4
|
|
56
56
|
|
57
57
|
def validate(new_value)
|
58
58
|
if new_value.nil? && !allows_nil?
|
59
|
-
|
59
|
+
validation_error 'This property does not allow for nil values to be set'
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -69,4 +69,4 @@ module OData4
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
72
|
-
end
|
72
|
+
end
|
data/lib/odata4/property.rb
CHANGED
@@ -8,6 +8,8 @@ module OData4
|
|
8
8
|
attr_reader :name
|
9
9
|
# The property's value
|
10
10
|
attr_accessor :value
|
11
|
+
# The property's options
|
12
|
+
attr_reader :options
|
11
13
|
|
12
14
|
# Default intialization for a property with a name, value and options.
|
13
15
|
# @param name [to_s]
|
@@ -44,13 +46,19 @@ module OData4
|
|
44
46
|
# (Default=false)
|
45
47
|
# @return [Boolean]
|
46
48
|
def strict?
|
47
|
-
options
|
49
|
+
if options.key? :strict
|
50
|
+
options[:strict]
|
51
|
+
elsif service
|
52
|
+
service.options[:strict]
|
53
|
+
else
|
54
|
+
true
|
55
|
+
end
|
48
56
|
end
|
49
57
|
|
50
58
|
# The configured concurrency mode for the property.
|
51
59
|
# @return [String]
|
52
60
|
def concurrency_mode
|
53
|
-
@
|
61
|
+
@concurrency_mode ||= options[:concurrency_mode]
|
54
62
|
end
|
55
63
|
|
56
64
|
# Value to be used in XML.
|
@@ -76,7 +84,7 @@ module OData4
|
|
76
84
|
# @param xml_builder [Nokogiri::XML::Builder]
|
77
85
|
def to_xml(xml_builder)
|
78
86
|
attributes = {
|
79
|
-
|
87
|
+
'metadata:type' => type,
|
80
88
|
}
|
81
89
|
|
82
90
|
if value.nil?
|
@@ -101,18 +109,31 @@ module OData4
|
|
101
109
|
new(property_xml.name, content, options)
|
102
110
|
end
|
103
111
|
|
104
|
-
|
112
|
+
protected
|
105
113
|
|
106
114
|
def default_options
|
107
115
|
{
|
108
116
|
allows_nil: true,
|
109
|
-
concurrency_mode: :none
|
110
|
-
strict: false
|
117
|
+
concurrency_mode: :none
|
111
118
|
}
|
112
119
|
end
|
113
120
|
|
114
|
-
def
|
115
|
-
|
121
|
+
def service
|
122
|
+
options[:service]
|
123
|
+
end
|
124
|
+
|
125
|
+
def logger
|
126
|
+
# Use a dummy logger if service is not available (-> unit tests)
|
127
|
+
@logger ||= service.andand.logger || Logger.new('/dev/null')
|
128
|
+
end
|
129
|
+
|
130
|
+
def validation_error(message)
|
131
|
+
if strict?
|
132
|
+
raise ArgumentError, "#{name}: #{message}"
|
133
|
+
else
|
134
|
+
logger.warn "#{name}: #{message}"
|
135
|
+
nil
|
136
|
+
end
|
116
137
|
end
|
117
138
|
end
|
118
139
|
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module OData4
|
2
|
+
class Schema
|
3
|
+
# The schema's parent service
|
4
|
+
attr_reader :service
|
5
|
+
# The schema's metadata (i.e its XML definition)
|
6
|
+
attr_reader :metadata
|
7
|
+
|
8
|
+
# Creates a new schema.
|
9
|
+
#
|
10
|
+
# @param schema_definition [Nokogiri::XML] The schema's XML definition
|
11
|
+
# @param service [OData4::Service] The schema's parent service
|
12
|
+
def initialize(schema_definition, service)
|
13
|
+
@metadata = schema_definition
|
14
|
+
@service = service
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns the schema's `Namespace` attribute (mandatory).
|
18
|
+
# @return [String]
|
19
|
+
def namespace
|
20
|
+
@namespace ||= metadata.attributes['Namespace'].value
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns a list of actions defined by the schema.
|
24
|
+
# @return [Array<String>]
|
25
|
+
def actions
|
26
|
+
@actions ||= metadata.xpath('//Action').map do |action|
|
27
|
+
action.attributes['Name'].value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns a list of entities defined by the schema.
|
32
|
+
# @return [Array<String>]
|
33
|
+
def entity_types
|
34
|
+
@entity_types ||= metadata.xpath('//EntityType').map do |entity|
|
35
|
+
entity.attributes['Name'].value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns a list of `ComplexType`s defined by the schema.
|
40
|
+
# @return [Hash<String, OData4::ComplexType>]
|
41
|
+
def complex_types
|
42
|
+
@complex_types ||= metadata.xpath('//ComplexType').map do |entity|
|
43
|
+
[
|
44
|
+
entity.attributes['Name'].value,
|
45
|
+
::OData4::ComplexType.new(entity, self)
|
46
|
+
]
|
47
|
+
end.to_h
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns a list of EnumTypes defined by the schema.
|
51
|
+
# @return [Hash<String, OData4::EnumType>]
|
52
|
+
def enum_types
|
53
|
+
@enum_types ||= metadata.xpath('//EnumType').map do |entity|
|
54
|
+
[
|
55
|
+
entity.attributes['Name'].value,
|
56
|
+
::OData4::EnumType.new(entity, self)
|
57
|
+
]
|
58
|
+
end.to_h
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns a list of functions defined by the schema.
|
62
|
+
# @return [Array<String>]
|
63
|
+
def functions
|
64
|
+
@functions ||= metadata.xpath('//Function').map do |function|
|
65
|
+
function.attributes['Name'].value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns a list of type definitions defined by the schema.
|
70
|
+
# @return [Array<String>]
|
71
|
+
def type_definitions
|
72
|
+
@typedefs ||= metadata.xpath('//TypeDefinition').map do |typedef|
|
73
|
+
typedef.attributes['Name'].value
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns a hash for finding an association through an entity type's defined
|
78
|
+
# NavigationProperty elements.
|
79
|
+
# @return [Hash<Hash<OData4::NavigationProperty>>]
|
80
|
+
def navigation_properties
|
81
|
+
@navigation_properties ||= metadata.xpath('//EntityType').map do |entity_type_def|
|
82
|
+
[
|
83
|
+
entity_type_def.attributes['Name'].value,
|
84
|
+
entity_type_def.xpath('./NavigationProperty').map do |nav_property_def|
|
85
|
+
[
|
86
|
+
nav_property_def.attributes['Name'].value,
|
87
|
+
::OData4::NavigationProperty.build(nav_property_def)
|
88
|
+
]
|
89
|
+
end.to_h
|
90
|
+
]
|
91
|
+
end.to_h
|
92
|
+
end
|
93
|
+
|
94
|
+
# Get the property type for an entity from metadata.
|
95
|
+
#
|
96
|
+
# @param entity_name [to_s] the name of the relevant entity
|
97
|
+
# @param property_name [to_s] the property name needed
|
98
|
+
# @return [String] the name of the property's type
|
99
|
+
def get_property_type(entity_name, property_name)
|
100
|
+
metadata.xpath("//EntityType[@Name='#{entity_name}']/Property[@Name='#{property_name}']").first.attributes['Type'].value
|
101
|
+
end
|
102
|
+
|
103
|
+
# Get the primary key for the supplied Entity.
|
104
|
+
#
|
105
|
+
# @param entity_name [to_s]
|
106
|
+
# @return [String]
|
107
|
+
def primary_key_for(entity_name)
|
108
|
+
metadata.xpath("//EntityType[@Name='#{entity_name}']/Key/PropertyRef").first.attributes['Name'].value
|
109
|
+
end
|
110
|
+
|
111
|
+
# Get the list of properties and their various options for the supplied
|
112
|
+
# Entity name.
|
113
|
+
# @param entity_name [to_s]
|
114
|
+
# @return [Hash]
|
115
|
+
# @api private
|
116
|
+
def properties_for_entity(entity_name)
|
117
|
+
type_definition = metadata.xpath("//EntityType[@Name='#{entity_name}']").first
|
118
|
+
raise ArgumentError, "Unknown EntityType: #{entity_name}" if type_definition.nil?
|
119
|
+
properties_to_return = {}
|
120
|
+
type_definition.xpath('./Property').each do |property_xml|
|
121
|
+
property_name, property = process_property_from_xml(property_xml)
|
122
|
+
properties_to_return[property_name] = property
|
123
|
+
end
|
124
|
+
properties_to_return
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def process_property_from_xml(property_xml)
|
130
|
+
property_name = property_xml.attributes['Name'].value
|
131
|
+
value_type = property_xml.attributes['Type'].value
|
132
|
+
property_options = { service: service }
|
133
|
+
|
134
|
+
klass = ::OData4::PropertyRegistry[value_type]
|
135
|
+
|
136
|
+
if klass.nil?
|
137
|
+
raise RuntimeError, "Unknown property type: #{value_type}"
|
138
|
+
else
|
139
|
+
property_options[:allows_nil] = false if property_xml.attributes['Nullable'] == 'false'
|
140
|
+
property = klass.new(property_name, nil, property_options)
|
141
|
+
end
|
142
|
+
|
143
|
+
return [property_name, property]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
data/lib/odata4/service.rb
CHANGED
@@ -52,64 +52,78 @@ module OData4
|
|
52
52
|
"#{service_url}/$metadata"
|
53
53
|
end
|
54
54
|
|
55
|
-
# Returns
|
56
|
-
|
57
|
-
|
55
|
+
# Returns the service's metadata definition.
|
56
|
+
# @return [Nokogiri::XML]
|
57
|
+
def metadata
|
58
|
+
@metadata ||= lambda { read_metadata }.call
|
58
59
|
end
|
59
60
|
|
60
|
-
# Returns
|
61
|
-
|
62
|
-
|
61
|
+
# Returns all of the service's schemas.
|
62
|
+
# @return Hash<String, OData4::Schema>
|
63
|
+
def schemas
|
64
|
+
@schemas ||= metadata.xpath('//Schema').map do |schema_xml|
|
63
65
|
[
|
64
|
-
|
65
|
-
|
66
|
+
schema_xml.attributes['Namespace'].value,
|
67
|
+
Schema.new(schema_xml, self)
|
66
68
|
]
|
67
|
-
|
69
|
+
end.to_h
|
68
70
|
end
|
69
71
|
|
70
|
-
# Returns
|
71
|
-
# @return
|
72
|
-
def
|
73
|
-
@
|
74
|
-
[
|
75
|
-
entity.attributes['Name'].value,
|
76
|
-
::OData4::ComplexType.new(entity, self)
|
77
|
-
]
|
78
|
-
end.to_h
|
72
|
+
# Returns the service's EntityContainer (singleton)
|
73
|
+
# @return OData4::EntityContainer
|
74
|
+
def entity_container
|
75
|
+
@entity_container ||= EntityContainer.new(self)
|
79
76
|
end
|
80
77
|
|
81
|
-
# Returns a
|
82
|
-
# @return
|
83
|
-
def
|
84
|
-
|
85
|
-
[
|
86
|
-
entity.attributes['Name'].value,
|
87
|
-
::OData4::EnumType.new(entity, self)
|
88
|
-
]
|
89
|
-
end.to_h
|
78
|
+
# Returns a hash of EntitySet names and their respective EntityType names
|
79
|
+
# @return Hash<String, String>
|
80
|
+
def entity_sets
|
81
|
+
entity_container.entity_sets
|
90
82
|
end
|
91
83
|
|
92
|
-
#
|
93
|
-
#
|
94
|
-
# @
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
[
|
99
|
-
entity_type_name,
|
100
|
-
entity_type_def.xpath('./NavigationProperty').collect do |nav_property_def|
|
101
|
-
[
|
102
|
-
nav_property_def.attributes['Name'].value,
|
103
|
-
::OData4::NavigationProperty.build(nav_property_def)
|
104
|
-
]
|
105
|
-
end.to_h
|
106
|
-
]
|
107
|
-
end.to_h
|
84
|
+
# Retrieves the EntitySet associated with a specific EntityType by name
|
85
|
+
#
|
86
|
+
# @param entity_set_name [to_s] the name of the EntitySet desired
|
87
|
+
# @return [OData4::EntitySet] an OData4::EntitySet to query
|
88
|
+
def [](entity_set_name)
|
89
|
+
entity_container[entity_set_name]
|
108
90
|
end
|
109
91
|
|
110
|
-
# Returns the namespace
|
92
|
+
# Returns the default namespace, that is, the namespace of the schema
|
93
|
+
# that contains the service's EntityContainer.
|
94
|
+
# @return [String]
|
111
95
|
def namespace
|
112
|
-
|
96
|
+
entity_container.namespace
|
97
|
+
end
|
98
|
+
|
99
|
+
# Returns a list of `EntityType`s exposed by the service
|
100
|
+
# @return Array<String>
|
101
|
+
def entity_types
|
102
|
+
@entity_types ||= schemas.map do |namespace, schema|
|
103
|
+
schema.entity_types.map do |entity_type|
|
104
|
+
"#{namespace}.#{entity_type}"
|
105
|
+
end
|
106
|
+
end.flatten
|
107
|
+
end
|
108
|
+
|
109
|
+
# Returns a list of `ComplexType`s used by the service.
|
110
|
+
# @return [Hash<String, OData4::ComplexType>]
|
111
|
+
def complex_types
|
112
|
+
@complex_types ||= schemas.map do |namespace, schema|
|
113
|
+
schema.complex_types.map do |name, complex_type|
|
114
|
+
[ "#{namespace}.#{name}", complex_type ]
|
115
|
+
end.to_h
|
116
|
+
end.reduce({}, :merge)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Returns a list of `EnumType`s used by the service
|
120
|
+
# @return [Hash<String, OData4::EnumType>]
|
121
|
+
def enum_types
|
122
|
+
@enum_types ||= schemas.map do |namespace, schema|
|
123
|
+
schema.enum_types.map do |name, enum_type|
|
124
|
+
[ "#{namespace}.#{name}", enum_type ]
|
125
|
+
end.to_h
|
126
|
+
end.reduce({}, :merge)
|
113
127
|
end
|
114
128
|
|
115
129
|
# Returns a more compact inspection of the service object
|
@@ -117,23 +131,6 @@ module OData4
|
|
117
131
|
"#<#{self.class.name}:#{self.object_id} name='#{name}' service_url='#{self.service_url}'>"
|
118
132
|
end
|
119
133
|
|
120
|
-
# Retrieves the EntitySet associated with a specific EntityType by name
|
121
|
-
#
|
122
|
-
# @param entity_set_name [to_s] the name of the EntitySet desired
|
123
|
-
# @return [OData4::EntitySet] an OData4::EntitySet to query
|
124
|
-
def [](entity_set_name)
|
125
|
-
xpath_query = "//EntityContainer/EntitySet[@Name='#{entity_set_name}']"
|
126
|
-
entity_set_node = metadata.xpath(xpath_query).first
|
127
|
-
raise ArgumentError, "Unknown Entity Set: #{entity_set_name}" if entity_set_node.nil?
|
128
|
-
container_name = entity_set_node.parent.attributes['Name'].value
|
129
|
-
entity_type_name = entity_set_node.attributes['EntityType'].value.gsub(/#{namespace}\./, '')
|
130
|
-
OData4::EntitySet.new(name: entity_set_name,
|
131
|
-
namespace: namespace,
|
132
|
-
type: entity_type_name.to_s,
|
133
|
-
service_name: name,
|
134
|
-
container: container_name)
|
135
|
-
end
|
136
|
-
|
137
134
|
# Execute a request against the service
|
138
135
|
#
|
139
136
|
# @param url_chunk [to_s] string to append to service url
|
@@ -189,19 +186,23 @@ module OData4
|
|
189
186
|
|
190
187
|
# Get the property type for an entity from metadata.
|
191
188
|
#
|
192
|
-
# @param entity_name [to_s] the
|
189
|
+
# @param entity_name [to_s] the fully qualified entity name
|
193
190
|
# @param property_name [to_s] the property name needed
|
194
191
|
# @return [String] the name of the property's type
|
195
192
|
def get_property_type(entity_name, property_name)
|
196
|
-
|
193
|
+
namespace, _, entity_name = entity_name.rpartition('.')
|
194
|
+
raise ArgumentError, 'Namespace missing' if namespace.nil? || namespace.empty?
|
195
|
+
schemas[namespace].get_property_type(entity_name, property_name)
|
197
196
|
end
|
198
197
|
|
199
198
|
# Get the primary key for the supplied Entity.
|
200
199
|
#
|
201
|
-
# @param entity_name [to_s]
|
200
|
+
# @param entity_name [to_s] The fully qualified entity name
|
202
201
|
# @return [String]
|
203
202
|
def primary_key_for(entity_name)
|
204
|
-
|
203
|
+
namespace, _, entity_name = entity_name.rpartition('.')
|
204
|
+
raise ArgumentError, 'Namespace missing' if namespace.nil? || namespace.empty?
|
205
|
+
schemas[namespace].primary_key_for(entity_name)
|
205
206
|
end
|
206
207
|
|
207
208
|
# Get the list of properties and their various options for the supplied
|
@@ -210,14 +211,9 @@ module OData4
|
|
210
211
|
# @return [Hash]
|
211
212
|
# @api private
|
212
213
|
def properties_for_entity(entity_name)
|
213
|
-
|
214
|
-
raise ArgumentError,
|
215
|
-
|
216
|
-
type_definition.xpath('./Property').each do |property_xml|
|
217
|
-
property_name, property = process_property_from_xml(property_xml)
|
218
|
-
properties_to_return[property_name] = property
|
219
|
-
end
|
220
|
-
properties_to_return
|
214
|
+
namespace, _, entity_name = entity_name.rpartition('.')
|
215
|
+
raise ArgumentError, 'Namespace missing' if namespace.nil? || namespace.empty?
|
216
|
+
schemas[namespace].properties_for_entity(entity_name)
|
221
217
|
end
|
222
218
|
|
223
219
|
# Returns the log level set via initial options, or the
|
@@ -262,7 +258,8 @@ module OData4
|
|
262
258
|
typhoeus: {
|
263
259
|
headers: { 'OData4-Version' => '4.0' },
|
264
260
|
timeout: HTTP_TIMEOUT
|
265
|
-
}
|
261
|
+
},
|
262
|
+
strict: true # strict property validation
|
266
263
|
}
|
267
264
|
end
|
268
265
|
|
@@ -276,10 +273,6 @@ module OData4
|
|
276
273
|
end
|
277
274
|
end
|
278
275
|
|
279
|
-
def metadata
|
280
|
-
@metadata ||= lambda { read_metadata }.call
|
281
|
-
end
|
282
|
-
|
283
276
|
def read_metadata
|
284
277
|
response = nil
|
285
278
|
# From file, good for debugging
|
@@ -314,30 +307,13 @@ module OData4
|
|
314
307
|
OData4::Query::Result.new(nil, response).error_message
|
315
308
|
end
|
316
309
|
|
317
|
-
def process_property_from_xml(property_xml)
|
318
|
-
property_name = property_xml.attributes['Name'].value
|
319
|
-
value_type = property_xml.attributes['Type'].value
|
320
|
-
property_options = {}
|
321
|
-
|
322
|
-
klass = ::OData4::PropertyRegistry[value_type]
|
323
|
-
|
324
|
-
if klass.nil?
|
325
|
-
raise RuntimeError, "Unknown property type: #{value_type}"
|
326
|
-
else
|
327
|
-
property_options[:allows_nil] = false if property_xml.attributes['Nullable'] == 'false'
|
328
|
-
property = klass.new(property_name, nil, property_options)
|
329
|
-
end
|
330
|
-
|
331
|
-
return [property_name, property]
|
332
|
-
end
|
333
|
-
|
334
310
|
def register_custom_types
|
335
311
|
complex_types.each do |name, type|
|
336
|
-
::OData4::PropertyRegistry.add(
|
312
|
+
::OData4::PropertyRegistry.add(name, type.property_class)
|
337
313
|
end
|
338
314
|
|
339
315
|
enum_types.each do |name, type|
|
340
|
-
::OData4::PropertyRegistry.add(
|
316
|
+
::OData4::PropertyRegistry.add(name, type.property_class)
|
341
317
|
end
|
342
318
|
end
|
343
319
|
end
|