safrano 0.4.4 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
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