safrano 0.4.4 → 0.4.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88f62ce611a5030382ea19c2e7c22b47f454b85c51261e5bad060d82e4680dff
4
- data.tar.gz: '088e66ed4a107a3bef8dd6db68c8ca626f7d3acef6ed2e58eb53d871e6349613'
3
+ metadata.gz: 9f2ebcbe8cf374526aa263f93515e2424753898ad878904d6d5d087bc6317c4e
4
+ data.tar.gz: 48190a71451991630bd48347c3cf2acb701423bb58266fa736b0cf7a5b6f3bdf
5
5
  SHA512:
6
- metadata.gz: 2d719e317178a4baebc2e40cc50b95559921fe2936a6a03437f7f92714d173ef6160b10620ce5476ea54a7433b3dd1366b49ec37a48b121b8f808ad030e2c364
7
- data.tar.gz: 535ee0f1d4fed30a0c94918c31149a2e95fce90051548a2ccca6bffb71930c0767543255695496c3623249070b5efb1b6a203a1dae6f868c1e4da9a126a85346
6
+ metadata.gz: 70ef7d275b566269879e4cd37f019958cd354504d1dede907adcf4d078e47361412997c69eec2c403317013ef5ac8019315aeb8cc89715906f2f12bd59e885dc
7
+ data.tar.gz: 1ff899294284a5e9531187533938e14ae304c1344131177dff1612037ca32e6a27dfcd72b367dd705afbb5cd5b9d38e9c11dc7b8f7766d470c2ac4c45686372b
@@ -53,7 +53,7 @@ module Safrano
53
53
  # methods related to transitions to next state (cf. walker)
54
54
  module Transitions
55
55
  def transition_end(_match_result)
56
- [nil, :end]
56
+ Transition::RESULT_END
57
57
  end
58
58
 
59
59
  def transition_value(_match_result)
@@ -64,7 +64,7 @@ module Safrano
64
64
  Safrano::TransitionValue].freeze
65
65
 
66
66
  def allowed_transitions
67
- ALLOWED_TRANSITIONS
67
+ Transitions::ALLOWED_TRANSITIONS
68
68
  end
69
69
  end
70
70
  include Transitions
@@ -77,17 +77,20 @@ module Safrano
77
77
  end
78
78
  end
79
79
 
80
- D = 'd'.freeze
81
- DJ_OPEN = '{"d":'.freeze
82
- DJ_CLOSE = '}'.freeze
80
+ D = 'd'
81
+ DJ_OPEN = '{"d":'
82
+ DJ_CLOSE = '}'
83
83
  EMPTYH = {}.freeze
84
84
 
85
85
  def to_odata_json(request:)
86
86
  template = @modelk.output_template(expand_list: @uparms.expand.template,
87
87
  select: @uparms.select)
88
+ # TODO: Error handling if database contains binary BLOB data that cant be
89
+ # interpreted as UTF-8 then JSON will fail here
88
90
  innerj = request.service.get_coll_odata_h(array: @cx.all,
89
91
  template: template,
90
92
  icount: @inlinecount).to_json
93
+
91
94
  "#{DJ_OPEN}#{innerj}#{DJ_CLOSE}"
92
95
  end
93
96
 
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'odata/error.rb'
3
+ require 'odata/error'
4
4
 
5
- require_relative 'filter/parse.rb'
6
- require_relative 'filter/sequel.rb'
5
+ require_relative 'filter/parse'
6
+ require_relative 'filter/sequel'
7
7
 
8
8
  # filter base class and subclass in our OData namespace
9
9
  module Safrano
@@ -45,12 +45,12 @@ module Safrano
45
45
  # the join-helper is shared by the order-by object and was potentially already
46
46
  # partly built on order-by object creation.
47
47
  def finalize(jh)
48
- @filtexpr = @ast.if_valid do |ast| ast.sequel_expr(jh) end
48
+ @filtexpr = @ast.if_valid { |ast| ast.sequel_expr(jh) }
49
49
  end
50
50
 
51
51
  def apply_to_dataset(dtcx)
52
52
  # normally finalize is called before, and thus @filtexpr is set
53
- @filtexpr.map_result! do |f| dtcx.where(f) end
53
+ @filtexpr.map_result! { |f| dtcx.where(f) }
54
54
  end
55
55
 
56
56
  # Note: this is really only *parse* error, ie the error encounterd while
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'rack'
4
4
  require 'fileutils'
5
- require_relative './navigation_attribute.rb'
5
+ require_relative './navigation_attribute'
6
6
 
7
7
  module Safrano
8
8
  module Media
@@ -24,9 +24,16 @@ module Safrano
24
24
 
25
25
  def register
26
26
  @abs_klass_dir = File.absolute_path(@media_dir_name, @root)
27
+ end
28
+
29
+ def create_abs_class_dir
27
30
  FileUtils.makedirs @abs_klass_dir unless Dir.exist?(@abs_klass_dir)
28
31
  end
29
32
 
33
+ def finalize
34
+ create_abs_class_dir
35
+ end
36
+
30
37
  # minimal working implementation...
31
38
  # Note: @file_server works relative to @root directory
32
39
  def odata_get(request:, entity:)
@@ -53,7 +60,7 @@ module Safrano
53
60
  # simple design: one file per directory, and the directory
54
61
  # contains the media entity-id --> implicit link between the media
55
62
  # entity
56
- File.join(media_path(entity), Dir.glob('*').sort.first)
63
+ File.join(media_path(entity), Dir.glob('*').min)
57
64
  end
58
65
  end
59
66
 
@@ -62,6 +69,11 @@ module Safrano
62
69
  File.absolute_path(media_path(entity), @root)
63
70
  end
64
71
 
72
+ # absolute filename
73
+ def abs_filename(entity)
74
+ File.absolute_path(filename(entity), @root)
75
+ end
76
+
65
77
  # this is relative to abs_klass_dir(entity) eg to /@root/Photo
66
78
  # simplest implementation is media_directory = entity.media_path_id
67
79
  # --> we get a 1 level depth flat directory structure
@@ -101,7 +113,7 @@ module Safrano
101
113
  def ressource_version(entity)
102
114
  Dir.chdir(@abs_klass_dir) do
103
115
  in_media_directory(entity) do
104
- Dir.glob('*').sort.last
116
+ Dir.glob('*').max
105
117
  end
106
118
  end
107
119
  end
@@ -201,9 +213,14 @@ module Safrano
201
213
  @media_handler = Safrano::Media::Static.new(mediaklass: self)
202
214
  end
203
215
 
216
+ def finalize_media
217
+ @media_handler.finalize
218
+ end
219
+
204
220
  def use(klass, args)
205
221
  args[:mediaklass] = self
206
222
  @media_handler = klass.new(**args)
223
+ @media_handler.create_abs_class_dir
207
224
  end
208
225
 
209
226
  # API method for setting the model field mapped to SLUG on upload
@@ -261,9 +278,16 @@ module Safrano
261
278
  req.register_content_id_ref(new_entity)
262
279
  new_entity.copy_request_infos(req)
263
280
 
281
+ # call before_create_media hook
282
+ new_entity.before_create_media if new_entity.respond_to? :before_create_media
283
+
264
284
  media_handler.save_file(data: data,
265
285
  entity: new_entity,
266
286
  filename: filename)
287
+
288
+ # call after_create_media hook
289
+ new_entity.after_create_media if new_entity.respond_to? :after_create_media
290
+
267
291
  # json is default content type so we dont need to specify it here again
268
292
  [201, EMPTY_HASH, new_entity.to_odata_post_json(service: req.service)]
269
293
  else # TODO: other formats
@@ -3,14 +3,14 @@
3
3
  module Safrano
4
4
  module FunctionImport
5
5
  class ResultDefinition
6
- D = 'd'.freeze
7
- DJ_OPEN = '{"d":'.freeze
8
- DJ_CLOSE = '}'.freeze
9
- METAK = '__metadata'.freeze
10
- TYPEK = 'type'.freeze
11
- VALUEK = 'value'.freeze
12
- RESULTSK = 'results'.freeze
13
- COLLECTION = 'Collection'.freeze
6
+ D = 'd'
7
+ DJ_OPEN = '{"d":'
8
+ DJ_CLOSE = '}'
9
+ METAK = '__metadata'
10
+ TYPEK = 'type'
11
+ VALUEK = 'value'
12
+ RESULTSK = 'results'
13
+ COLLECTION = 'Collection'
14
14
 
15
15
  def initialize(klassmod)
16
16
  @klassmod = klassmod
@@ -97,8 +97,8 @@ module Safrano
97
97
  def initialize
98
98
  @values = {}
99
99
  end
100
- METAK = '__metadata'.freeze
101
- TYPEK = 'type'.freeze
100
+ METAK = '__metadata'
101
+ TYPEK = 'type'
102
102
 
103
103
  def odata_h
104
104
  ret = { METAK => { TYPEK => self.class.type_name } }
@@ -37,6 +37,15 @@ module Safrano
37
37
  super(msg, symbname)
38
38
  end
39
39
  end
40
+
41
+ # duplicate attribute name
42
+ class ModelDuplicateAttributeError < NameError
43
+ def initialize(klass, symb)
44
+ symbname = symb.to_s
45
+ msg = "There is already an attribute :#{symbname} defined in class #{klass}"
46
+ super(msg, symbname)
47
+ end
48
+ end
40
49
  end
41
50
 
42
51
  # base module for HTTP errors, when used as a Error Class
@@ -57,6 +57,11 @@ module Safrano
57
57
  class Literal < Leave
58
58
  end
59
59
 
60
+ # Null Literal is unquoted null word
61
+ class NullLiteral < Literal
62
+ LEUQES = nil
63
+ end
64
+
60
65
  # Qualit (qualified lits) are words separated by /
61
66
  # path/path/path/attrib
62
67
  class Qualit < Literal
@@ -151,6 +151,12 @@ module Safrano
151
151
  grow_at_cursor(Literal.new(tok))
152
152
  end
153
153
 
154
+ when :NullLiteral
155
+ with_accepted(tok, typ) do
156
+ @cursor.update_state(tok, typ)
157
+ grow_at_cursor(NullLiteral.new(tok))
158
+ end
159
+
154
160
  when :Qualit
155
161
  with_accepted(tok, typ) do
156
162
  @cursor.update_state(tok, typ)
@@ -183,6 +183,13 @@ module Safrano
183
183
  end
184
184
  Contract.collect_result!(@children[0].leuqes(jh),
185
185
  @children[1].leuqes(jh)) do |c0, c1|
186
+ if c1 == NullLiteral::LEUQES
187
+ if @value == :eq
188
+ leuqes_op = :IS
189
+ elsif @value == :ne
190
+ leuqes_op = :'IS NOT'
191
+ end
192
+ end
186
193
  Sequel::SQL::BooleanExpression.new(leuqes_op, c0, c1)
187
194
  end
188
195
  end
@@ -262,6 +269,14 @@ module Safrano
262
269
  end
263
270
  end
264
271
 
272
+ # Null
273
+ class NullLiteral
274
+ def leuqes(jh)
275
+ # Sequel's representation of NULL
276
+ success LEUQES
277
+ end
278
+ end
279
+
265
280
  # Qualit (qualified lits) are words separated by /
266
281
  class Qualit
267
282
  def leuqes(jh)
@@ -10,13 +10,14 @@ module Safrano
10
10
  day hour minute month second year
11
11
  round floor ceiling].freeze
12
12
  FUNCRGX = FUNCNAMES.join('|')
13
+ NULLRGX = 'null|NULL|Null'
13
14
  QSTRINGRGX = /'((?:[^']|(?:'{2}))*)'/.freeze
14
15
  BINOBOOL = '[eE][qQ]|[LlgGNn][eETt]|[aA][nN][dD]|[oO][rR]'
15
16
  BINOARITHM = '[aA][dD][dD]|[sS][uU][bB]|[mM][uU][lL]|[dD][iI][vV]|[mM][oO][dD]'
16
- NOTRGX = 'not|NOT'
17
+ NOTRGX = 'not|NOT|Not'
17
18
  FPRGX = '\d+(?:\.\d+)?(?:e[+-]?\d+)?'
18
19
  QUALITRGX = '\w+(?:\/\w+)+'
19
- RGX = /(#{FUNCRGX})|([\(\),])|(#{BINOBOOL})\s+|(#{BINOARITHM})|(#{NOTRGX})|#{QSTRINGRGX}|(#{FPRGX})|(#{QUALITRGX})|(\w+)|(')/.freeze
20
+ RGX = /(#{FUNCRGX})|(#{NULLRGX})|([\(\),])|(#{BINOBOOL})\s+|(#{BINOARITHM})|(#{NOTRGX})|#{QSTRINGRGX}|(#{FPRGX})|(#{QUALITRGX})|(\w+)|(')/.freeze
20
21
 
21
22
  def each_typed_token(inp)
22
23
  typ = nil
@@ -34,27 +35,29 @@ module Safrano
34
35
  when 0
35
36
  :FuncTree
36
37
  when 1
38
+ :NullLiteral
39
+ when 2
37
40
  case found
38
41
  when '(', ')'
39
42
  :Delimiter
40
43
  when ','
41
44
  :Separator
42
45
  end
43
- when 2
44
- :BinopBool
45
46
  when 3
46
- :BinopArithm
47
+ :BinopBool
47
48
  when 4
48
- :UnopTree
49
+ :BinopArithm
49
50
  when 5
50
- :QString
51
+ :UnopTree
51
52
  when 6
52
- :FPNumber
53
+ :QString
53
54
  when 7
54
- :Qualit
55
+ :FPNumber
55
56
  when 8
56
- :Literal
57
+ :Qualit
57
58
  when 9
59
+ :Literal
60
+ when 10
58
61
  :unmatchedQuote
59
62
  end
60
63
  yield found, typ
@@ -65,7 +65,7 @@ module Safrano
65
65
  # nil is considered as accepted, otherwise non-nil=the error
66
66
  def accept?(tok, typ)
67
67
  case typ
68
- when :Literal, :Qualit, :QString, :FuncTree, :ArgTree,
68
+ when :Literal, :NullLiteral, :Qualit, :QString, :FuncTree, :ArgTree,
69
69
  :UnopTree, :FPNumber
70
70
  nil
71
71
  when :Delimiter
@@ -232,7 +232,7 @@ module Safrano
232
232
 
233
233
  def update_state(_tok, typ)
234
234
  case typ
235
- when :Literal, :Qualit, :QString, :FuncTree, :BinopBool, :BinopArithm, :UnopTree, :FPNumber
235
+ when :Literal, :NullLiteral, :Qualit, :QString, :FuncTree, :BinopBool, :BinopArithm, :UnopTree, :FPNumber
236
236
  @state = :closed
237
237
  end
238
238
  end
@@ -297,7 +297,7 @@ module Safrano
297
297
  @state = :closed
298
298
  when :Separator
299
299
  @state = :sep
300
- when :Literal, :Qualit, :QString, :FuncTree, :FPNumber
300
+ when :Literal, :NullLiteral, :Qualit, :QString, :FuncTree, :FPNumber
301
301
  @state = :val
302
302
  end
303
303
  end
@@ -327,7 +327,7 @@ module Safrano
327
327
  elsif @state == :sep
328
328
  Parser::ErrorInvalidToken.new(tok, typ, self)
329
329
  end
330
- when :Literal, :Qualit, :QString, :FuncTree, :FPNumber
330
+ when :Literal, :NullLiteral, :Qualit, :QString, :FuncTree, :FPNumber
331
331
  if (@state == :open) || (@state == :sep)
332
332
  if @parent.arity_full?(@children.size)
333
333
  Parser::ErrorInvalidArity.new(tok, typ, self)
@@ -2,8 +2,10 @@
2
2
 
3
3
  require_relative 'complex_type'
4
4
  require_relative 'edm/primitive_types'
5
+ require_relative 'transition'
6
+
5
7
  module Safrano
6
- def Safrano.FunctionImport(name)
8
+ def self.FunctionImport(name)
7
9
  FunctionImport::Function.new(name)
8
10
  end
9
11
 
@@ -24,7 +26,7 @@ module Safrano
24
26
 
25
27
  def input(**parmtypes)
26
28
  @input = {}
27
- parmtypes.each { |k, t|
29
+ parmtypes.each do |k, t|
28
30
  @input[k] = case t.name
29
31
  when 'Integer'
30
32
  Safrano::Edm::Edm::Int32
@@ -37,7 +39,7 @@ module Safrano
37
39
  else
38
40
  t
39
41
  end
40
- }
42
+ end
41
43
  self
42
44
  end
43
45
 
@@ -91,20 +93,20 @@ module Safrano
91
93
  return nil unless @input # anything to check ?
92
94
 
93
95
  # do we have all parameters provided ?
94
- check_missing_params.tap_error do |error| return error end
96
+ check_missing_params.tap_error { |error| return error }
95
97
  # ==> all params were provided
96
98
 
97
99
  # now we shall check the content and type of the parameters
98
- @input.each { |ksym, typ|
100
+ @input.each do |ksym, typ|
99
101
  typ.convert_from_urlparam(v = @params[ksym.to_s])
100
102
  .tap_valid do |retval|
101
103
  @funcparams[ksym] = retval
102
104
  end
103
- .tap_error do |error|
105
+ .tap_error do
104
106
  # return is really needed here, or we end up returning nil below
105
107
  return parameter_convertion_error(ksym, typ, v)
106
108
  end
107
- }
109
+ end
108
110
  nil
109
111
  end
110
112
 
@@ -125,12 +127,12 @@ module Safrano
125
127
  # EntitySet= @entity_set ,
126
128
  'ReturnType' => @returning.type_metadata,
127
129
  'm:HttpMethod' => @http_method)
128
- @input.each { |iname, type|
130
+ @input.each do |iname, type|
129
131
  funky.add_element('Parameter',
130
132
  'Name' => iname.to_s,
131
133
  'Type' => type.type_name,
132
134
  'Mode' => 'In')
133
- } if @input
135
+ end if @input
134
136
  funky
135
137
  end
136
138
 
@@ -159,7 +161,7 @@ module Safrano
159
161
  end
160
162
 
161
163
  def transition_end(_match_result)
162
- [nil, :end]
164
+ Transition::RESULT_END
163
165
  end
164
166
  end
165
167
  end
@@ -299,6 +299,14 @@ module Safrano
299
299
 
300
300
  attr_class = assoc[:class_name].constantize
301
301
  lattr_name_str = (attr_name_str || assoc_symb.to_s)
302
+
303
+ # check duplicate attributes names
304
+ raise Safrano::API::ModelDuplicateAttributeError.new(self, lattr_name_str) if @columns.include? lattr_name_str.to_sym
305
+
306
+ if @nav_entity_attribs_keys
307
+ raise Safrano::API::ModelDuplicateAttributeError.new(self, lattr_name_str) if @nav_entity_attribs_keys.include? lattr_name_str
308
+ end
309
+
302
310
  @nav_collection_attribs[lattr_name_str] = attr_class
303
311
  @nav_collection_attribs_keys << lattr_name_str
304
312
  @nav_collection_url_regexp = @nav_collection_attribs_keys.join('|')
@@ -317,6 +325,14 @@ module Safrano
317
325
 
318
326
  attr_class = assoc[:class_name].constantize
319
327
  lattr_name_str = (attr_name_str || assoc_symb.to_s)
328
+
329
+ # check duplicate attributes names
330
+ raise Safrano::API::ModelDuplicateAttributeError.new(self, lattr_name_str) if @columns.include? lattr_name_str.to_sym
331
+
332
+ if @nav_collection_attribs_keys
333
+ raise Safrano::API::ModelDuplicateAttributeError.new(self, lattr_name_str) if @nav_collection_attribs_keys.include? lattr_name_str
334
+ end
335
+
320
336
  @nav_entity_attribs[lattr_name_str] = attr_class
321
337
  @nav_entity_attribs_keys << lattr_name_str
322
338
  @nav_entity_url_regexp = @nav_entity_attribs_keys.join('|')
@@ -352,6 +368,9 @@ module Safrano
352
368
 
353
369
  build_allowed_transitions
354
370
  build_entity_allowed_transitions
371
+
372
+ # for media
373
+ finalize_media if self.respond_to? :finalize_media
355
374
  end
356
375
 
357
376
  KEYPRED_URL_REGEXP = /\A\(\s*'?([\w=,'\s]+)'?\s*\)(.*)/.freeze
@@ -30,9 +30,9 @@ module Safrano
30
30
  # are $links requested ?
31
31
  attr_reader :do_links
32
32
 
33
- NIL_SERVICE_FATAL = 'Walker is called with a nil service'.freeze
34
- EMPTYSTR = ''.freeze
35
- SLASH = '/'.freeze
33
+ NIL_SERVICE_FATAL = 'Walker is called with a nil service'
34
+ EMPTYSTR = ''
35
+ SLASH = '/'
36
36
 
37
37
  def initialize(service, path, content_id_refs = nil)
38
38
  raise NIL_SERVICE_FATAL unless service
@@ -106,11 +106,11 @@ module Safrano
106
106
  end
107
107
  end # class Valid
108
108
 
109
- def Contract.valid(result)
109
+ def self.valid(result)
110
110
  Contract::Valid.new(result)
111
111
  end
112
112
 
113
- def Contract.and(*contracts)
113
+ def self.and(*contracts)
114
114
  # pick the first error if any
115
115
  if (ff = contracts.find(&:error))
116
116
  return ff
@@ -118,18 +118,18 @@ module Safrano
118
118
 
119
119
  # return a new one with @result = list of the contracts's results
120
120
  # usually this then be reduced again with #collect_result! or # #if_valid_collect methods
121
- Contract.valid(contracts.map(&:result))
121
+ valid(contracts.map(&:result))
122
122
  end
123
123
 
124
124
  # shortcut for Contract.and(*contracts).collect_result!
125
- def Contract.collect_result!(*contracts)
125
+ def self.collect_result!(*contracts)
126
126
  # pick the first error if any
127
127
  if (ff = contracts.find(&:error))
128
128
  return ff
129
129
  end
130
130
 
131
131
  # return a new one with @result = yield(*list of the contracts's results)
132
- Contract.valid(yield(*contracts.map(&:result)))
132
+ valid(yield(*contracts.map(&:result)))
133
133
  end
134
134
 
135
135
  # generic success return, when return value does not matter
@@ -6,22 +6,22 @@ module Safrano
6
6
  EMPTY_ARRAY = [].freeze
7
7
  EMPTY_HASH = {}.freeze
8
8
  EMPTY_HASH_IN_ARY = [EMPTY_HASH].freeze
9
- EMPTY_STRING = ''.freeze
9
+ EMPTY_STRING = ''
10
10
  ARY_204_EMPTY_HASH_ARY = [204, EMPTY_HASH, EMPTY_ARRAY].freeze
11
- SPACE = ' '.freeze
12
- COMMA = ','.freeze
11
+ SPACE = ' '
12
+ COMMA = ','
13
13
 
14
14
  # some prominent constants... probably already defined elsewhere eg in Rack
15
15
  # but lets KISS
16
- CONTENT_TYPE = 'Content-Type'.freeze
17
- CTT_TYPE_LC = 'content-type'.freeze
18
- TEXTPLAIN_UTF8 = 'text/plain;charset=utf-8'.freeze
19
- APPJSON = 'application/json'.freeze
20
- APPXML = 'application/xml'.freeze
21
- MP_MIXED = 'multipart/mixed'.freeze
22
- APPXML_UTF8 = 'application/xml;charset=utf-8'.freeze
23
- APPATOMXML_UTF8 = 'application/atomsvc+xml;charset=utf-8'.freeze
24
- APPJSON_UTF8 = 'application/json;charset=utf-8'.freeze
16
+ CONTENT_TYPE = 'Content-Type'
17
+ CTT_TYPE_LC = 'content-type'
18
+ TEXTPLAIN_UTF8 = 'text/plain;charset=utf-8'
19
+ APPJSON = 'application/json'
20
+ APPXML = 'application/xml'
21
+ MP_MIXED = 'multipart/mixed'
22
+ APPXML_UTF8 = 'application/xml;charset=utf-8'
23
+ APPATOMXML_UTF8 = 'application/atomsvc+xml;charset=utf-8'
24
+ APPJSON_UTF8 = 'application/json;charset=utf-8'
25
25
 
26
26
  CT_JSON = { CONTENT_TYPE => APPJSON_UTF8 }.freeze
27
27
  CT_TEXT = { CONTENT_TYPE => TEXTPLAIN_UTF8 }.freeze
@@ -22,7 +22,7 @@ module Safrano
22
22
  module Deprecation
23
23
  @backtrace_filter = false
24
24
  @output = $stderr
25
- @prefix = "SAFRANO DEPRECATION WARNING: ".freeze
25
+ @prefix = 'SAFRANO DEPRECATION WARNING: '
26
26
 
27
27
  class << self
28
28
  # How to filter backtraces. +false+ does not include backtraces, +true+ includes
@@ -64,10 +64,10 @@ module Safrano
64
64
  # otherwise do nothing as the ruby implementation does not support constant deprecation.
65
65
  def self.deprecate_constant(mod, constant)
66
66
  # :nocov:
67
- if RUBY_VERSION > '2.3'
68
- # :nocov:
69
- mod.deprecate_constant(constant)
70
- end
67
+ return unless RUBY_VERSION > '2.3'
68
+
69
+ # :nocov:
70
+ mod.deprecate_constant(constant)
71
71
  end
72
72
  end
73
73
  end
@@ -110,11 +110,11 @@ module MIME
110
110
  @target.ct = @target_ct
111
111
  @state = :bmp
112
112
  end
113
- MPS = 'multipart/'.freeze
113
+ MPS = 'multipart/'
114
114
  MP_RGX1 = %r{^(digest|mixed);\s*boundary="(.*)"}.freeze
115
115
  MP_RGX2 = %r{^(digest|mixed);\s*boundary=(.*)}.freeze
116
116
  # APP_HTTP_RGX = %r{^application/http}.freeze
117
- APP_HTTP = 'application/http'.freeze
117
+ APP_HTTP = 'application/http'
118
118
  def new_content
119
119
  @target =
120
120
  if @target_ct.start_with?(MPS) &&
@@ -56,7 +56,7 @@ module Safrano
56
56
  NOCACHE_HDRS = { 'Cache-Control' => 'no-cache',
57
57
  'Expires' => '-1',
58
58
  'Pragma' => 'no-cache' }.freeze
59
- DATASERVICEVERSION = 'DataServiceVersion'.freeze
59
+ DATASERVICEVERSION = 'DataServiceVersion'
60
60
  include MethodHandlers
61
61
 
62
62
  def before
@@ -9,7 +9,7 @@ module Safrano
9
9
  # is not passed
10
10
  class Request < Rack::Request
11
11
  HEADER_PARAM = /\s*[\w.]+=(?:[\w.]+|"(?:[^"\\]|\\.)*")?\s*/.freeze
12
- HEADER_VAL_RAW = '(?:\w+|\*)\/(?:\w+(?:\.|\-|\+)?|\*)*'.freeze
12
+ HEADER_VAL_RAW = '(?:\w+|\*)\/(?:\w+(?:\.|\-|\+)?|\*)*'
13
13
  HEADER_VAL_WITH_PAR = /(?:#{HEADER_VAL_RAW})\s*(?:;#{HEADER_PARAM})*/.freeze
14
14
  ON_CGST_ERROR = (proc { |r| raise(Sequel::Rollback) if r.in_changeset })
15
15
 
@@ -194,7 +194,7 @@ module Safrano
194
194
  if (rqv = env['HTTP_DATASERVICEVERSION'])
195
195
  if (m = DATASERVICEVERSION_RGX.match(rqv))
196
196
  # client request an too new version --> 501
197
- if ((v = m[1]) > Safrano::MAX_DATASERVICE_VERSION) or
197
+ if ((v = m[1]) > Safrano::MAX_DATASERVICE_VERSION) ||
198
198
  (v < Safrano::MIN_DATASERVICE_VERSION)
199
199
  Safrano::VersionNotImplementedError
200
200
  else
@@ -15,8 +15,8 @@ module Safrano
15
15
  # and will be included in Service class
16
16
  module ExpandHandler
17
17
  PATH_SPLITTER = %r{\A(\w+)/?(.*)\z}.freeze
18
- DEFERRED = '__deferred'.freeze
19
- URI = 'uri'.freeze
18
+ DEFERRED = '__deferred'
19
+ URI = 'uri'
20
20
 
21
21
  def get_deferred_odata_h(entity_uri:, attrib:)
22
22
  { DEFERRED => { URI => "#{entity_uri}/#{attrib}" } }
@@ -24,8 +24,8 @@ module Safrano
24
24
 
25
25
  # default v2
26
26
  # overriden in ServiceV1
27
- RESULTS_K = 'results'.freeze
28
- COUNT_K = '__count'.freeze
27
+ RESULTS_K = 'results'
28
+ COUNT_K = '__count'
29
29
  def get_coll_odata_h(array:, template:, icount: nil)
30
30
  array.map! do |w|
31
31
  get_entity_odata_h(entity: w, template: template)
@@ -40,7 +40,7 @@ module Safrano
40
40
  end
41
41
 
42
42
  EMPTYH = {}.freeze
43
- METADATA_K = '__metadata'.freeze
43
+ METADATA_K = '__metadata'
44
44
  def get_entity_odata_h(entity:, template:)
45
45
  # start with metadata
46
46
  hres = { METADATA_K => entity.metadata_h }
@@ -90,21 +90,20 @@ module Safrano
90
90
  # xml namespace constants needed for the output of XML service and
91
91
  # and metadata
92
92
  module XMLNS
93
- MSFT_ADO = 'http://schemas.microsoft.com/ado'.freeze
94
- MSFT_ADO_2009_EDM = "#{MSFT_ADO}/2009/11/edm".freeze
95
- MSFT_ADO_2007_EDMX = "#{MSFT_ADO}/2007/06/edmx".freeze
96
- MSFT_ADO_2007_META = MSFT_ADO + \
97
- '/2007/08/dataservices/metadata'.freeze
98
-
99
- W3_2005_ATOM = 'http://www.w3.org/2005/Atom'.freeze
100
- W3_2007_APP = 'http://www.w3.org/2007/app'.freeze
93
+ MSFT_ADO = 'http://schemas.microsoft.com/ado'
94
+ MSFT_ADO_2009_EDM = "#{MSFT_ADO}/2009/11/edm"
95
+ MSFT_ADO_2007_EDMX = "#{MSFT_ADO}/2007/06/edmx"
96
+ MSFT_ADO_2007_META = "#{MSFT_ADO}/2007/08/dataservices/metadata"
97
+
98
+ W3_2005_ATOM = 'http://www.w3.org/2005/Atom'
99
+ W3_2007_APP = 'http://www.w3.org/2007/app'
101
100
  end
102
101
  end
103
102
 
104
103
  # Link to Model
105
104
  module Safrano
106
- MAX_DATASERVICE_VERSION = '2'.freeze
107
- MIN_DATASERVICE_VERSION = '1'.freeze
105
+ MAX_DATASERVICE_VERSION = '2'
106
+ MIN_DATASERVICE_VERSION = '1'
108
107
  CV_MAX_DATASERVICE_VERSION = Contract.valid(MAX_DATASERVICE_VERSION).freeze
109
108
  CV_MIN_DATASERVICE_VERSION = Contract.valid(MIN_DATASERVICE_VERSION).freeze
110
109
  include XMLNS
@@ -113,7 +112,7 @@ module Safrano
113
112
  include Safrano
114
113
  include ExpandHandler
115
114
 
116
- XML_PREAMBLE = %Q(<?xml version="1.0" encoding="utf-8" standalone="yes"?>\r\n).freeze
115
+ XML_PREAMBLE = %Q(<?xml version="1.0" encoding="utf-8" standalone="yes"?>\r\n)
117
116
 
118
117
  # This is just a hash of entity Set Names to the corresponding Class
119
118
  # Example
@@ -161,8 +160,8 @@ module Safrano
161
160
  end
162
161
 
163
162
  TRAILING_SLASH = %r{/\z}.freeze
164
- DEFAULT_PATH_PREFIX = '/'.freeze
165
- DEFAULT_SERVER_URL = 'http://localhost:9494'.freeze
163
+ DEFAULT_PATH_PREFIX = '/'
164
+ DEFAULT_SERVER_URL = 'http://localhost:9494'
166
165
 
167
166
  def enable_batch
168
167
  @batch_handler = Safrano::Batch::EnabledHandler.new
@@ -530,7 +529,7 @@ module Safrano
530
529
 
531
530
  # methods related to transitions to next state (cf. walker)
532
531
  module Transitions
533
- DOLLAR_ID_REGEXP = Regexp.new('\A\/\$').freeze
532
+ DOLLAR_ID_REGEXP = Regexp.new('\A\/\$')
534
533
  ALLOWED_TRANSITIONS_FIXED = [
535
534
  Safrano::TransitionEnd,
536
535
  Safrano::TransitionMetadata,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Safrano
4
- VERSION = '0.4.4'
4
+ VERSION = '0.4.5'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safrano
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - oz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-30 00:00:00.000000000 Z
11
+ date: 2020-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -56,16 +56,16 @@ dependencies:
56
56
  name: rfc2047
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '0.3'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '0.3'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -189,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
189
  - !ruby/object:Gem::Version
190
190
  version: '0'
191
191
  requirements: []
192
- rubygems_version: 3.1.4
192
+ rubygems_version: 3.2.0.rc.2
193
193
  signing_key:
194
194
  specification_version: 4
195
195
  summary: Safrano is a Ruby OData server library based on Sequel and Rack