safrano 0.5.5 → 0.6.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.
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