frodo 0.10.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 +7 -0
- data/.autotest +2 -0
- data/.circleci/config.yml +54 -0
- data/.gitignore +24 -0
- data/.gitlab-ci.yml +9 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +75 -0
- data/CHANGELOG.md +163 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +23 -0
- data/README.md +479 -0
- data/Rakefile +7 -0
- data/TODO.md +55 -0
- data/frodo.gemspec +39 -0
- data/images/frodo.jpg +0 -0
- data/lib/frodo/abstract_client.rb +11 -0
- data/lib/frodo/client.rb +6 -0
- data/lib/frodo/concerns/api.rb +292 -0
- data/lib/frodo/concerns/authentication.rb +32 -0
- data/lib/frodo/concerns/base.rb +84 -0
- data/lib/frodo/concerns/caching.rb +26 -0
- data/lib/frodo/concerns/connection.rb +79 -0
- data/lib/frodo/concerns/verbs.rb +68 -0
- data/lib/frodo/config.rb +143 -0
- data/lib/frodo/entity.rb +335 -0
- data/lib/frodo/entity_container.rb +75 -0
- data/lib/frodo/entity_set.rb +131 -0
- data/lib/frodo/errors.rb +70 -0
- data/lib/frodo/middleware/authentication/token.rb +13 -0
- data/lib/frodo/middleware/authentication.rb +87 -0
- data/lib/frodo/middleware/authorization.rb +18 -0
- data/lib/frodo/middleware/caching.rb +30 -0
- data/lib/frodo/middleware/custom_headers.rb +14 -0
- data/lib/frodo/middleware/gzip.rb +33 -0
- data/lib/frodo/middleware/instance_url.rb +20 -0
- data/lib/frodo/middleware/logger.rb +42 -0
- data/lib/frodo/middleware/multipart.rb +64 -0
- data/lib/frodo/middleware/odata_headers.rb +13 -0
- data/lib/frodo/middleware/raise_error.rb +47 -0
- data/lib/frodo/middleware.rb +33 -0
- data/lib/frodo/navigation_property/proxy.rb +80 -0
- data/lib/frodo/navigation_property.rb +29 -0
- data/lib/frodo/properties/binary.rb +50 -0
- data/lib/frodo/properties/boolean.rb +37 -0
- data/lib/frodo/properties/collection.rb +50 -0
- data/lib/frodo/properties/complex.rb +114 -0
- data/lib/frodo/properties/date.rb +27 -0
- data/lib/frodo/properties/date_time.rb +83 -0
- data/lib/frodo/properties/date_time_offset.rb +17 -0
- data/lib/frodo/properties/decimal.rb +54 -0
- data/lib/frodo/properties/enum.rb +62 -0
- data/lib/frodo/properties/float.rb +67 -0
- data/lib/frodo/properties/geography/base.rb +162 -0
- data/lib/frodo/properties/geography/line_string.rb +33 -0
- data/lib/frodo/properties/geography/point.rb +31 -0
- data/lib/frodo/properties/geography/polygon.rb +38 -0
- data/lib/frodo/properties/geography.rb +13 -0
- data/lib/frodo/properties/guid.rb +17 -0
- data/lib/frodo/properties/integer.rb +107 -0
- data/lib/frodo/properties/number.rb +14 -0
- data/lib/frodo/properties/string.rb +72 -0
- data/lib/frodo/properties/time.rb +40 -0
- data/lib/frodo/properties/time_of_day.rb +27 -0
- data/lib/frodo/properties.rb +32 -0
- data/lib/frodo/property.rb +139 -0
- data/lib/frodo/property_registry.rb +41 -0
- data/lib/frodo/query/criteria/comparison_operators.rb +49 -0
- data/lib/frodo/query/criteria/date_functions.rb +61 -0
- data/lib/frodo/query/criteria/geography_functions.rb +21 -0
- data/lib/frodo/query/criteria/lambda_operators.rb +27 -0
- data/lib/frodo/query/criteria/string_functions.rb +40 -0
- data/lib/frodo/query/criteria.rb +92 -0
- data/lib/frodo/query/in_batches.rb +58 -0
- data/lib/frodo/query.rb +221 -0
- data/lib/frodo/railtie.rb +19 -0
- data/lib/frodo/schema/complex_type.rb +79 -0
- data/lib/frodo/schema/enum_type.rb +95 -0
- data/lib/frodo/schema.rb +164 -0
- data/lib/frodo/service.rb +199 -0
- data/lib/frodo/service_registry.rb +52 -0
- data/lib/frodo/version.rb +3 -0
- data/lib/frodo.rb +67 -0
- data/spec/fixtures/auth_success_response.json +11 -0
- data/spec/fixtures/error.json +11 -0
- data/spec/fixtures/files/entity_to_xml.xml +18 -0
- data/spec/fixtures/files/error.xml +5 -0
- data/spec/fixtures/files/metadata.xml +150 -0
- data/spec/fixtures/files/metadata_with_error.xml +157 -0
- data/spec/fixtures/files/product_0.json +10 -0
- data/spec/fixtures/files/product_0.xml +28 -0
- data/spec/fixtures/files/products.json +106 -0
- data/spec/fixtures/files/products.xml +308 -0
- data/spec/fixtures/files/supplier_0.json +26 -0
- data/spec/fixtures/files/supplier_0.xml +32 -0
- data/spec/fixtures/leads.json +923 -0
- data/spec/fixtures/refresh_error_response.json +8 -0
- data/spec/frodo/abstract_client_spec.rb +13 -0
- data/spec/frodo/client_spec.rb +57 -0
- data/spec/frodo/concerns/authentication_spec.rb +79 -0
- data/spec/frodo/concerns/base_spec.rb +68 -0
- data/spec/frodo/concerns/caching_spec.rb +40 -0
- data/spec/frodo/concerns/connection_spec.rb +65 -0
- data/spec/frodo/config_spec.rb +127 -0
- data/spec/frodo/entity/shared_examples.rb +83 -0
- data/spec/frodo/entity_container_spec.rb +38 -0
- data/spec/frodo/entity_set_spec.rb +169 -0
- data/spec/frodo/entity_spec.rb +153 -0
- data/spec/frodo/errors_spec.rb +48 -0
- data/spec/frodo/middleware/authentication/token_spec.rb +87 -0
- data/spec/frodo/middleware/authentication_spec.rb +83 -0
- data/spec/frodo/middleware/authorization_spec.rb +17 -0
- data/spec/frodo/middleware/custom_headers_spec.rb +21 -0
- data/spec/frodo/middleware/gzip_spec.rb +68 -0
- data/spec/frodo/middleware/instance_url_spec.rb +27 -0
- data/spec/frodo/middleware/logger_spec.rb +21 -0
- data/spec/frodo/middleware/odata_headers_spec.rb +15 -0
- data/spec/frodo/middleware/raise_error_spec.rb +66 -0
- data/spec/frodo/navigation_property/proxy_spec.rb +46 -0
- data/spec/frodo/navigation_property_spec.rb +55 -0
- data/spec/frodo/properties/binary_spec.rb +50 -0
- data/spec/frodo/properties/boolean_spec.rb +72 -0
- data/spec/frodo/properties/collection_spec.rb +44 -0
- data/spec/frodo/properties/date_spec.rb +23 -0
- data/spec/frodo/properties/date_time_offset_spec.rb +30 -0
- data/spec/frodo/properties/date_time_spec.rb +23 -0
- data/spec/frodo/properties/decimal_spec.rb +50 -0
- data/spec/frodo/properties/float_spec.rb +45 -0
- data/spec/frodo/properties/geography/line_string_spec.rb +33 -0
- data/spec/frodo/properties/geography/point_spec.rb +29 -0
- data/spec/frodo/properties/geography/polygon_spec.rb +55 -0
- data/spec/frodo/properties/geography/shared_examples.rb +72 -0
- data/spec/frodo/properties/guid_spec.rb +17 -0
- data/spec/frodo/properties/integer_spec.rb +58 -0
- data/spec/frodo/properties/string_spec.rb +46 -0
- data/spec/frodo/properties/time_of_day_spec.rb +23 -0
- data/spec/frodo/properties/time_spec.rb +15 -0
- data/spec/frodo/property_registry_spec.rb +16 -0
- data/spec/frodo/property_spec.rb +71 -0
- data/spec/frodo/query/criteria_spec.rb +229 -0
- data/spec/frodo/query_spec.rb +156 -0
- data/spec/frodo/schema/complex_type_spec.rb +97 -0
- data/spec/frodo/schema/enum_type_spec.rb +112 -0
- data/spec/frodo/schema_spec.rb +113 -0
- data/spec/frodo/service_registry_spec.rb +19 -0
- data/spec/frodo/service_spec.rb +153 -0
- data/spec/frodo/usage_example_spec.rb +161 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/support/coverage.rb +2 -0
- data/spec/support/fixture_helpers.rb +14 -0
- data/spec/support/middleware.rb +19 -0
- metadata +479 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Frodo
|
|
2
|
+
module Properties
|
|
3
|
+
module Geography
|
|
4
|
+
class Polygon < Base
|
|
5
|
+
def type
|
|
6
|
+
'Edm.GeographyPolygon'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def coords_to_s
|
|
10
|
+
'(' + value.map { |pos| pos.join(' ') }.join(',') + ')'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def coords_from_s(str)
|
|
14
|
+
str.gsub(/[()]/, '')
|
|
15
|
+
.split(',').map { |pos| pos.split(' ').map(&:to_f) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def xml_value
|
|
19
|
+
{
|
|
20
|
+
exterior: {
|
|
21
|
+
LinearRing: value.map do |coords|
|
|
22
|
+
{ pos: coords.join(' ') }
|
|
23
|
+
end
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def self.parse_xml(property_xml)
|
|
31
|
+
property_xml.xpath('//pos').map do |el|
|
|
32
|
+
el.content.split(' ').map(&:to_f)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'frodo/properties/geography/base'
|
|
2
|
+
require 'frodo/properties/geography/point'
|
|
3
|
+
require 'frodo/properties/geography/line_string'
|
|
4
|
+
require 'frodo/properties/geography/polygon'
|
|
5
|
+
|
|
6
|
+
Frodo::Properties::Geography.constants.each do |property_name|
|
|
7
|
+
next if property_name =~ /Base$/
|
|
8
|
+
klass = Frodo::Properties::Geography.const_get(property_name)
|
|
9
|
+
if klass.is_a?(Class)
|
|
10
|
+
property = klass.new('test', nil)
|
|
11
|
+
Frodo::PropertyRegistry.add(property.type, property.class)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Frodo
|
|
2
|
+
module Properties
|
|
3
|
+
# Defines the GUID Frodo type.
|
|
4
|
+
class Guid < Frodo::Property
|
|
5
|
+
# The Frodo type name
|
|
6
|
+
def type
|
|
7
|
+
'Edm.Guid'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Value to be used in URLs.
|
|
11
|
+
# @return [String]
|
|
12
|
+
def url_value
|
|
13
|
+
"#{value}"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
module Frodo
|
|
2
|
+
module Properties
|
|
3
|
+
# Defines the Integer Frodo type.
|
|
4
|
+
class Integer < Frodo::Property
|
|
5
|
+
include Frodo::Properties::Number
|
|
6
|
+
|
|
7
|
+
# Returns the property value, properly typecast
|
|
8
|
+
# @return [Integer,nil]
|
|
9
|
+
def value
|
|
10
|
+
if (@value.nil? || @value.empty?) && allows_nil?
|
|
11
|
+
nil
|
|
12
|
+
else
|
|
13
|
+
@value.to_i
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Sets the property value
|
|
18
|
+
# @params new_value [to_i]
|
|
19
|
+
def value=(new_value)
|
|
20
|
+
validate(new_value.to_i)
|
|
21
|
+
@value = new_value.to_i.to_s
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# The Frodo type name
|
|
25
|
+
def type
|
|
26
|
+
'Edm.Int64'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def exponent_size
|
|
32
|
+
63
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def min_value
|
|
36
|
+
@min ||= -(2**exponent_size)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def max_value
|
|
40
|
+
@max ||= (2**exponent_size)-1
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Defines the Integer (16 bit) Frodo type.
|
|
45
|
+
class Int16 < Integer
|
|
46
|
+
# The Frodo type name
|
|
47
|
+
def type
|
|
48
|
+
'Edm.Int16'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def exponent_size
|
|
54
|
+
15
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Defines the Integer (32 bit) Frodo type.
|
|
59
|
+
class Int32 < Integer
|
|
60
|
+
# The Frodo type name
|
|
61
|
+
def type
|
|
62
|
+
'Edm.Int32'
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def exponent_size
|
|
68
|
+
31
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Defines the Integer (64 bit) Frodo type.
|
|
73
|
+
class Int64 < Integer; end
|
|
74
|
+
|
|
75
|
+
# Defines the Byte Frodo type.
|
|
76
|
+
class Byte < Integer
|
|
77
|
+
# The Frodo type name
|
|
78
|
+
def type
|
|
79
|
+
'Edm.Byte'
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def exponent_size
|
|
85
|
+
8
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def min_value
|
|
89
|
+
0
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Defines the Signed Byte Frodo type.
|
|
94
|
+
class SByte < Integer
|
|
95
|
+
# The Frodo type name
|
|
96
|
+
def type
|
|
97
|
+
'Edm.SByte'
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
private
|
|
101
|
+
|
|
102
|
+
def exponent_size
|
|
103
|
+
7
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Frodo
|
|
2
|
+
module Properties
|
|
3
|
+
# Defines common behavior for Frodo numeric types.
|
|
4
|
+
module Number
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def validate(value)
|
|
8
|
+
if value > max_value || value < min_value
|
|
9
|
+
validation_error "Value is outside accepted range: #{min_value} to #{max_value}"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module Frodo
|
|
2
|
+
module Properties
|
|
3
|
+
# Defines the String Frodo type.
|
|
4
|
+
class String < Frodo::Property
|
|
5
|
+
# Returns the property value, properly typecast
|
|
6
|
+
# @return [String,nil]
|
|
7
|
+
def value
|
|
8
|
+
if (@value.nil? || @value.empty?) && allows_nil?
|
|
9
|
+
nil
|
|
10
|
+
else
|
|
11
|
+
encode_value(@value)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Sets the property value
|
|
16
|
+
# @params new_value [to_s,nil]
|
|
17
|
+
def value=(new_value)
|
|
18
|
+
validate(new_value)
|
|
19
|
+
@value = new_value.nil? ? nil : encode_value(new_value.to_s)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Value to be used in URLs.
|
|
23
|
+
# @return [String]
|
|
24
|
+
def url_value
|
|
25
|
+
"'#{value}'"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# The Frodo type name
|
|
29
|
+
def type
|
|
30
|
+
'Edm.String'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Is the property value Unicode encoded
|
|
34
|
+
def is_unicode?
|
|
35
|
+
options[:unicode]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Does the property have a default value
|
|
39
|
+
def has_default_value?
|
|
40
|
+
not(options[:default_value].nil?)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# The default value for the property
|
|
44
|
+
def default_value
|
|
45
|
+
options[:default_value]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def default_options
|
|
51
|
+
super.merge({
|
|
52
|
+
unicode: true,
|
|
53
|
+
default_value: nil
|
|
54
|
+
})
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def validate(new_value)
|
|
58
|
+
if new_value.nil? && !allows_nil?
|
|
59
|
+
validation_error 'This property does not allow for nil values to be set'
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def encode_value(new_value)
|
|
64
|
+
if options[:unicode]
|
|
65
|
+
new_value.encode(Encoding::UTF_8)
|
|
66
|
+
else
|
|
67
|
+
new_value.encode(Encoding::ASCII)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Frodo
|
|
2
|
+
module Properties
|
|
3
|
+
# Defines the Time Frodo type.
|
|
4
|
+
class Time < Frodo::Property
|
|
5
|
+
# Returns the property value, properly typecast
|
|
6
|
+
# @return [Time,nil]
|
|
7
|
+
def value
|
|
8
|
+
if (@value.nil? || @value.empty?) && allows_nil?
|
|
9
|
+
nil
|
|
10
|
+
else
|
|
11
|
+
::Time.strptime(@value, '%H:%M:%S%:z')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Sets the property value
|
|
16
|
+
# @params new_value [Time]
|
|
17
|
+
def value=(new_value)
|
|
18
|
+
validate(new_value)
|
|
19
|
+
@value = parse_value(new_value)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# The Frodo type name
|
|
23
|
+
def type
|
|
24
|
+
'Edm.Time'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def validate(value)
|
|
30
|
+
unless value.is_a?(::Time)
|
|
31
|
+
validation_error 'Value is not a time object'
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def parse_value(value)
|
|
36
|
+
value.strftime('%H:%M:%S%:z')
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'frodo/properties/date_time'
|
|
2
|
+
|
|
3
|
+
module Frodo
|
|
4
|
+
module Properties
|
|
5
|
+
# Defines the Date Frodo type.
|
|
6
|
+
class TimeOfDay < Frodo::Properties::DateTime
|
|
7
|
+
# The Frodo type name
|
|
8
|
+
def type
|
|
9
|
+
'Edm.TimeOfDay'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def url_value
|
|
13
|
+
@value
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
protected
|
|
17
|
+
|
|
18
|
+
def date_class
|
|
19
|
+
::Time
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def strptime_format
|
|
23
|
+
'%H:%M:%S.%L'
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Modules
|
|
2
|
+
require 'frodo/properties/number'
|
|
3
|
+
|
|
4
|
+
# Implementations
|
|
5
|
+
require 'frodo/properties/binary'
|
|
6
|
+
require 'frodo/properties/boolean'
|
|
7
|
+
require 'frodo/properties/collection'
|
|
8
|
+
require 'frodo/properties/complex'
|
|
9
|
+
require 'frodo/properties/date'
|
|
10
|
+
require 'frodo/properties/date_time'
|
|
11
|
+
require 'frodo/properties/date_time_offset'
|
|
12
|
+
require 'frodo/properties/decimal'
|
|
13
|
+
require 'frodo/properties/enum'
|
|
14
|
+
require 'frodo/properties/float'
|
|
15
|
+
require 'frodo/properties/geography'
|
|
16
|
+
require 'frodo/properties/guid'
|
|
17
|
+
require 'frodo/properties/integer'
|
|
18
|
+
require 'frodo/properties/string'
|
|
19
|
+
require 'frodo/properties/time'
|
|
20
|
+
require 'frodo/properties/time_of_day'
|
|
21
|
+
|
|
22
|
+
Frodo::Properties.constants.each do |property_name|
|
|
23
|
+
klass = Frodo::Properties.const_get(property_name)
|
|
24
|
+
if klass.is_a?(Class)
|
|
25
|
+
begin
|
|
26
|
+
property = klass.new('test', nil)
|
|
27
|
+
Frodo::PropertyRegistry.add(property.type, property.class)
|
|
28
|
+
rescue NotImplementedError
|
|
29
|
+
# Abstract type classes cannot be instantiated, ignore
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
module Frodo
|
|
2
|
+
# Frodo::Property represents an abstract property, defining the basic
|
|
3
|
+
# interface and required methods, with some default implementations. All
|
|
4
|
+
# supported property types should be implemented under the Frodo::Properties
|
|
5
|
+
# namespace.
|
|
6
|
+
class Property
|
|
7
|
+
# The property's name
|
|
8
|
+
attr_reader :name
|
|
9
|
+
# The property's value
|
|
10
|
+
attr_accessor :value
|
|
11
|
+
# The property's options
|
|
12
|
+
attr_reader :options
|
|
13
|
+
|
|
14
|
+
# Default intialization for a property with a name, value and options.
|
|
15
|
+
# @param name [to_s]
|
|
16
|
+
# @param value [to_s,nil]
|
|
17
|
+
# @param options [Hash]
|
|
18
|
+
def initialize(name, value, options = {})
|
|
19
|
+
@name = name.to_s
|
|
20
|
+
@value = value.nil? ? nil : value.to_s
|
|
21
|
+
@options = default_options.merge(options)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Abstract implementation, should return property type, based on
|
|
25
|
+
# Frodo::Service metadata in proper implementation.
|
|
26
|
+
# @raise NotImplementedError
|
|
27
|
+
def type
|
|
28
|
+
raise NotImplementedError
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Provides for value-based equality checking.
|
|
32
|
+
# @param other [value] object for comparison
|
|
33
|
+
# @return [Boolean]
|
|
34
|
+
def ==(other)
|
|
35
|
+
self.value == other.value
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Whether the property permits a nil value.
|
|
39
|
+
# (Default=true)
|
|
40
|
+
# @return [Boolean]
|
|
41
|
+
def allows_nil?
|
|
42
|
+
options[:allows_nil]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Whether the property uses strict validation.
|
|
46
|
+
# (Default=false)
|
|
47
|
+
# @return [Boolean]
|
|
48
|
+
def strict?
|
|
49
|
+
if options.key? :strict
|
|
50
|
+
options[:strict]
|
|
51
|
+
elsif service
|
|
52
|
+
service.options[:strict]
|
|
53
|
+
else
|
|
54
|
+
true
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# The configured concurrency mode for the property.
|
|
59
|
+
# @return [String]
|
|
60
|
+
def concurrency_mode
|
|
61
|
+
@concurrency_mode ||= options[:concurrency_mode]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Value to be used in XML.
|
|
65
|
+
# @return [String]
|
|
66
|
+
def xml_value
|
|
67
|
+
@value
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Value to be used in JSON.
|
|
71
|
+
# @return [*]
|
|
72
|
+
def json_value
|
|
73
|
+
value
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Value to be used in URLs.
|
|
77
|
+
# @return [String]
|
|
78
|
+
def url_value
|
|
79
|
+
@value
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Returns the XML representation of the property to the supplied XML
|
|
83
|
+
# builder.
|
|
84
|
+
# @param xml_builder [Nokogiri::XML::Builder]
|
|
85
|
+
def to_xml(xml_builder)
|
|
86
|
+
attributes = {
|
|
87
|
+
'metadata:type' => type,
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if value.nil?
|
|
91
|
+
attributes['metadata:null'] = 'true'
|
|
92
|
+
xml_builder['data'].send(name.to_sym, attributes)
|
|
93
|
+
else
|
|
94
|
+
xml_builder['data'].send(name.to_sym, attributes, xml_value)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Creates a new property instance from an XML element
|
|
99
|
+
# @param property_xml [Nokogiri::XML::Element]
|
|
100
|
+
# @param options [Hash]
|
|
101
|
+
# @return [Frodo::Property]
|
|
102
|
+
def self.from_xml(property_xml, options = {})
|
|
103
|
+
if property_xml.attributes['null'].andand.value == 'true'
|
|
104
|
+
content = nil
|
|
105
|
+
else
|
|
106
|
+
content = property_xml.content
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
new(property_xml.name, content, options)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
protected
|
|
113
|
+
|
|
114
|
+
def default_options
|
|
115
|
+
{
|
|
116
|
+
allows_nil: true,
|
|
117
|
+
concurrency_mode: :none
|
|
118
|
+
}
|
|
119
|
+
end
|
|
120
|
+
|
|
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
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
|
|
3
|
+
module Frodo
|
|
4
|
+
# Provides a registry for keeping track of various property types used by
|
|
5
|
+
# Frodo.
|
|
6
|
+
class PropertyRegistry
|
|
7
|
+
include Singleton
|
|
8
|
+
|
|
9
|
+
# Add a property type to the registry
|
|
10
|
+
#
|
|
11
|
+
# @param type_name [String] property type name to register
|
|
12
|
+
# @param klass [Class] Ruby class to use for the specified type
|
|
13
|
+
def add(type_name, klass)
|
|
14
|
+
properties[type_name] = klass
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Lookup a property by name and get the Ruby class to use for its instances
|
|
18
|
+
#
|
|
19
|
+
# @param type_name [String] the type name to lookup
|
|
20
|
+
# @return [Class, nil] the proper class or nil
|
|
21
|
+
def [](type_name)
|
|
22
|
+
properties[type_name]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# (see #add)
|
|
26
|
+
def self.add(type_name, klass)
|
|
27
|
+
Frodo::PropertyRegistry.instance.add(type_name, klass)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# (see #[])
|
|
31
|
+
def self.[](type_name)
|
|
32
|
+
Frodo::PropertyRegistry.instance[type_name]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def properties
|
|
38
|
+
@properties ||= {}
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Frodo
|
|
2
|
+
class Query
|
|
3
|
+
class Criteria
|
|
4
|
+
module ComparisonOperators
|
|
5
|
+
# Sets up equality operator.
|
|
6
|
+
# @param value [to_s]
|
|
7
|
+
# @return [self]
|
|
8
|
+
def eq(value)
|
|
9
|
+
set_operator_and_value(:eq, value)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Sets up non-equality operator.
|
|
13
|
+
# @param value [to_s]
|
|
14
|
+
# @return [self]
|
|
15
|
+
def ne(value)
|
|
16
|
+
set_operator_and_value(:ne, value)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Sets up greater-than operator.
|
|
20
|
+
# @param value [to_s]
|
|
21
|
+
# @return [self]
|
|
22
|
+
def gt(value)
|
|
23
|
+
set_operator_and_value(:gt, value)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Sets up greater-than-or-equal operator.
|
|
27
|
+
# @param value [to_s]
|
|
28
|
+
# @return [self]
|
|
29
|
+
def ge(value)
|
|
30
|
+
set_operator_and_value(:ge, value)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Sets up less-than operator.
|
|
34
|
+
# @param value [to_s]
|
|
35
|
+
# @return [self]
|
|
36
|
+
def lt(value)
|
|
37
|
+
set_operator_and_value(:lt, value)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Sets up less-than-or-equal operator.
|
|
41
|
+
# @param value [to_s]
|
|
42
|
+
# @return [self]
|
|
43
|
+
def le(value)
|
|
44
|
+
set_operator_and_value(:le, value)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Frodo
|
|
2
|
+
class Query
|
|
3
|
+
class Criteria
|
|
4
|
+
module DateFunctions
|
|
5
|
+
# Applies the `year` function.
|
|
6
|
+
# @return [self]
|
|
7
|
+
def year
|
|
8
|
+
set_function_and_argument(:year, nil)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Applies the `month` function.
|
|
12
|
+
# @return [self]
|
|
13
|
+
def month
|
|
14
|
+
set_function_and_argument(:month, nil)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Applies the `day` function.
|
|
18
|
+
# @return [self]
|
|
19
|
+
def day
|
|
20
|
+
set_function_and_argument(:day, nil)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Applies the `hour` function.
|
|
24
|
+
# @return [self]
|
|
25
|
+
def hour
|
|
26
|
+
set_function_and_argument(:hour, nil)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Applies the `minute` function.
|
|
30
|
+
# @return [self]
|
|
31
|
+
def minute
|
|
32
|
+
set_function_and_argument(:minute, nil)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Applies the `second` function.
|
|
36
|
+
# @return [self]
|
|
37
|
+
def second
|
|
38
|
+
set_function_and_argument(:second, nil)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Applies the `fractionalseconds` function.
|
|
42
|
+
# @return [self]
|
|
43
|
+
def fractionalseconds
|
|
44
|
+
set_function_and_argument(:fractionalseconds, nil)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Applies the `date` function.
|
|
48
|
+
# @return [self]
|
|
49
|
+
def date
|
|
50
|
+
set_function_and_argument(:date, nil)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Applies the `time` function.
|
|
54
|
+
# @return [self]
|
|
55
|
+
def time
|
|
56
|
+
set_function_and_argument(:time, nil)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Frodo
|
|
2
|
+
class Query
|
|
3
|
+
class Criteria
|
|
4
|
+
module GeographyFunctions
|
|
5
|
+
# Applies the `geo.distance` function.
|
|
6
|
+
# @param to [to_s]
|
|
7
|
+
# @return [self]
|
|
8
|
+
def distance(to)
|
|
9
|
+
set_function_and_argument(:'geo.distance', to)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Applies the `geo.intersects` function.
|
|
13
|
+
# @param what [to_s]
|
|
14
|
+
# @return [self]
|
|
15
|
+
def intersects(what)
|
|
16
|
+
set_function_and_argument(:'geo.intersects', what)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Frodo
|
|
2
|
+
class Query
|
|
3
|
+
class Criteria
|
|
4
|
+
module LambdaOperators
|
|
5
|
+
# Applies the `any` lambda operator to the given property
|
|
6
|
+
# @param property [to_s]
|
|
7
|
+
# @return [self]
|
|
8
|
+
def any(property)
|
|
9
|
+
set_function_and_argument(:any, property)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Applies the `any` lambda operator to the given property
|
|
13
|
+
# @param property [to_s]
|
|
14
|
+
# @return [self]
|
|
15
|
+
def all(property)
|
|
16
|
+
set_function_and_argument(:all, property)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def lambda_operator?
|
|
22
|
+
[:any, :all].include?(function)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|