safrano 0.5.5 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/core_ext/Date/format.rb +47 -0
  3. data/lib/core_ext/DateTime/format.rb +54 -0
  4. data/lib/core_ext/Dir/iter.rb +7 -5
  5. data/lib/core_ext/Hash/transform.rb +14 -6
  6. data/lib/core_ext/Numeric/convert.rb +1 -1
  7. data/lib/core_ext/Time/format.rb +71 -0
  8. data/lib/core_ext/date.rb +5 -0
  9. data/lib/core_ext/datetime.rb +5 -0
  10. data/lib/core_ext/time.rb +5 -0
  11. data/lib/odata/attribute.rb +8 -6
  12. data/lib/odata/batch.rb +3 -3
  13. data/lib/odata/collection.rb +5 -5
  14. data/lib/odata/collection_filter.rb +3 -1
  15. data/lib/odata/collection_media.rb +4 -27
  16. data/lib/odata/collection_order.rb +1 -1
  17. data/lib/odata/common_logger.rb +5 -27
  18. data/lib/odata/complex_type.rb +19 -21
  19. data/lib/odata/edm/primitive_types.rb +14 -19
  20. data/lib/odata/entity.rb +12 -12
  21. data/lib/odata/error.rb +7 -7
  22. data/lib/odata/expand.rb +2 -2
  23. data/lib/odata/filter/base.rb +10 -1
  24. data/lib/odata/filter/error.rb +2 -2
  25. data/lib/odata/filter/parse.rb +16 -2
  26. data/lib/odata/filter/sequel.rb +31 -4
  27. data/lib/odata/filter/sequel_datetime_adapter.rb +21 -0
  28. data/lib/odata/filter/token.rb +18 -5
  29. data/lib/odata/filter/tree.rb +83 -9
  30. data/lib/odata/function_import.rb +11 -9
  31. data/lib/odata/model_ext.rb +26 -29
  32. data/lib/odata/request/json.rb +171 -0
  33. data/lib/odata/transition.rb +2 -2
  34. data/lib/odata/url_parameters.rb +3 -3
  35. data/lib/odata/walker.rb +1 -1
  36. data/lib/safrano/multipart.rb +1 -3
  37. data/lib/safrano/rack_app.rb +2 -14
  38. data/lib/safrano/rack_builder.rb +0 -15
  39. data/lib/safrano/request.rb +3 -3
  40. data/lib/safrano/response.rb +3 -3
  41. data/lib/safrano/service.rb +13 -5
  42. data/lib/safrano/type_mapping.rb +4 -4
  43. data/lib/safrano/version.rb +1 -2
  44. data/lib/safrano.rb +3 -0
  45. metadata +51 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb412667db93e26340fc21440c89572fbff42fe52ae36807614f0fd11aac808c
4
- data.tar.gz: 90883acded679aa860346e49242b1149933ccdb474e3e39eb6a893da5958dde7
3
+ metadata.gz: 26b1634021c6ab2117b0b2fe4fb8c49242d4a045b6afafec604ef61e26c3bc48
4
+ data.tar.gz: 86adac4fb2ab8ad02d570f373325b7e1c4945941a01e2328fc50ff10c9460abd
5
5
  SHA512:
6
- metadata.gz: f66a01241685f18493d0519cb009674f0764e260ccc79b048ebc7346b5d4c64bd78deeb9983a0b4893e4fcfc2d1361f7024ca212bcbdc8071191417e793d9427
7
- data.tar.gz: 85e2cdd6c5c65e52f882fe2e8386cdf772c239ecdf27d979d473170f51bb1c0a37d8919cb8fc7422bb04eadf50baa8adb1ad4e712ea3952d3e2c0f7d9923bd48
6
+ metadata.gz: c19b30f23c22127742d8c557a23feec6de75a91d20b1b8b0033fb85e4f1549e92de300e17cb3d80564f92ed0dcd81096b5b4aca1a268eba803b6bbd6a4c0a75c
7
+ data.tar.gz: ee3a9d73e9e1d5862cb1a699786e9f81c5a58d7937678b5a138eecae08ccc10e49248f70066ede55e270fb361744978ca4b5b9a75bbd6e62a2c4685e6fc2ae46
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Safrano
4
+ module CoreExt
5
+ module Date
6
+ module Format
7
+ # Date is a DateTime with time 00:00:00 thus the milliseconds are ALWAYS 000
8
+ # excepted when we get Date(0) = Epoch date
9
+ REGEX = /\/Date\((?:(-?\d+)000|0+)\)\//.freeze
10
+ # Input: /Date(86400000)/
11
+ # Match groups
12
+ # 1. 86400
13
+ # Input: /Date(0)/
14
+ # Match groups
15
+ # 1.
16
+
17
+ def from_edm_json(instr)
18
+ return unless (md = instr.match(REGEX))
19
+
20
+ if md[1].nil? # no offset relative to Epoch
21
+ ::Date.new(1970, 1, 1).freeze
22
+ else
23
+ # parse as seconds since epoch
24
+ ::Date.strptime(md[1], '%s')
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ module CoreIncl
31
+ module Date
32
+ module Format
33
+ # https://www.odata.org/documentation/odata-version-2-0/json-format/
34
+ # Edm.DateTime
35
+ # "/Date(<ticks>["+" | "-" <offset>)/"
36
+ # <ticks> = number of milliseconds since midnight Jan 1, 1970
37
+ # <offset> = number of minutes to add or subtract
38
+ # https://stackoverflow.com/questions/10286204/what-is-the-right-json-date-format/10286228#10286228
39
+ def to_edm_json
40
+ # no offset
41
+ # --> %Q milliseconds since epoch
42
+ strftime('/Date(%Q)/')
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Safrano
4
+ module CoreExt
5
+ module DateTime
6
+ module Format
7
+ REGEX = /\/Date\((-?\d+)(?:([-+])(\d+))?\)\//.freeze
8
+ # Input: /Date(120000+150)/
9
+ # Match groups
10
+ # 1. 120000
11
+ # 2. +
12
+ # 3. 150
13
+
14
+ def from_edm_json(instr)
15
+ return unless (md = instr.match(REGEX))
16
+
17
+ if md[3].nil? # no offset
18
+ ::DateTime.strptime(md[1], '%Q')
19
+ else
20
+ # offset in hours / mins
21
+ off_h, off_m = md[3].to_i.divmod(60)
22
+ # DateTime.strptime("120000+2:30", '%Q%z') milliseconds since epoch with a z-offset
23
+ # --> #<DateTime: 1970-01-01T02:32:00+02:30 ((2440588j,120s,0n),+9000s,2299161j)>
24
+ ::DateTime.strptime("#{md[1]}#{md[2]}#{off_h}:#{off_m}", '%Q%z')
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ module CoreIncl
31
+ module DateTime
32
+ module Format
33
+ # https://www.odata.org/documentation/odata-version-2-0/json-format/
34
+ # Edm.DateTime
35
+ # "/Date(<ticks>["+" | "-" <offset>)/"
36
+ # <ticks> = number of milliseconds since midnight Jan 1, 1970
37
+ # <offset> = number of minutes to add or subtract
38
+ # https://stackoverflow.com/questions/10286204/what-is-the-right-json-date-format/10286228#10286228
39
+ def to_edm_json
40
+ if offset.zero?
41
+ # no offset
42
+ # --> %Q milliseconds since epoch
43
+ strftime('/Date(%Q)/')
44
+ else
45
+ # same as above with GMT offset in minutes
46
+ # DateTime offset is Rational ; fraction of hours per Day --> *24*60
47
+ min_off_s = (min_off = (offset * 60 * 24).to_i) > 0 ? "+#{min_off}" : min_off.to_s
48
+ "/Date(#{strftime('%Q')}#{min_off_s})/"
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -5,13 +5,15 @@ module Safrano
5
5
  module CoreExt
6
6
  module Dir
7
7
  module Iter
8
- def each_child(dir)
9
- ::Dir.foreach(dir) do |x|
10
- next if (x == '.') || (x == '..')
8
+ unless ::Dir.respond_to? :each_child
9
+ def each_child(dir)
10
+ ::Dir.foreach(dir) do |x|
11
+ next if (x == '.') || (x == '..')
11
12
 
12
- yield x
13
+ yield x
14
+ end
13
15
  end
14
- end unless ::Dir.respond_to? :each_child
16
+ end
15
17
  end
16
18
  end
17
19
  end
@@ -5,15 +5,23 @@ module Safrano
5
5
  module CoreIncl
6
6
  module Hash
7
7
  module Transform
8
- def transform_keys!
9
- keys.each do |key|
10
- self[yield(key)] = delete(key)
8
+ unless method_defined? :transform_keys!
9
+ def transform_keys!
10
+ keys.each do |key|
11
+ self[yield(key)] = delete(key)
12
+ end
13
+ self
11
14
  end
12
- self
13
- end unless method_defined? :transform_keys!
15
+ end
14
16
 
15
17
  def symbolize_keys!
16
- transform_keys! { |key| key.to_sym rescue key }
18
+ transform_keys! do |key|
19
+ begin
20
+ key.to_sym
21
+ rescue StandardError
22
+ key
23
+ end
24
+ end
17
25
  end
18
26
  end
19
27
  end
@@ -17,7 +17,7 @@ module Safrano
17
17
 
18
18
  def toDecimalPrecisionScaleString(precision, scale)
19
19
  p = Integer(precision)
20
- sprintf("%#{p + 2}.#{scale}f", self).strip
20
+ format("%#{p + 2}.#{scale}f", self).strip
21
21
  end
22
22
  end
23
23
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Safrano
4
+ module CoreExt
5
+ module Time
6
+ module Format
7
+ REGEX = /\/Date\((-?\d+)(?:([-+])(\d+))?\)\//.freeze
8
+ # Input: /Date(120000+150)/
9
+ # Match groups
10
+ # 1. 120000
11
+ # 2. +
12
+ # 3. 150
13
+
14
+ def from_edm_json(instr)
15
+ return unless (md = instr.match(REGEX))
16
+
17
+ sec, milli = md[1].to_i.divmod(1000)
18
+ secm = milli.zero? ? sec : sec + Float(milli) / 1000
19
+ if md[3].nil? # no offset
20
+ # ::Time.at(sec, milli, :millisecond) # not supported in ruby 2.4
21
+ ::Time.gm(1970, 1, 1) + secm
22
+ else
23
+ # offset in hours / mins
24
+ off_h, off_m = md[3].to_i.divmod(60)
25
+ # add leading 0 because Time.at is expecting "+HH:MM", "-HH:MM"
26
+ off_h = off_h < 10 ? "0#{off_h}" : off_h.to_s
27
+ off_m = off_m < 10 ? "0#{off_m}" : off_m.to_s
28
+ # Time.strptime("120000+2:30", '%Q%z') milliseconds since epoch with a z-offset
29
+ # --> #<DateTime: 1970-01-01T02:32:00+02:30 ((2440588j,120s,0n),+9000s,2299161j)>
30
+ # ::Time.at(sec, milli, :millisecond, in: "#{md[2]}#{off_h}:#{off_m}") # not supported in ruby 2.4
31
+ offset_str = "#{md[2]}#{off_h}:#{off_m}"
32
+ ::Time.new(1970, 1, 1, 0, 0, 0, offset_str) + secm + ::Time.zone_offset(offset_str)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ module CoreIncl
40
+ module Time
41
+ module Format
42
+ # Welcome to Hell
43
+ # https://www.odata.org/documentation/odata-version-2-0/json-format/
44
+ # Edm.DateTime
45
+ # "/Date(<ticks>["+" | "-" <offset>)/"
46
+ # <ticks> = number of milliseconds since midnight Jan 1, 1970
47
+ # <offset> = number of minutes to add or subtract
48
+ # https://stackoverflow.com/questions/10286204/what-is-the-right-json-date-format/10286228#10286228
49
+ # also https://www.hanselman.com/blog/on-the-nightmare-that-is-json-dates-plus-jsonnet-and-aspnet-web-api
50
+ # and https://itecnote.com/tecnote/c-use-json-net-to-parse-json-date-of-format-dateepochtime-offset/
51
+ # https://docs.microsoft.com/de-de/dotnet/standard/datetime/system-text-json-support
52
+ # https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/stand-alone-json-serialization#datestimes-and-json
53
+ # https://blogs.sap.com/2017/01/05/date-and-time-in-sap-gateway-foundation/
54
+ def to_edm_json
55
+ if utc? || (gmt_offset == 0)
56
+ # no offset
57
+ # %s : seconds since unix epoch
58
+ # %L : milliseconds 000-999
59
+ # --> %S%L milliseconds since epoch
60
+ strftime('/Date(%s%L)/')
61
+ else
62
+ # same as above with GMT offset in minutes
63
+
64
+ min_off_s = (min_off = gmt_offset / 60) > 0 ? "+#{min_off}" : min_off.to_s
65
+ "/Date(#{strftime('%s%L')}#{min_off_s})/"
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,5 @@
1
+ require_relative 'Date/format'
2
+ require 'date'
3
+
4
+ Date.include Safrano::CoreIncl::Date::Format
5
+ Date.extend Safrano::CoreExt::Date::Format
@@ -0,0 +1,5 @@
1
+ require_relative 'DateTime/format'
2
+ require 'date'
3
+
4
+ DateTime.include Safrano::CoreIncl::DateTime::Format
5
+ DateTime.extend Safrano::CoreExt::DateTime::Format
@@ -0,0 +1,5 @@
1
+ require_relative 'Time/format'
2
+ require 'time'
3
+
4
+ Time.include Safrano::CoreIncl::Time::Format
5
+ Time.extend Safrano::CoreExt::Time::Format
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
- require_relative '../safrano/core.rb'
5
- require_relative './entity.rb'
4
+ require_relative '../safrano/core'
5
+ require_relative './entity'
6
6
 
7
7
  module Safrano
8
8
  # Represents a named and valued attribute of an Entity
@@ -18,12 +18,14 @@ module Safrano
18
18
  def value
19
19
  # WARNING ... this require more work to handle the timezones topci
20
20
  # currently it is just set to make some minimal testcase work
21
+ # See also model_ext.rb
21
22
  case (v = @entity.values[@name.to_sym])
23
+ when Date
24
+ v.to_edm_json
22
25
  when Time
23
- # try to get back the database time zone and value
24
- # (v + v.gmt_offset).utc.to_datetime
25
- v.iso8601
26
-
26
+ v.to_edm_json
27
+ when DateTime
28
+ v.to_edm_json
27
29
  else
28
30
  v
29
31
  end
data/lib/odata/batch.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../safrano/rack_app.rb'
4
- require_relative '../safrano/core.rb'
3
+ require_relative '../safrano/rack_app'
4
+ require_relative '../safrano/core'
5
5
  require 'rack/body_proxy'
6
- require_relative './common_logger.rb'
6
+ require_relative './common_logger'
7
7
 
8
8
  module Safrano
9
9
  # Support for OData multipart $batch Requests
@@ -134,14 +134,14 @@ module Safrano
134
134
 
135
135
  # on model class level we return the collection
136
136
  def odata_get(req)
137
- @params = @params || req.params
137
+ @params ||= req.params
138
138
  initialize_dataset
139
139
  initialize_uparms
140
- @uparms.check_all.if_valid { |_ret|
141
- odata_get_apply_params.if_valid { |_ret|
140
+ @uparms.check_all.if_valid do |_ret|
141
+ odata_get_apply_params.if_valid do |_ret|
142
142
  odata_get_output(req)
143
- }
144
- }.tap_error { |e| return e.odata_get(req) }.result
143
+ end
144
+ end.tap_error { |e| return e.odata_get(req) }.result
145
145
  end
146
146
 
147
147
  def odata_post(req)
@@ -20,7 +20,9 @@ module Safrano
20
20
  end
21
21
 
22
22
  # finalize
23
- def finalize(_jh) Contract::OK end
23
+ def finalize(_jh)
24
+ Contract::OK
25
+ end
24
26
 
25
27
  def empty?
26
28
  true
@@ -143,8 +143,8 @@ module Safrano
143
143
  # with directory Tree structure
144
144
 
145
145
  class StaticTree < Static
146
- SEP = '/00/'.freeze
147
- VERS = '/v'.freeze
146
+ SEP = '/00/'
147
+ VERS = '/v'
148
148
 
149
149
  def self.path_builder(ids)
150
150
  ids.map { |id| id.to_s.chars.join('/') }.join(SEP) << VERS
@@ -276,7 +276,7 @@ module Safrano
276
276
 
277
277
  media_handler.check_before_create(data: data,
278
278
  entity: new_entity,
279
- filename: filename).if_valid { |_ret|
279
+ filename: filename).if_valid do |_ret|
280
280
  # to_one rels are create with FK data set on the parent entity
281
281
  if parent
282
282
  odata_create_save_entity_and_rel(req, new_entity, assoc, parent)
@@ -302,7 +302,7 @@ module Safrano
302
302
  # Contract.valid([201, EMPTY_HASH, new_entity.to_odata_post_json(service: req.service)])
303
303
  # TODO quirks array mode !
304
304
  Contract.valid([201, EMPTY_HASH, new_entity.to_odata_create_json(request: req)])
305
- }.tap_error { |e| return e.odata_get(req) }.result
305
+ end.tap_error { |e| return e.odata_get(req) }.result
306
306
 
307
307
  else # TODO: other formats
308
308
  415
@@ -311,26 +311,3 @@ module Safrano
311
311
  end
312
312
  end
313
313
  end
314
-
315
- # deprecated
316
- # REMOVE 0.6
317
- module OData
318
- module Media
319
- class Static < ::Safrano::Media::Static
320
- def initialize(root: nil, mediaklass:)
321
- ::Safrano::Deprecation.deprecate('OData::Media::Static',
322
- 'Use Safrano::Media::Static instead')
323
-
324
- super
325
- end
326
- end
327
- class StaticTree < ::Safrano::Media::StaticTree
328
- def initialize(root: nil, mediaklass:)
329
- ::Safrano::Deprecation.deprecate('OData::Media::StaticTree',
330
- 'Use Safrano::Media::StaticTree instead')
331
-
332
- super
333
- end
334
- end
335
- end
336
- end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'odata/error.rb'
3
+ require 'odata/error'
4
4
 
5
5
  # all ordering related classes in our OData module
6
6
  module Safrano
@@ -10,36 +10,14 @@ module Rack
10
10
  # Handle https://github.com/rack/rack/pull/1526
11
11
  # new in Rack 2.2.2 : Format has now 11 placeholders instead of 10
12
12
 
13
- MSG_FUNC = if FORMAT.count('%') == 10
13
+ MSG_FUNC = case FORMAT.count('%')
14
+ when 10
14
15
  lambda { |env, length, status, began_at|
15
- FORMAT % [
16
- env['HTTP_X_FORWARDED_FOR'] || env['REMOTE_ADDR'] || '-',
17
- env['REMOTE_USER'] || '-',
18
- Time.now.strftime('%d/%b/%Y:%H:%M:%S %z'),
19
- env[REQUEST_METHOD],
20
- env[SCRIPT_NAME] + env[PATH_INFO],
21
- env[QUERY_STRING].empty? ? '' : "?#{env[QUERY_STRING]}",
22
- env[SERVER_PROTOCOL],
23
- status.to_s[0..3],
24
- length,
25
- Utils.clock_time - began_at
26
- ]
16
+ format(FORMAT, env['HTTP_X_FORWARDED_FOR'] || env['REMOTE_ADDR'] || '-', env['REMOTE_USER'] || '-', Time.now.strftime('%d/%b/%Y:%H:%M:%S %z'), env[REQUEST_METHOD], env[SCRIPT_NAME] + env[PATH_INFO], env[QUERY_STRING].empty? ? '' : "?#{env[QUERY_STRING]}", env[SERVER_PROTOCOL], status.to_s[0..3], length, Utils.clock_time - began_at)
27
17
  }
28
- elsif FORMAT.count('%') == 11
18
+ when 11
29
19
  lambda { |env, length, status, began_at|
30
- FORMAT % [
31
- env['HTTP_X_FORWARDED_FOR'] || env['REMOTE_ADDR'] || '-',
32
- env['REMOTE_USER'] || '-',
33
- Time.now.strftime('%d/%b/%Y:%H:%M:%S %z'),
34
- env[REQUEST_METHOD],
35
- env[SCRIPT_NAME],
36
- env[PATH_INFO],
37
- env[QUERY_STRING].empty? ? '' : "?#{env[QUERY_STRING]}",
38
- env[SERVER_PROTOCOL],
39
- status.to_s[0..3],
40
- length,
41
- Utils.clock_time - began_at
42
- ]
20
+ format(FORMAT, env['HTTP_X_FORWARDED_FOR'] || env['REMOTE_ADDR'] || '-', env['REMOTE_USER'] || '-', Time.now.strftime('%d/%b/%Y:%H:%M:%S %z'), env[REQUEST_METHOD], env[SCRIPT_NAME], env[PATH_INFO], env[QUERY_STRING].empty? ? '' : "?#{env[QUERY_STRING]}", env[SERVER_PROTOCOL], status.to_s[0..3], length, Utils.clock_time - began_at)
43
21
  }
44
22
  end
45
23
 
@@ -22,8 +22,8 @@ module Safrano
22
22
  end
23
23
 
24
24
  # we will have this on class and instance level for making things simpler first
25
- def self.klassmod
26
- @klassmod
25
+ class << self
26
+ attr_reader :klassmod
27
27
  end
28
28
 
29
29
  # return a subclass of ResultAsComplexType
@@ -88,8 +88,8 @@ module Safrano
88
88
  # wrapper
89
89
  # for OData Entity and Collections, return them directly
90
90
  # for others, ie ComplexType, Prims etc, return the ResultDefinition-subclass wrapped result
91
- def self.do_execute_func_result(result, _req, apply_query_params = false)
92
- self.new(result)
91
+ def self.do_execute_func_result(result, _req, _apply_query_params = false)
92
+ new(result)
93
93
  end
94
94
  end
95
95
 
@@ -186,12 +186,12 @@ module Safrano
186
186
  EMPTYH = {}.freeze
187
187
 
188
188
  @namespace = nil
189
- def self.namespace
190
- @namespace
189
+ class << self
190
+ attr_reader :namespace
191
191
  end
192
192
 
193
- def self.props
194
- @props
193
+ class << self
194
+ attr_reader :props
195
195
  end
196
196
 
197
197
  def type_name
@@ -214,11 +214,9 @@ module Safrano
214
214
  expand_e = {}
215
215
 
216
216
  template[:all_values] = EMPTYH
217
- @props.each { |prop, kl|
218
- if kl.respond_to? :default_template
219
- expand_e[prop] = kl.default_template
220
- end
221
- }
217
+ @props.each do |prop, kl|
218
+ expand_e[prop] = kl.default_template if kl.respond_to? :default_template
219
+ end
222
220
  template[:expand_e] = expand_e
223
221
  template
224
222
  end
@@ -228,7 +226,7 @@ module Safrano
228
226
  end
229
227
 
230
228
  def self.type_name
231
- @namespace ? "#{@namespace}.#{self.to_s}" : self.to_s
229
+ @namespace ? "#{@namespace}.#{self}" : to_s
232
230
  end
233
231
 
234
232
  def initialize
@@ -240,13 +238,13 @@ module Safrano
240
238
  def odata_h
241
239
  ret = { METAK => { TYPEK => self.class.type_name } }
242
240
 
243
- @values.each { |k, v|
241
+ @values.each do |k, v|
244
242
  ret[k] = if v.respond_to? :odata_h
245
243
  v.odata_h
246
244
  else
247
245
  v
248
246
  end
249
- }
247
+ end
250
248
  ret
251
249
  end
252
250
 
@@ -272,14 +270,14 @@ module Safrano
272
270
  end
273
271
  end
274
272
 
275
- def Safrano.ComplexType(**props)
273
+ def self.ComplexType(**props)
276
274
  Class.new(Safrano::ComplexType) do
277
275
  @props = props
278
- props.each { |a, klassmod|
276
+ props.each do |a, _klassmod|
279
277
  asym = a.to_sym
280
- define_method(asym) do @values[asym] end
281
- define_method("#{a}=") do |val| @values[asym] = val end
282
- }
278
+ define_method(asym) { @values[asym] }
279
+ define_method("#{a}=") { |val| @values[asym] = val }
280
+ end
283
281
  define_method :initialize do |*p, **kwvals|
284
282
  super()
285
283
  p.zip(props.keys).each { |val, a| @values[a] = val } if p
@@ -42,8 +42,8 @@ module Safrano
42
42
  metadata[:edm_type] = if (md = DB_TYPE_NUMDEC_RGX.match(props[:db_type]))
43
43
  prec = md[4]
44
44
  scale = md[6]
45
- if (scale && prec)
46
- if (scale == '0') # dont force default scale to 0 like SQL standard
45
+ if scale && prec
46
+ if scale == '0' # dont force default scale to 0 like SQL standard
47
47
  metadata[:edm_precision] = prec
48
48
  "Edm.Decimal(#{prec})"
49
49
  else
@@ -116,7 +116,6 @@ module Safrano
116
116
  'Edm.Decimal'
117
117
  when :blob
118
118
  'Edm.Binary'
119
- else
120
119
  end
121
120
  end
122
121
 
@@ -142,12 +141,12 @@ module Safrano
142
141
  class Null < NilClass
143
142
  extend OutputClassMethods
144
143
  # nil --> null convertion is done by to_json
145
- def self.odata_value(instance)
144
+ def self.odata_value(_instance)
146
145
  nil
147
146
  end
148
147
 
149
148
  def self.convert_from_urlparam(v)
150
- return Contract::NOK unless (v == 'null')
149
+ return Contract::NOK unless v == 'null'
151
150
 
152
151
  Contract.valid(nil)
153
152
  end
@@ -167,7 +166,7 @@ module Safrano
167
166
  # or false([nil, false])
168
167
  class Boolean < Object
169
168
  extend OutputClassMethods
170
- def Boolean.odata_value(instance)
169
+ def self.odata_value(instance)
171
170
  instance ? true : false
172
171
  end
173
172
 
@@ -176,7 +175,7 @@ module Safrano
176
175
  end
177
176
 
178
177
  def self.convert_from_urlparam(v)
179
- return Contract::NOK unless ['true', 'false'].include?(v)
178
+ return Contract::NOK unless %w[true false].include?(v)
180
179
 
181
180
  Contract.valid(v == 'true')
182
181
  end
@@ -188,7 +187,7 @@ module Safrano
188
187
  extend OutputClassMethods
189
188
 
190
189
  def self.convert_from_urlparam(v)
191
- return Contract::NOK unless ((bytev = v.to_i) < 256)
190
+ return Contract::NOK unless (bytev = v.to_i) < 256
192
191
 
193
192
  Contract.valid(bytev)
194
193
  end
@@ -196,7 +195,7 @@ module Safrano
196
195
 
197
196
  class DateTime < ::DateTime
198
197
  extend OutputClassMethods
199
- def DateTime.odata_value(instance)
198
+ def self.odata_value(instance)
200
199
  instance.to_datetime
201
200
  end
202
201
 
@@ -205,11 +204,9 @@ module Safrano
205
204
  end
206
205
 
207
206
  def self.convert_from_urlparam(v)
208
- begin
209
- Contract.valid(DateTime.parse(v))
210
- rescue
211
- return convertion_error(v)
212
- end
207
+ Contract.valid(DateTime.parse(v))
208
+ rescue StandardError
209
+ convertion_error(v)
213
210
  end
214
211
  end
215
212
 
@@ -245,11 +242,9 @@ module Safrano
245
242
  extend OutputClassMethods
246
243
 
247
244
  def self.convert_from_urlparam(v)
248
- begin
249
- Contract.valid(v.to_f)
250
- rescue
251
- return Contract::NOK
252
- end
245
+ Contract.valid(v.to_f)
246
+ rescue StandardError
247
+ Contract::NOK
253
248
  end
254
249
  end
255
250
  end