safrano 0.8.0 → 0.8.2
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 +4 -4
- data/lib/core_ext/Date/format.rb +1 -0
- data/lib/core_ext/DateTime/format.rb +1 -0
- data/lib/core_ext/Hash/transform.rb +2 -2
- data/lib/core_ext/MatchData/matchlen.rb +14 -0
- data/lib/core_ext/Time/format.rb +1 -1
- data/lib/core_ext/matchdata.rb +3 -0
- data/lib/odata/attribute.rb +4 -5
- data/lib/odata/batch.rb +3 -1
- data/lib/odata/collection.rb +3 -0
- data/lib/odata/collection_media.rb +5 -4
- data/lib/odata/complex_type.rb +4 -3
- data/lib/odata/entity.rb +7 -4
- data/lib/odata/error.rb +21 -5
- data/lib/odata/filter/base.rb +1 -0
- data/lib/odata/filter/error.rb +3 -0
- data/lib/odata/filter/sequel.rb +6 -10
- data/lib/odata/filter/sequel_datetime_adapter.rb +1 -0
- data/lib/odata/filter/sequel_function_adapter.rb +1 -0
- data/lib/odata/filter/tree.rb +28 -26
- data/lib/odata/function_import.rb +7 -0
- data/lib/odata/model_ext.rb +20 -17
- data/lib/odata/navigation_attribute.rb +6 -0
- data/lib/odata/request/json.rb +1 -0
- data/lib/odata/transition.rb +134 -27
- data/lib/odata/walker.rb +5 -25
- data/lib/safrano/rack_app.rb +16 -3
- data/lib/safrano/rack_builder.rb +37 -37
- data/lib/safrano/request.rb +5 -4
- data/lib/safrano/service.rb +61 -7
- data/lib/safrano/type_mapping.rb +6 -3
- data/lib/safrano/version.rb +1 -1
- data/lib/sequel/plugins/join_by_paths.rb +2 -2
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e43512da576932288321a8e821e26fa9c70d578f52562f6a343bfe3c3711bae
|
4
|
+
data.tar.gz: e2c00621b792634355f99d2025fada0d05cd44666516d916aa2546fb72f5157f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ff433c52ec4406198b0988e122213f0af36a8f1a06b2eb1d2ebfc2c3736db5f8c575fa86e04b8ac9801d4d4fb363edc468c3078b3f93c66313497739ffc3c2e
|
7
|
+
data.tar.gz: 59ebba62c9a7e81496a651473fa9469d843409dab4c1703221f897425136fe02439ea400e17124a910de599378056b7b21758815d734c9807778193c791e3286
|
data/lib/core_ext/Date/format.rb
CHANGED
data/lib/core_ext/Time/format.rb
CHANGED
@@ -15,7 +15,7 @@ module Safrano
|
|
15
15
|
return unless (md = instr.match(REGEX))
|
16
16
|
|
17
17
|
sec, milli = md[1].to_i.divmod(1000)
|
18
|
-
secm = milli.zero? ? sec : sec + Float(milli) / 1000
|
18
|
+
secm = milli.zero? ? sec : sec + (Float(milli) / 1000)
|
19
19
|
if md[3].nil? # no offset
|
20
20
|
# ::Time.at(sec, milli, :millisecond) # not supported in ruby 2.4
|
21
21
|
::Time.gm(1970, 1, 1) + secm
|
data/lib/odata/attribute.rb
CHANGED
@@ -13,6 +13,7 @@ module Safrano
|
|
13
13
|
def initialize(entity, name)
|
14
14
|
@entity = entity
|
15
15
|
@name = name
|
16
|
+
@allowed_transitions = ALLOWED_TRANSITIONS
|
16
17
|
end
|
17
18
|
|
18
19
|
def value
|
@@ -20,11 +21,7 @@ module Safrano
|
|
20
21
|
# currently it is just set to make some minimal testcase work
|
21
22
|
# See also model_ext.rb
|
22
23
|
case (v = @entity.values[@name.to_sym])
|
23
|
-
when Date
|
24
|
-
v.to_edm_json
|
25
|
-
when Time
|
26
|
-
v.to_edm_json
|
27
|
-
when DateTime
|
24
|
+
when Date, Time, DateTime
|
28
25
|
v.to_edm_json
|
29
26
|
else
|
30
27
|
v
|
@@ -68,6 +65,8 @@ module Safrano
|
|
68
65
|
def allowed_transitions
|
69
66
|
Transitions::ALLOWED_TRANSITIONS
|
70
67
|
end
|
68
|
+
|
69
|
+
include Safrano::Transitions::GetNextTrans::BySimpleDetect
|
71
70
|
end
|
72
71
|
include Transitions
|
73
72
|
end
|
data/lib/odata/batch.rb
CHANGED
@@ -103,7 +103,7 @@ module Safrano
|
|
103
103
|
|
104
104
|
# $batch Handler
|
105
105
|
class HandlerBase
|
106
|
-
TREND = Safrano::Transition.new('', trans:
|
106
|
+
TREND = Safrano::Transition.new('', trans: :transition_end)
|
107
107
|
def allowed_transitions
|
108
108
|
@allowed_transitions = [TREND]
|
109
109
|
end
|
@@ -111,6 +111,8 @@ module Safrano
|
|
111
111
|
def transition_end(_match_result)
|
112
112
|
Safrano::Transition::RESULT_END
|
113
113
|
end
|
114
|
+
|
115
|
+
include Safrano::Transitions::GetNextTrans::ForJustTransitionEnd
|
114
116
|
end
|
115
117
|
|
116
118
|
# $batch disabled Handler
|
data/lib/odata/collection.rb
CHANGED
@@ -20,6 +20,7 @@ module Safrano
|
|
20
20
|
|
21
21
|
def initialize(modelk)
|
22
22
|
@modelk = modelk
|
23
|
+
@allowed_transitions = @modelk.allowed_transitions
|
23
24
|
end
|
24
25
|
|
25
26
|
def allowed_transitions
|
@@ -52,6 +53,8 @@ module Safrano
|
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
56
|
+
include Safrano::Transitions::GetNextTrans::ByLongestMatch
|
57
|
+
|
55
58
|
# pkid can be a single value for single-pk models, or an array.
|
56
59
|
# type checking/convertion is done in check_odata_key_type
|
57
60
|
def find_by_odata_key(pkid)
|
@@ -14,6 +14,7 @@ module Safrano
|
|
14
14
|
Contract::OK
|
15
15
|
end
|
16
16
|
end
|
17
|
+
|
17
18
|
# Simple static File/Directory based media store handler
|
18
19
|
# similar to Rack::Static
|
19
20
|
# with a flat directory structure
|
@@ -35,11 +36,11 @@ module Safrano
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def create_abs_class_dir
|
38
|
-
FileUtils.makedirs @abs_klass_dir
|
39
|
+
FileUtils.makedirs @abs_klass_dir
|
39
40
|
end
|
40
41
|
|
41
42
|
def create_abs_temp_dir
|
42
|
-
FileUtils.makedirs @abs_temp_dir
|
43
|
+
FileUtils.makedirs @abs_temp_dir
|
43
44
|
end
|
44
45
|
|
45
46
|
def finalize
|
@@ -114,7 +115,7 @@ module Safrano
|
|
114
115
|
# and ensure the directory exists
|
115
116
|
def with_media_directory(entity)
|
116
117
|
mpi = abs_media_directory(entity)
|
117
|
-
|
118
|
+
FileUtils.mkdir_p mpi
|
118
119
|
yield Pathname(mpi)
|
119
120
|
end
|
120
121
|
|
@@ -200,7 +201,7 @@ module Safrano
|
|
200
201
|
def with_media_directory(entity)
|
201
202
|
mpi = abs_media_directory(entity)
|
202
203
|
|
203
|
-
FileUtils.makedirs mpi
|
204
|
+
FileUtils.makedirs mpi
|
204
205
|
yield Pathname(mpi)
|
205
206
|
end
|
206
207
|
|
data/lib/odata/complex_type.rb
CHANGED
@@ -21,6 +21,8 @@ module Safrano
|
|
21
21
|
Safrano::Transition::RESULT_END
|
22
22
|
end
|
23
23
|
|
24
|
+
include Safrano::Transitions::GetNextTrans::ForJustTransitionEnd
|
25
|
+
|
24
26
|
# we will have this on class and instance level for making things simpler first
|
25
27
|
class << self
|
26
28
|
attr_reader :klassmod
|
@@ -202,7 +204,7 @@ module Safrano
|
|
202
204
|
end
|
203
205
|
|
204
206
|
def metadata_h
|
205
|
-
{
|
207
|
+
{ type: type_name }
|
206
208
|
end
|
207
209
|
|
208
210
|
def casted_values
|
@@ -213,10 +215,9 @@ module Safrano
|
|
213
215
|
# needed for nested json output
|
214
216
|
# this is a simpler version of model_ext#output_template
|
215
217
|
def self.default_template
|
216
|
-
template = {}
|
218
|
+
template = { meta: EMPTYH, all_values: EMPTYH }
|
217
219
|
expand_e = {}
|
218
220
|
|
219
|
-
template[:all_values] = EMPTYH
|
220
221
|
@props.each do |prop, kl|
|
221
222
|
expand_e[prop] = kl.default_template if kl.respond_to? :default_template
|
222
223
|
end
|
data/lib/odata/entity.rb
CHANGED
@@ -19,6 +19,8 @@ module Safrano
|
|
19
19
|
self.class.entity_allowed_transitions
|
20
20
|
end
|
21
21
|
|
22
|
+
include Safrano::Transitions::GetNextTrans::ByLongestMatchDyn
|
23
|
+
|
22
24
|
def transition_end(_match_result)
|
23
25
|
Safrano::Transition::RESULT_END
|
24
26
|
end
|
@@ -184,9 +186,9 @@ module Safrano
|
|
184
186
|
if req.walker.media_value
|
185
187
|
odata_media_value_put(req)
|
186
188
|
elsif req.accept?(APPJSON)
|
187
|
-
|
189
|
+
|
188
190
|
AlreadyExistsUnprocessableError.odata_get(req)
|
189
|
-
|
191
|
+
|
190
192
|
else # TODO: other formats
|
191
193
|
415
|
192
194
|
end
|
@@ -215,7 +217,6 @@ module Safrano
|
|
215
217
|
def odata_patch(req)
|
216
218
|
req.with_parsed_data(self.class) do |data|
|
217
219
|
data.delete('__metadata')
|
218
|
-
|
219
220
|
# validate payload column names
|
220
221
|
if (invalid = self.class.invalid_hash_data?(data))
|
221
222
|
::Safrano::Request::ON_CGST_ERROR.call(req)
|
@@ -354,7 +355,7 @@ module Safrano
|
|
354
355
|
# real implementation for replacing $value for a media entity
|
355
356
|
def odata_media_value_put(req)
|
356
357
|
model = self.class
|
357
|
-
req.with_media_data do |data, mimetype,
|
358
|
+
req.with_media_data do |data, mimetype, _filename|
|
358
359
|
emdata = { content_type: mimetype }
|
359
360
|
if req.in_changeset
|
360
361
|
set_fields(emdata, model.data_fields, missing: :skip)
|
@@ -385,6 +386,7 @@ module Safrano
|
|
385
386
|
[pk_uri]
|
386
387
|
end
|
387
388
|
end
|
389
|
+
|
388
390
|
module PKUriWithoutFunc
|
389
391
|
def pk_uri
|
390
392
|
pk
|
@@ -398,6 +400,7 @@ module Safrano
|
|
398
400
|
[pk]
|
399
401
|
end
|
400
402
|
end
|
403
|
+
|
401
404
|
# for a single public key
|
402
405
|
module EntitySinglePK
|
403
406
|
include Entity
|
data/lib/odata/error.rb
CHANGED
@@ -46,6 +46,14 @@ module Safrano
|
|
46
46
|
super(msg, symbname)
|
47
47
|
end
|
48
48
|
end
|
49
|
+
|
50
|
+
# invalid response format option
|
51
|
+
class InvalidRespFormatOption < NameError
|
52
|
+
def initialize(opt)
|
53
|
+
msg = "Invalid response format option: #{opt}"
|
54
|
+
super(msg, opt.to_s)
|
55
|
+
end
|
56
|
+
end
|
49
57
|
end
|
50
58
|
|
51
59
|
# used in function import error handling. cf. func import / do_execute_func
|
@@ -142,11 +150,11 @@ module Safrano
|
|
142
150
|
@msg = reason
|
143
151
|
end
|
144
152
|
end
|
145
|
-
|
153
|
+
|
146
154
|
class AlreadyExistsUnprocessableError < UnprocessableEntityError
|
147
155
|
@msg = 'The ressource you are trying to create already exists'
|
148
156
|
end
|
149
|
-
|
157
|
+
|
150
158
|
# http Bad Req.
|
151
159
|
class BadRequestError
|
152
160
|
extend ErrorClass
|
@@ -165,6 +173,7 @@ module Safrano
|
|
165
173
|
@msg = "Bad Request: empty media file #{path}"
|
166
174
|
end
|
167
175
|
end
|
176
|
+
|
168
177
|
# Generic failed changeset
|
169
178
|
class BadRequestFailedChangeSet < BadRequestError
|
170
179
|
@msg = 'Bad Request: Failed changeset '
|
@@ -174,6 +183,7 @@ module Safrano
|
|
174
183
|
class BadRequestNonMediaValue < BadRequestError
|
175
184
|
@msg = 'Bad Request: $value request for a non-media entity'
|
176
185
|
end
|
186
|
+
|
177
187
|
class BadRequestSequelAdapterError < BadRequestError
|
178
188
|
include ErrorInstance
|
179
189
|
def initialize(err)
|
@@ -201,6 +211,7 @@ module Safrano
|
|
201
211
|
@msg = "Bad Request: the $expand path #{path} is invalid for entityset #{model.entity_set_name}"
|
202
212
|
end
|
203
213
|
end
|
214
|
+
|
204
215
|
# for invalid properti(es) in $select param
|
205
216
|
class BadRequestSelectInvalidProps < BadRequestError
|
206
217
|
include ErrorInstance
|
@@ -221,7 +232,7 @@ module Safrano
|
|
221
232
|
|
222
233
|
# http not found
|
223
234
|
class ErrorNotFound
|
224
|
-
extend
|
235
|
+
extend ErrorClass
|
225
236
|
HTTP_CODE = 404
|
226
237
|
@msg = 'The requested ressource was not found'
|
227
238
|
end
|
@@ -242,16 +253,17 @@ module Safrano
|
|
242
253
|
|
243
254
|
# not implemented (Safrano specific)
|
244
255
|
class NotImplementedError
|
245
|
-
extend
|
256
|
+
extend ErrorClass
|
246
257
|
HTTP_CODE = 501
|
247
258
|
end
|
248
259
|
|
249
260
|
# version not implemented (Safrano specific)
|
250
261
|
class VersionNotImplementedError
|
251
|
-
extend
|
262
|
+
extend ErrorClass
|
252
263
|
HTTP_CODE = 501
|
253
264
|
@msg = 'The requested OData version is not yet supported'
|
254
265
|
end
|
266
|
+
|
255
267
|
# batch not implemented (Safrano specific)
|
256
268
|
class BatchNotImplementedError < RuntimeError
|
257
269
|
@msg = 'Not implemented: OData batch'
|
@@ -270,22 +282,26 @@ module Safrano
|
|
270
282
|
@msg = xmsg
|
271
283
|
end
|
272
284
|
end
|
285
|
+
|
273
286
|
class FilterUnknownFunctionError < BadRequestError
|
274
287
|
include ErrorInstance
|
275
288
|
def initialize(badfuncname)
|
276
289
|
@msg = "Bad request: unknown function #{badfuncname} in $filter"
|
277
290
|
end
|
278
291
|
end
|
292
|
+
|
279
293
|
class FilterParseErrorWrongColumnName < BadRequestError
|
280
294
|
extend ErrorClass
|
281
295
|
@msg = 'Bad request: invalid property name in $filter'
|
282
296
|
end
|
297
|
+
|
283
298
|
class FilterParseWrappedError < BadRequestError
|
284
299
|
include ErrorInstance
|
285
300
|
def initialize(exception)
|
286
301
|
@msg = exception.to_s
|
287
302
|
end
|
288
303
|
end
|
304
|
+
|
289
305
|
class ServiceOperationParameterMissing < BadRequestError
|
290
306
|
include ErrorInstance
|
291
307
|
def initialize(missing:, sopname:)
|
data/lib/odata/filter/base.rb
CHANGED
data/lib/odata/filter/error.rb
CHANGED
@@ -35,6 +35,7 @@ module Safrano
|
|
35
35
|
@cur_typ = cur.class
|
36
36
|
end
|
37
37
|
end
|
38
|
+
|
38
39
|
# Invalid Tokens
|
39
40
|
class ErrorInvalidToken < Error
|
40
41
|
include ::Safrano::ErrorInstance
|
@@ -43,6 +44,7 @@ module Safrano
|
|
43
44
|
@msg = "Bad Request: invalid token #{tok} in $filter"
|
44
45
|
end
|
45
46
|
end
|
47
|
+
|
46
48
|
# Unmached closed
|
47
49
|
class ErrorUnmatchedClose < Error
|
48
50
|
include ::Safrano::ErrorInstance
|
@@ -73,6 +75,7 @@ module Safrano
|
|
73
75
|
@msg = "Bad Request: wrong number of parameters for function #{cur.parent.value} in $filter"
|
74
76
|
end
|
75
77
|
end
|
78
|
+
|
76
79
|
# Invalid separator in this context (missing parenthesis?)
|
77
80
|
class ErrorInvalidSeparator < Error
|
78
81
|
include ::Safrano::ErrorInstance
|
data/lib/odata/filter/sequel.rb
CHANGED
@@ -51,21 +51,17 @@ module Safrano
|
|
51
51
|
when :substringof
|
52
52
|
|
53
53
|
# there are multiple possible argument types (but all should return edm.string)
|
54
|
-
if args[0].is_a?(QString)
|
55
|
-
# substringof('Rhum', name) -->
|
56
|
-
# name contains substr 'Rhum'
|
57
|
-
Contract.collect_result!(args[1].leuqes(jh),
|
58
|
-
args[0].leuqes_substringof_sig1(jh)) do |l1, l0|
|
59
|
-
Sequel.like(l1, l0)
|
60
|
-
end
|
61
54
|
|
62
|
-
|
63
|
-
|
55
|
+
if args[0].is_a?(QString) ||
|
56
|
+
# substringof('Rhum', name) -->
|
57
|
+
# name contains substr 'Rhum'
|
58
|
+
|
59
|
+
# special non standard (ui5 client) case ?
|
60
|
+
(args[0].is_a?(Literal) && args[1].is_a?(Literal))
|
64
61
|
Contract.collect_result!(args[1].leuqes(jh),
|
65
62
|
args[0].leuqes_substringof_sig1(jh)) do |l1, l0|
|
66
63
|
Sequel.like(l1, l0)
|
67
64
|
end
|
68
|
-
|
69
65
|
elsif args[1].is_a?(QString)
|
70
66
|
substringof_sig2(jh) # adapter specific
|
71
67
|
else
|
@@ -64,6 +64,7 @@ module Safrano
|
|
64
64
|
Safrano::FilterFunctionNotImplementedError.new("$filter function 'ceiling' is not implemented in sqlite adapter")
|
65
65
|
end
|
66
66
|
end
|
67
|
+
|
67
68
|
# re-useable module with math floor/ceil functions for those adapters having these SQL funcs
|
68
69
|
module MathFloorCeilFuncTree
|
69
70
|
def floor(lq)
|
data/lib/odata/filter/tree.rb
CHANGED
@@ -355,14 +355,14 @@ module Safrano
|
|
355
355
|
|
356
356
|
# Numbers (floating point, ints, dec)
|
357
357
|
class FPNumber
|
358
|
-
def initialize(val)
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
end
|
358
|
+
# def initialize(val)
|
359
|
+
# 1.53f --> value 1.53
|
360
|
+
# 1.53d --> value 1.53
|
361
|
+
# 1.53 --> value 1.53
|
362
|
+
# Note: the tokenizer has already dropped the not usefull string parts
|
363
|
+
# Note : we dont differentiate between Float and Double here
|
364
|
+
# super(val)
|
365
|
+
# end
|
366
366
|
|
367
367
|
def accept?(tok, typ)
|
368
368
|
case typ
|
@@ -396,14 +396,13 @@ module Safrano
|
|
396
396
|
end
|
397
397
|
|
398
398
|
class DecimalLit
|
399
|
-
def initialize(val)
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
end
|
399
|
+
# def initialize(val)
|
400
|
+
# 1.53m --> value 1.53
|
401
|
+
# Warning, this assumes that the m|M part in the input is really not optional
|
402
|
+
# Note: the tokenizer has already dropped the not usefull string parts
|
403
|
+
# cf. DECIMALRGX in token.rb
|
404
|
+
# super(val)
|
405
|
+
# end
|
407
406
|
|
408
407
|
def accept?(tok, typ)
|
409
408
|
case typ
|
@@ -418,6 +417,7 @@ module Safrano
|
|
418
417
|
:decimal
|
419
418
|
end
|
420
419
|
end
|
420
|
+
|
421
421
|
# Literals are unquoted words without /
|
422
422
|
class Literal
|
423
423
|
def accept?(tok, typ)
|
@@ -465,11 +465,11 @@ module Safrano
|
|
465
465
|
|
466
466
|
# DateTimeLit
|
467
467
|
class DateTimeLit
|
468
|
-
def initialize(val)
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
end
|
468
|
+
# def initialize(val)
|
469
|
+
# datetime'2000-12-12T12:00:53' --> value 2000-12-12T12:00:53
|
470
|
+
# Note: the tokenizer has already dropped the not usefull string parts
|
471
|
+
# super(val)
|
472
|
+
# end
|
473
473
|
|
474
474
|
def accept?(tok, typ)
|
475
475
|
case typ
|
@@ -484,13 +484,14 @@ module Safrano
|
|
484
484
|
:datetime
|
485
485
|
end
|
486
486
|
end
|
487
|
+
|
487
488
|
# DateTimeOffsetLit
|
488
489
|
class DateTimeOffsetLit
|
489
|
-
def initialize(val)
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
end
|
490
|
+
# def initialize(val)
|
491
|
+
# datetimeoffset'2000-12-12T12:00:53+02:00' --> value 2000-12-12T12:00:53+02:00
|
492
|
+
# Note: the tokenizer has already dropped the not usefull string parts
|
493
|
+
# super(val)
|
494
|
+
# end
|
494
495
|
|
495
496
|
def accept?(tok, typ)
|
496
497
|
case typ
|
@@ -505,6 +506,7 @@ module Safrano
|
|
505
506
|
:datetimeoffset
|
506
507
|
end
|
507
508
|
end
|
509
|
+
|
508
510
|
# Quoted Strings
|
509
511
|
class QString
|
510
512
|
DBL_QO = "''"
|
@@ -17,6 +17,7 @@ module Safrano
|
|
17
17
|
super(msg)
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
20
21
|
class ProcRedefinition < StandardError
|
21
22
|
def initialize(fnam)
|
22
23
|
msg = "Function import #{fnam}: Block/lambda Redefinition . Provide definition either as a return code block or with .definition(lambda) but not both"
|
@@ -39,6 +40,12 @@ module Safrano
|
|
39
40
|
[Safrano::TransitionExecuteFunc]
|
40
41
|
end
|
41
42
|
|
43
|
+
include Safrano::Transitions::GetNextTrans::ForJustTransitionEnd
|
44
|
+
|
45
|
+
def get_next_transresult(path_remain)
|
46
|
+
Safrano::TransitionExecuteFunc.result(path_remain)
|
47
|
+
end
|
48
|
+
|
42
49
|
def input(**parmtypes)
|
43
50
|
@input = {}
|
44
51
|
parmtypes.each do |k, t|
|
data/lib/odata/model_ext.rb
CHANGED
@@ -236,9 +236,9 @@ module Safrano
|
|
236
236
|
def output_template(expand_list:,
|
237
237
|
select: Safrano::SelectBase::ALL)
|
238
238
|
|
239
|
-
return @default_template if expand_list.empty? && select.all_props?
|
239
|
+
return @default_template.dup if expand_list.empty? && select.all_props?
|
240
240
|
|
241
|
-
template = {}
|
241
|
+
template = { meta: EMPTYH }
|
242
242
|
expand_e = {}
|
243
243
|
expand_c = {}
|
244
244
|
deferr = []
|
@@ -364,7 +364,7 @@ module Safrano
|
|
364
364
|
EMPTYH = {}.freeze
|
365
365
|
|
366
366
|
def build_default_template
|
367
|
-
@default_template = { all_values: EMPTYH }
|
367
|
+
@default_template = { meta: EMPTYH, all_values: EMPTYH }
|
368
368
|
@default_template[:deferr] = (@nav_entity_attribs&.keys || []) + (@nav_collection_attribs&.keys || EMPTY_ARRAY) if @nav_entity_attribs || @nav_collection_attribs
|
369
369
|
end
|
370
370
|
|
@@ -445,17 +445,17 @@ module Safrano
|
|
445
445
|
|
446
446
|
# check if key needs casting. Important for later entity-uri generation !
|
447
447
|
return unless primary_key.is_a? Symbol # single key field
|
448
|
-
|
449
|
-
# guid key as guid'xxx-yyy-zzz'
|
448
|
+
|
449
|
+
# guid key as guid'xxx-yyy-zzz'
|
450
450
|
metadata = @cols_metadata[primary_key]
|
451
|
-
|
451
|
+
|
452
452
|
if metadata[:edm_type] == 'Edm.Guid'
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
453
|
+
props = db_schema[primary_key]
|
454
|
+
@pk_castfunc = if props[:type] == :blob # Edm.Guid but as 16 byte binary Blob on DB level, eg in Sqlite
|
455
|
+
lambda { |x| "guid'#{UUIDTools::UUID.parse_raw(x)}'" unless x.nil? }
|
456
|
+
else
|
457
|
+
lambda { |x| "guid'#{x}'" unless x.nil? }
|
458
|
+
end
|
459
459
|
else
|
460
460
|
@pk_castfunc = @casted_cols[primary_key]
|
461
461
|
end
|
@@ -607,12 +607,15 @@ module Safrano
|
|
607
607
|
end
|
608
608
|
end
|
609
609
|
end
|
610
|
+
|
610
611
|
# methods related to transitions to next state (cf. walker)
|
611
612
|
module Transitions
|
612
613
|
def allowed_transitions
|
613
614
|
@allowed_transitions
|
614
615
|
end
|
615
616
|
|
617
|
+
include Safrano::Transitions::GetNextTrans::BySimpleDetect
|
618
|
+
|
616
619
|
def entity_allowed_transitions
|
617
620
|
@entity_allowed_transitions
|
618
621
|
end
|
@@ -621,7 +624,7 @@ module Safrano
|
|
621
624
|
@allowed_transitions = [Safrano::TransitionEnd,
|
622
625
|
Safrano::TransitionCount,
|
623
626
|
Safrano::Transition.new(entity_id_url_regexp,
|
624
|
-
trans:
|
627
|
+
trans: :transition_id)].freeze
|
625
628
|
end
|
626
629
|
|
627
630
|
def build_entity_allowed_transitions
|
@@ -630,17 +633,17 @@ module Safrano
|
|
630
633
|
Safrano::TransitionCount,
|
631
634
|
Safrano::TransitionLinks,
|
632
635
|
Safrano::TransitionValue,
|
633
|
-
Safrano::Transition.new(transition_attribute_regexp, trans:
|
636
|
+
Safrano::Transition.new(transition_attribute_regexp, trans: :transition_attribute)
|
634
637
|
]
|
635
638
|
if (ncurgx = @nav_collection_url_regexp)
|
636
639
|
@entity_allowed_transitions <<
|
637
|
-
Safrano::Transition.new(%r{\A/(#{ncurgx})(.*)\z}, trans:
|
640
|
+
Safrano::Transition.new(%r{\A/(#{ncurgx})(.*)\z}, trans: :transition_nav_collection)
|
638
641
|
end
|
639
642
|
if (neurgx = @nav_entity_url_regexp)
|
640
643
|
@entity_allowed_transitions <<
|
641
|
-
Safrano::Transition.new(%r{\A/(#{neurgx})(.*)\z}, trans:
|
644
|
+
Safrano::Transition.new(%r{\A/(#{neurgx})(.*)\z}, trans: :transition_nav_entity)
|
642
645
|
end
|
643
|
-
@entity_allowed_transitions << Safrano::Transition.new(%r{\A/(\w+)(.*)\z}, trans:
|
646
|
+
@entity_allowed_transitions << Safrano::Transition.new(%r{\A/(\w+)(.*)\z}, trans: :transition_invalid_attribute)
|
644
647
|
@entity_allowed_transitions.freeze
|
645
648
|
@entity_allowed_transitions
|
646
649
|
end
|