safrano 0.4.3 → 0.5.1
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/Dir/iter.rb +18 -0
- data/lib/core_ext/Hash/transform.rb +21 -0
- data/lib/core_ext/Integer/edm.rb +13 -0
- data/lib/core_ext/REXML/Document/output.rb +16 -0
- data/lib/core_ext/String/convert.rb +25 -0
- data/lib/core_ext/String/edm.rb +13 -0
- data/lib/core_ext/dir.rb +3 -0
- data/lib/core_ext/hash.rb +3 -0
- data/lib/core_ext/integer.rb +3 -0
- data/lib/core_ext/rexml.rb +3 -0
- data/lib/core_ext/string.rb +5 -0
- data/lib/odata/attribute.rb +8 -4
- data/lib/odata/batch.rb +9 -7
- data/lib/odata/collection.rb +139 -642
- data/lib/odata/collection_filter.rb +18 -42
- data/lib/odata/collection_media.rb +111 -54
- data/lib/odata/collection_order.rb +5 -2
- data/lib/odata/common_logger.rb +2 -0
- data/lib/odata/complex_type.rb +196 -0
- data/lib/odata/edm/primitive_types.rb +184 -0
- data/lib/odata/entity.rb +78 -123
- data/lib/odata/error.rb +170 -37
- data/lib/odata/expand.rb +20 -17
- data/lib/odata/filter/base.rb +9 -1
- data/lib/odata/filter/error.rb +43 -27
- data/lib/odata/filter/parse.rb +39 -25
- data/lib/odata/filter/sequel.rb +112 -56
- data/lib/odata/filter/sequel_function_adapter.rb +50 -49
- data/lib/odata/filter/token.rb +21 -18
- data/lib/odata/filter/tree.rb +78 -44
- data/lib/odata/function_import.rb +168 -0
- data/lib/odata/model_ext.rb +641 -0
- data/lib/odata/navigation_attribute.rb +9 -24
- data/lib/odata/relations.rb +5 -5
- data/lib/odata/select.rb +17 -5
- data/lib/odata/transition.rb +71 -0
- data/lib/odata/url_parameters.rb +100 -24
- data/lib/odata/walker.rb +18 -10
- data/lib/safrano.rb +18 -38
- data/lib/safrano/contract.rb +141 -0
- data/lib/safrano/core.rb +24 -106
- data/lib/safrano/core_ext.rb +13 -0
- data/lib/safrano/deprecation.rb +73 -0
- data/lib/safrano/multipart.rb +29 -24
- data/lib/safrano/rack_app.rb +62 -63
- data/lib/safrano/{odata_rack_builder.rb → rack_builder.rb} +18 -1
- data/lib/safrano/request.rb +96 -38
- data/lib/safrano/response.rb +4 -2
- data/lib/safrano/sequel_join_by_paths.rb +2 -2
- data/lib/safrano/service.rb +156 -110
- data/lib/safrano/version.rb +3 -1
- data/lib/sequel/plugins/join_by_paths.rb +6 -19
- metadata +30 -11
data/lib/odata/filter/token.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
module OData
|
3
|
+
module Safrano
|
5
4
|
module Filter
|
6
5
|
class Parser
|
7
6
|
# Input tokenizer
|
@@ -10,14 +9,16 @@ module OData
|
|
10
9
|
replace substring trim toupper tolower
|
11
10
|
day hour minute month second year
|
12
11
|
round floor ceiling].freeze
|
13
|
-
FUNCRGX = FUNCNAMES.join('|')
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
FUNCRGX = FUNCNAMES.join('|')
|
13
|
+
NULLRGX = 'null|NULL|Null'
|
14
|
+
QSTRINGRGX = /'((?:[^']|(?:'{2}))*)'/.freeze
|
15
|
+
BINOBOOL = '[eE][qQ]|[LlgGNn][eETt]|[aA][nN][dD]|[oO][rR]'
|
16
|
+
BINOARITHM = '[aA][dD][dD]|[sS][uU][bB]|[mM][uU][lL]|[dD][iI][vV]|[mM][oO][dD]'
|
17
|
+
NOTRGX = 'not|NOT|Not'
|
18
|
+
FPRGX = '\d+(?:\.\d+)?(?:e[+-]?\d+)?'
|
19
|
+
QUALITRGX = '\w+(?:\/\w+)+'
|
20
|
+
RGX = /(#{FUNCRGX})|(#{NULLRGX})|([\(\),])|(#{BINOBOOL})\s+|(#{BINOARITHM})|(#{NOTRGX})|#{QSTRINGRGX}|(#{FPRGX})|(#{QUALITRGX})|(\w+)|(')/.freeze
|
21
|
+
|
21
22
|
def each_typed_token(inp)
|
22
23
|
typ = nil
|
23
24
|
|
@@ -34,27 +35,29 @@ module OData
|
|
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
|
-
:
|
47
|
+
:BinopBool
|
47
48
|
when 4
|
48
|
-
:
|
49
|
+
:BinopArithm
|
49
50
|
when 5
|
50
|
-
:
|
51
|
+
:UnopTree
|
51
52
|
when 6
|
52
|
-
:
|
53
|
+
:QString
|
53
54
|
when 7
|
54
|
-
:
|
55
|
+
:FPNumber
|
55
56
|
when 8
|
56
|
-
:
|
57
|
+
:Qualit
|
57
58
|
when 9
|
59
|
+
:Literal
|
60
|
+
when 10
|
58
61
|
:unmatchedQuote
|
59
62
|
end
|
60
63
|
yield found, typ
|
data/lib/odata/filter/tree.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative './base
|
4
|
-
require_relative './error
|
3
|
+
require_relative './base'
|
4
|
+
require_relative './error'
|
5
5
|
|
6
|
-
module
|
6
|
+
module Safrano
|
7
7
|
module Filter
|
8
8
|
# Base class for Leaves, Trees, RootTrees etc
|
9
9
|
class Node
|
10
10
|
attr_reader :value
|
11
|
+
|
11
12
|
def initialize(val, &block)
|
12
13
|
@value = val
|
13
14
|
instance_eval(&block) if block_given?
|
@@ -21,15 +22,16 @@ module OData
|
|
21
22
|
# Leaves are Nodes with a parent but no children
|
22
23
|
class Leave
|
23
24
|
attr_accessor :parent
|
25
|
+
|
26
|
+
# nil is considered as accepted, otherwise non-nil=the error
|
24
27
|
def accept?(tok, typ)
|
25
|
-
|
28
|
+
Parser::ErrorInvalidToken(tok, typ)
|
26
29
|
end
|
27
30
|
|
28
31
|
def check_types; end
|
29
32
|
|
30
|
-
def attach(
|
31
|
-
|
32
|
-
raise ErrorLeaveChild
|
33
|
+
def attach(_child)
|
34
|
+
Safrano::Filter::Parser::ErrorLeaveChild
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
@@ -37,6 +39,7 @@ module OData
|
|
37
39
|
class RootTree
|
38
40
|
attr_reader :children
|
39
41
|
attr_accessor :state
|
42
|
+
|
40
43
|
def initialize(val: :root, &block)
|
41
44
|
@children = []
|
42
45
|
super(val, &block)
|
@@ -45,6 +48,7 @@ module OData
|
|
45
48
|
def attach(child)
|
46
49
|
child.parent = self
|
47
50
|
@children << child
|
51
|
+
Contract::OK
|
48
52
|
end
|
49
53
|
|
50
54
|
def detach(child)
|
@@ -58,23 +62,27 @@ module OData
|
|
58
62
|
|
59
63
|
def update_state(tok, typ) end
|
60
64
|
|
65
|
+
# nil is considered as accepted, otherwise non-nil=the error
|
61
66
|
def accept?(tok, typ)
|
62
67
|
case typ
|
63
|
-
when :Literal, :Qualit, :QString, :FuncTree, :ArgTree,
|
64
|
-
|
68
|
+
when :Literal, :NullLiteral, :Qualit, :QString, :FuncTree, :ArgTree,
|
69
|
+
:UnopTree, :FPNumber
|
70
|
+
nil
|
65
71
|
when :Delimiter
|
66
72
|
if tok == '('
|
67
|
-
|
73
|
+
nil
|
68
74
|
else
|
69
|
-
|
75
|
+
Parser::ErrorInvalidToken.new(tok, typ, self)
|
70
76
|
end
|
71
77
|
else
|
72
|
-
|
78
|
+
Parser::ErrorInvalidToken.new(tok, typ, self)
|
73
79
|
end
|
74
80
|
end
|
75
81
|
|
76
82
|
def check_types
|
77
|
-
|
83
|
+
err = nil
|
84
|
+
@children.find { |c| (err = c.check_types) }
|
85
|
+
err
|
78
86
|
end
|
79
87
|
end
|
80
88
|
|
@@ -125,10 +133,11 @@ module OData
|
|
125
133
|
end
|
126
134
|
end
|
127
135
|
|
136
|
+
# nil is considered as accepted, otherwise non-nil=the error
|
128
137
|
def accept?(tok, typ)
|
129
138
|
case typ
|
130
139
|
when :BinopBool, :BinopArithm
|
131
|
-
|
140
|
+
nil
|
132
141
|
else
|
133
142
|
super(tok, typ)
|
134
143
|
end
|
@@ -139,9 +148,9 @@ module OData
|
|
139
148
|
when :length
|
140
149
|
argtyp = args.first.edm_type
|
141
150
|
if (argtyp != :any) && (argtyp != :string)
|
142
|
-
|
143
|
-
|
144
|
-
|
151
|
+
return Parser::ErrorInvalidArgumentType.new(self,
|
152
|
+
expected: :string,
|
153
|
+
actual: argtyp)
|
145
154
|
end
|
146
155
|
end
|
147
156
|
super
|
@@ -158,13 +167,33 @@ module OData
|
|
158
167
|
|
159
168
|
# we can have parenthesis with one expression inside everywhere
|
160
169
|
# only in FuncTree this is redefined for the function's arity
|
170
|
+
# Note: if you change this method, please also update arity_full_monkey?
|
171
|
+
# see below
|
161
172
|
def arity_full?(cursize)
|
162
173
|
cursize >= 1
|
163
174
|
end
|
164
175
|
|
176
|
+
# this is for testing only.
|
177
|
+
# see 99_threadsafe_tc.rb
|
178
|
+
# there we will monkey patch arity_full? by adding some sleeping
|
179
|
+
# to easily slow down a given test-thread (while the other one runs normaly)
|
180
|
+
#
|
181
|
+
# The rule is to keep this method here exactly same as the original
|
182
|
+
# "productive" one
|
183
|
+
#
|
184
|
+
# With this trick we can test threadsafeness without touching
|
185
|
+
# "productive" code
|
186
|
+
def arity_full_monkey?(cursize)
|
187
|
+
cursize >= 1
|
188
|
+
end
|
189
|
+
|
165
190
|
def edm_type
|
166
191
|
@children.first.edm_type
|
167
192
|
end
|
193
|
+
|
194
|
+
def ==(other)
|
195
|
+
@children == other.children
|
196
|
+
end
|
168
197
|
end
|
169
198
|
|
170
199
|
# unary op eg. NOT
|
@@ -203,7 +232,7 @@ module OData
|
|
203
232
|
|
204
233
|
def update_state(_tok, typ)
|
205
234
|
case typ
|
206
|
-
when :Literal, :Qualit, :QString, :FuncTree, :BinopBool, :BinopArithm, :UnopTree, :FPNumber
|
235
|
+
when :Literal, :NullLiteral, :Qualit, :QString, :FuncTree, :BinopBool, :BinopArithm, :UnopTree, :FPNumber
|
207
236
|
@state = :closed
|
208
237
|
end
|
209
238
|
end
|
@@ -255,6 +284,7 @@ module OData
|
|
255
284
|
# Arguments or lists
|
256
285
|
class ArgTree
|
257
286
|
attr_reader :type
|
287
|
+
|
258
288
|
def initialize(val)
|
259
289
|
@type = :expression
|
260
290
|
@state = :open
|
@@ -267,45 +297,48 @@ module OData
|
|
267
297
|
@state = :closed
|
268
298
|
when :Separator
|
269
299
|
@state = :sep
|
270
|
-
when :Literal, :Qualit, :QString, :FuncTree, :FPNumber
|
300
|
+
when :Literal, :NullLiteral, :Qualit, :QString, :FuncTree, :FPNumber
|
271
301
|
@state = :val
|
272
302
|
end
|
273
303
|
end
|
274
304
|
|
305
|
+
# nil is considered as accepted, otherwise non-nil=the error
|
275
306
|
def accept?(tok, typ)
|
276
307
|
case typ
|
277
308
|
when :Delimiter
|
278
309
|
if @value == '(' && tok == ')' && @state != :closed
|
279
|
-
if @parent.
|
280
|
-
|
310
|
+
if (@parent.class == IdentityFuncTree) or
|
311
|
+
(@parent.arity_full?(@children.size))
|
312
|
+
|
313
|
+
nil
|
281
314
|
else
|
282
|
-
|
315
|
+
Parser::ErrorInvalidArity.new(tok, typ, self)
|
283
316
|
end
|
284
317
|
else
|
285
|
-
|
318
|
+
if @value == '(' && tok == '(' && @state == :open
|
319
|
+
nil
|
320
|
+
else
|
321
|
+
Parser::ErrorUnmatchedClose.new(tok, typ, self)
|
322
|
+
end
|
286
323
|
end
|
287
324
|
when :Separator
|
288
325
|
if @value == '(' && tok == ',' && @state == :val
|
289
|
-
|
326
|
+
nil
|
290
327
|
elsif @state == :sep
|
291
|
-
|
292
|
-
else
|
293
|
-
true
|
328
|
+
Parser::ErrorInvalidToken.new(tok, typ, self)
|
294
329
|
end
|
295
|
-
when :Literal, :Qualit, :QString, :FuncTree, :FPNumber
|
330
|
+
when :Literal, :NullLiteral, :Qualit, :QString, :FuncTree, :FPNumber
|
296
331
|
if (@state == :open) || (@state == :sep)
|
297
332
|
if @parent.arity_full?(@children.size)
|
298
|
-
|
299
|
-
else
|
300
|
-
true
|
333
|
+
Parser::ErrorInvalidArity.new(tok, typ, self)
|
301
334
|
end
|
302
335
|
else
|
303
|
-
|
336
|
+
Parser::ErrorInvalidToken.new(tok, typ, self)
|
304
337
|
end
|
305
338
|
when :BinopBool, :BinopArithm
|
306
|
-
|
339
|
+
nil
|
307
340
|
else
|
308
|
-
|
341
|
+
Parser::ErrorInvalidToken.new(tok, typ, self)
|
309
342
|
end
|
310
343
|
end
|
311
344
|
|
@@ -319,9 +352,9 @@ module OData
|
|
319
352
|
def accept?(tok, typ)
|
320
353
|
case typ
|
321
354
|
when :Delimiter, :Separator, :BinopBool, :BinopArithm
|
322
|
-
|
355
|
+
nil
|
323
356
|
else
|
324
|
-
|
357
|
+
Parser::ErrorInvalidToken.new(tok, typ, self)
|
325
358
|
end
|
326
359
|
end
|
327
360
|
|
@@ -336,9 +369,9 @@ module OData
|
|
336
369
|
def accept?(tok, typ)
|
337
370
|
case typ
|
338
371
|
when :Delimiter, :Separator, :BinopBool, :BinopArithm
|
339
|
-
|
372
|
+
nil
|
340
373
|
else
|
341
|
-
|
374
|
+
Parser::ErrorInvalidToken.new(tok, typ, self)
|
342
375
|
end
|
343
376
|
end
|
344
377
|
|
@@ -351,8 +384,8 @@ module OData
|
|
351
384
|
# an attempt to use a unknown function, eg. ceil(Total)
|
352
385
|
# instead of ceiling(Total)
|
353
386
|
def attach(child)
|
354
|
-
if child.
|
355
|
-
|
387
|
+
if child.is_a? Safrano::Filter::IdentityFuncTree
|
388
|
+
Safrano::FilterUnknownFunctionError.new(value)
|
356
389
|
else
|
357
390
|
super
|
358
391
|
end
|
@@ -365,6 +398,7 @@ module OData
|
|
365
398
|
REGEXP = /((?:\w+\/)+)(\w+)/.freeze
|
366
399
|
attr_reader :path
|
367
400
|
attr_reader :attrib
|
401
|
+
|
368
402
|
def initialize(val)
|
369
403
|
super(val)
|
370
404
|
# split into path + attrib
|
@@ -377,8 +411,8 @@ module OData
|
|
377
411
|
|
378
412
|
# Quoted Strings
|
379
413
|
class QString
|
380
|
-
DBL_QO = "''"
|
381
|
-
SI_QO = "'"
|
414
|
+
DBL_QO = "''"
|
415
|
+
SI_QO = "'"
|
382
416
|
def initialize(val)
|
383
417
|
# unescape double quotes
|
384
418
|
super(val.gsub(DBL_QO, SI_QO))
|
@@ -387,9 +421,9 @@ module OData
|
|
387
421
|
def accept?(tok, typ)
|
388
422
|
case typ
|
389
423
|
when :Delimiter, :Separator, :BinopBool, :BinopArithm
|
390
|
-
|
424
|
+
nil
|
391
425
|
else
|
392
|
-
|
426
|
+
Parser::ErrorInvalidToken.new(tok, typ, self)
|
393
427
|
end
|
394
428
|
end
|
395
429
|
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'complex_type'
|
4
|
+
require_relative 'edm/primitive_types'
|
5
|
+
require_relative 'transition'
|
6
|
+
|
7
|
+
module Safrano
|
8
|
+
def self.FunctionImport(name)
|
9
|
+
FunctionImport::Function.new(name)
|
10
|
+
end
|
11
|
+
|
12
|
+
module FunctionImport
|
13
|
+
class Function
|
14
|
+
@allowed_transitions = [Safrano::TransitionEnd]
|
15
|
+
attr_reader :name
|
16
|
+
attr_reader :proc
|
17
|
+
|
18
|
+
def initialize(name)
|
19
|
+
@name = name
|
20
|
+
@http_method = 'GET'
|
21
|
+
end
|
22
|
+
|
23
|
+
def allowed_transitions
|
24
|
+
[Safrano::TransitionEnd]
|
25
|
+
end
|
26
|
+
|
27
|
+
def input(**parmtypes)
|
28
|
+
@input = {}
|
29
|
+
parmtypes.each do |k, t|
|
30
|
+
@input[k] = case t.name
|
31
|
+
when 'Integer'
|
32
|
+
Safrano::Edm::Edm::Int32
|
33
|
+
when 'String'
|
34
|
+
Safrano::Edm::Edm::String
|
35
|
+
when 'Float'
|
36
|
+
Safrano::Edm::Edm::Double
|
37
|
+
when 'DateTime'
|
38
|
+
Safrano::Edm::Edm::DateTime
|
39
|
+
else
|
40
|
+
t
|
41
|
+
end
|
42
|
+
end
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def return(klassmod, &proc)
|
47
|
+
raise('Please provide a code block') unless block_given?
|
48
|
+
|
49
|
+
@returning = if klassmod.respond_to? :return_as_instance_descriptor
|
50
|
+
klassmod.return_as_instance_descriptor
|
51
|
+
else
|
52
|
+
# if it's neither a ComplexType nor a Model-Entity
|
53
|
+
# --> assume it is a Primitive
|
54
|
+
ResultAsPrimitiveType.new(klassmod)
|
55
|
+
end
|
56
|
+
@proc = proc
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
def return_collection(klassmod, &proc)
|
61
|
+
raise('Please provide a code block') unless block_given?
|
62
|
+
|
63
|
+
@returning = if klassmod.respond_to? :return_as_collection_descriptor
|
64
|
+
klassmod.return_as_collection_descriptor
|
65
|
+
else
|
66
|
+
# if it's neither a ComplexType nor a Modle-Entity
|
67
|
+
# --> assume it is a Primitive
|
68
|
+
ResultAsPrimitiveTypeColl.new(klassmod)
|
69
|
+
end
|
70
|
+
@proc = proc
|
71
|
+
self
|
72
|
+
end
|
73
|
+
# def initialize_params
|
74
|
+
# @uparms = UrlParameters4Func.new(@model, @params)
|
75
|
+
# end
|
76
|
+
|
77
|
+
def check_missing_params
|
78
|
+
# do we have all parameters provided ? use Set difference to check
|
79
|
+
pkeys = @params.keys.map(&:to_sym).to_set
|
80
|
+
unless (idiff = @input.keys.to_set - pkeys).empty?
|
81
|
+
|
82
|
+
Safrano::ServiceOperationParameterMissing.new(
|
83
|
+
missing: idiff.to_a,
|
84
|
+
sopname: @name
|
85
|
+
)
|
86
|
+
else
|
87
|
+
Contract::OK
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def check_url_func_params
|
92
|
+
@funcparams = {}
|
93
|
+
return nil unless @input # anything to check ?
|
94
|
+
|
95
|
+
# do we have all parameters provided ?
|
96
|
+
check_missing_params.tap_error { |error| return error }
|
97
|
+
# ==> all params were provided
|
98
|
+
|
99
|
+
# now we shall check the content and type of the parameters
|
100
|
+
@input.each do |ksym, typ|
|
101
|
+
typ.convert_from_urlparam(v = @params[ksym.to_s])
|
102
|
+
.tap_valid do |retval|
|
103
|
+
@funcparams[ksym] = retval
|
104
|
+
end
|
105
|
+
.tap_error do
|
106
|
+
# return is really needed here, or we end up returning nil below
|
107
|
+
return parameter_convertion_error(ksym, typ, v)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
|
113
|
+
def parameter_convertion_error(param, type, val)
|
114
|
+
Safrano::ServiceOperationParameterError.new(type: type,
|
115
|
+
value: val,
|
116
|
+
param: param,
|
117
|
+
sopname: @name)
|
118
|
+
end
|
119
|
+
|
120
|
+
def add_metadata_rexml(ec)
|
121
|
+
## https://services.odata.org/V2/OData/Safrano.svc/$metadata
|
122
|
+
# <FunctionImport Name="GetProductsByRating" EntitySet="Products" ReturnType="Collection(ODataDemo.Product)" m:HttpMethod="GET">
|
123
|
+
# <Parameter Name="rating" Type="Edm.Int32" Mode="In"/>
|
124
|
+
# </FunctionImport>
|
125
|
+
funky = ec.add_element('FunctionImport',
|
126
|
+
'Name' => @name.to_s,
|
127
|
+
# EntitySet= @entity_set ,
|
128
|
+
'ReturnType' => @returning.type_metadata,
|
129
|
+
'm:HttpMethod' => @http_method)
|
130
|
+
@input.each do |iname, type|
|
131
|
+
funky.add_element('Parameter',
|
132
|
+
'Name' => iname.to_s,
|
133
|
+
'Type' => type.type_name,
|
134
|
+
'Mode' => 'In')
|
135
|
+
end if @input
|
136
|
+
funky
|
137
|
+
end
|
138
|
+
|
139
|
+
def with_validated_get(req)
|
140
|
+
# initialize_params
|
141
|
+
return yield unless (@error = check_url_func_params)
|
142
|
+
|
143
|
+
@error.odata_get(req) if @error
|
144
|
+
end
|
145
|
+
|
146
|
+
def to_odata_json(req)
|
147
|
+
result = @proc.call(**@funcparams)
|
148
|
+
@returning.to_odata_json(result, req)
|
149
|
+
end
|
150
|
+
|
151
|
+
def odata_get_output(req)
|
152
|
+
[200, EMPTY_HASH, [to_odata_json(req)]]
|
153
|
+
end
|
154
|
+
|
155
|
+
def odata_get(req)
|
156
|
+
@params = req.params
|
157
|
+
|
158
|
+
with_validated_get(req) do
|
159
|
+
odata_get_output(req)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def transition_end(_match_result)
|
164
|
+
Transition::RESULT_END
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|