safrano 0.3.3 → 0.4.3
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/odata/attribute.rb +9 -8
- data/lib/odata/batch.rb +8 -8
- data/lib/odata/collection.rb +239 -92
- data/lib/odata/collection_filter.rb +40 -9
- data/lib/odata/collection_media.rb +159 -28
- data/lib/odata/collection_order.rb +46 -36
- data/lib/odata/common_logger.rb +37 -12
- data/lib/odata/entity.rb +188 -99
- data/lib/odata/error.rb +60 -12
- data/lib/odata/expand.rb +123 -0
- data/lib/odata/filter/base.rb +66 -0
- data/lib/odata/filter/error.rb +33 -0
- data/lib/odata/filter/parse.rb +6 -12
- data/lib/odata/filter/sequel.rb +42 -29
- data/lib/odata/filter/sequel_function_adapter.rb +147 -0
- data/lib/odata/filter/token.rb +5 -1
- data/lib/odata/filter/tree.rb +45 -29
- data/lib/odata/navigation_attribute.rb +60 -27
- data/lib/odata/relations.rb +2 -2
- data/lib/odata/select.rb +42 -0
- data/lib/odata/url_parameters.rb +51 -36
- data/lib/odata/walker.rb +6 -6
- data/lib/safrano.rb +23 -13
- data/lib/{safrano_core.rb → safrano/core.rb} +12 -4
- data/lib/{multipart.rb → safrano/multipart.rb} +17 -26
- data/lib/{odata_rack_builder.rb → safrano/odata_rack_builder.rb} +0 -1
- data/lib/{rack_app.rb → safrano/rack_app.rb} +12 -10
- data/lib/{request.rb → safrano/request.rb} +8 -14
- data/lib/{response.rb → safrano/response.rb} +1 -2
- data/lib/{sequel_join_by_paths.rb → safrano/sequel_join_by_paths.rb} +1 -1
- data/lib/{service.rb → safrano/service.rb} +162 -131
- data/lib/safrano/version.rb +3 -0
- data/lib/sequel/plugins/join_by_paths.rb +11 -10
- metadata +33 -16
- data/lib/version.rb +0 -4
@@ -1,6 +1,5 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
1
|
require 'rack'
|
2
|
+
require 'rfc2047'
|
4
3
|
|
5
4
|
module OData
|
6
5
|
# monkey patch deactivate Rack/multipart because it does not work on simple
|
@@ -109,13 +108,6 @@ module OData
|
|
109
108
|
end
|
110
109
|
end
|
111
110
|
|
112
|
-
def uribase
|
113
|
-
return @uribase if @uribase
|
114
|
-
|
115
|
-
@uribase =
|
116
|
-
"#{env['rack.url_scheme']}://#{env['HTTP_HOST']}#{service.xpath_prefix}"
|
117
|
-
end
|
118
|
-
|
119
111
|
def accept?(type)
|
120
112
|
preferred_type(type).to_s.include?(type)
|
121
113
|
end
|
@@ -136,11 +128,13 @@ module OData
|
|
136
128
|
def with_media_data
|
137
129
|
if (filename = @env['HTTP_SLUG'])
|
138
130
|
|
139
|
-
yield @env['rack.input'],
|
131
|
+
yield @env['rack.input'],
|
132
|
+
content_type.split(';').first,
|
133
|
+
Rfc2047.decode(filename)
|
140
134
|
|
141
135
|
else
|
142
136
|
ON_CGST_ERROR.call(self)
|
143
|
-
|
137
|
+
[400, EMPTY_HASH, ['File upload error: Missing SLUG']]
|
144
138
|
end
|
145
139
|
end
|
146
140
|
|
@@ -151,15 +145,15 @@ module OData
|
|
151
145
|
data = JSON.parse(body.read)
|
152
146
|
rescue JSON::ParserError => e
|
153
147
|
ON_CGST_ERROR.call(self)
|
154
|
-
return [400,
|
155
|
-
|
148
|
+
return [400, EMPTY_HASH, ['JSON Parser Error while parsing payload : ',
|
149
|
+
e.message]]
|
156
150
|
end
|
157
151
|
|
158
152
|
yield data
|
159
153
|
|
160
154
|
else # TODO: other formats
|
161
155
|
|
162
|
-
[415,
|
156
|
+
[415, EMPTY_HASH, EMPTY_ARRAY]
|
163
157
|
end
|
164
158
|
end
|
165
159
|
|
@@ -1,4 +1,3 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
1
|
require 'rack'
|
3
2
|
|
4
3
|
# monkey patch deactivate Rack/multipart because it does not work on simple
|
@@ -35,7 +34,7 @@ module OData
|
|
35
34
|
|
36
35
|
if drop_body?
|
37
36
|
close
|
38
|
-
result =
|
37
|
+
result = EMPTY_ARRAY
|
39
38
|
end
|
40
39
|
|
41
40
|
if calculate_content_length?
|
@@ -1,17 +1,19 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
1
|
require 'rexml/document'
|
4
2
|
require 'odata/relations.rb'
|
5
3
|
require 'odata/batch.rb'
|
6
4
|
require 'odata/error.rb'
|
5
|
+
require 'odata/filter/sequel.rb'
|
7
6
|
|
8
7
|
module OData
|
9
8
|
# this module has all methods related to expand/defered output preparation
|
10
9
|
# and will be included in Service class
|
11
10
|
module ExpandHandler
|
12
11
|
PATH_SPLITTER = %r{\A(\w+)\/?(.*)\z}.freeze
|
13
|
-
|
14
|
-
|
12
|
+
DEFERRED = '__deferred'.freeze
|
13
|
+
URI = 'uri'.freeze
|
14
|
+
|
15
|
+
def get_deferred_odata_h(entity_uri:, attrib:)
|
16
|
+
{ DEFERRED => { URI => "#{entity_uri}/#{attrib}" } }
|
15
17
|
end
|
16
18
|
|
17
19
|
# split expand argument into first and rest part
|
@@ -23,109 +25,75 @@ module OData
|
|
23
25
|
# TODO: check errorhandling
|
24
26
|
raise OData::ServerError if cur_exp.nil?
|
25
27
|
|
26
|
-
|
28
|
+
k_s = cur_exp
|
29
|
+
|
27
30
|
else
|
28
|
-
|
31
|
+
k_s = exp_one.strip
|
29
32
|
rest_exp = nil
|
30
33
|
end
|
31
|
-
|
34
|
+
k = k_s.to_sym
|
35
|
+
yield k, k_s, rest_exp
|
32
36
|
end
|
33
37
|
|
34
38
|
# default v2
|
35
39
|
# overriden in ServiceV1
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
RESULTS_K = 'results'.freeze
|
41
|
+
COUNT_K = '__count'.freeze
|
42
|
+
def get_coll_odata_h(array:, template:, icount: nil)
|
43
|
+
array.map! do |w|
|
44
|
+
get_entity_odata_h(entity: w, template: template)
|
41
45
|
end
|
42
46
|
if icount
|
43
|
-
{
|
47
|
+
{ RESULTS_K => array, COUNT_K => icount }
|
44
48
|
else
|
45
|
-
{
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# handle a single expand
|
50
|
-
def handle_entity_expand_one(entity:, exp_one:, nav_values_h:, nav_coll_h:,
|
51
|
-
uribase:)
|
52
|
-
|
53
|
-
split_entity_expand_arg(exp_one) do |first, rest_exp|
|
54
|
-
if (enval = entity.nav_values[first])
|
55
|
-
nav_values_h[first.to_s] = get_entity_odata_h(entity: enval,
|
56
|
-
expand: rest_exp,
|
57
|
-
uribase: uribase)
|
58
|
-
elsif (encoll = entity.nav_coll[first])
|
59
|
-
# nav attributes that are a collection (x..n)
|
60
|
-
nav_coll_h[first.to_s] = get_coll_odata_h(array: encoll,
|
61
|
-
expand: rest_exp,
|
62
|
-
uribase: uribase)
|
63
|
-
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def handle_entity_expand(entity:, expand:, nav_values_h:,
|
69
|
-
nav_coll_h:, uribase:)
|
70
|
-
expand.strip!
|
71
|
-
explist = expand.split(',')
|
72
|
-
# handle multiple expands
|
73
|
-
explist.each do |exp|
|
74
|
-
handle_entity_expand_one(entity: entity, exp_one: exp,
|
75
|
-
nav_values_h: nav_values_h,
|
76
|
-
nav_coll_h: nav_coll_h,
|
77
|
-
uribase: uribase)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def handle_entity_deferred_attribs(entity:, nav_values_h:,
|
82
|
-
nav_coll_h:, uribase:)
|
83
|
-
entity.nav_values.each_key do |ksy|
|
84
|
-
ks = ksy.to_s
|
85
|
-
next if nav_values_h.key?(ks)
|
86
|
-
|
87
|
-
nav_values_h[ks] = get_deferred_odata_h(entity: entity,
|
88
|
-
attrib: ks, uribase: uribase)
|
89
|
-
end
|
90
|
-
entity.nav_coll.each_key do |ksy|
|
91
|
-
ks = ksy.to_s
|
92
|
-
next if nav_coll_h.key?(ks)
|
93
|
-
|
94
|
-
nav_coll_h[ks] = get_deferred_odata_h(entity: entity, attrib: ks,
|
95
|
-
uribase: uribase)
|
49
|
+
{ RESULTS_K => array }
|
96
50
|
end
|
97
51
|
end
|
98
52
|
|
99
53
|
# handle $links ... Note: $expand seems to be ignored when $links
|
100
54
|
# are requested
|
101
|
-
def get_entity_odata_link_h(entity
|
102
|
-
{ uri: entity.uri
|
103
|
-
end
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
55
|
+
def get_entity_odata_link_h(entity:)
|
56
|
+
{ uri: entity.uri }
|
57
|
+
end
|
58
|
+
|
59
|
+
EMPTYH = {}.freeze
|
60
|
+
METADATA_K = '__metadata'.freeze
|
61
|
+
def get_entity_odata_h(entity:, template:)
|
62
|
+
# start with metadata
|
63
|
+
hres = { METADATA_K => entity.metadata_h }
|
64
|
+
|
65
|
+
template.each do |elmt, arg|
|
66
|
+
case elmt
|
67
|
+
when :all_values
|
68
|
+
hres.merge! entity.casted_values
|
69
|
+
when :selected_vals
|
70
|
+
hres.merge! entity.casted_values(arg)
|
71
|
+
when :expand_e
|
72
|
+
|
73
|
+
arg.each do |attr, templ|
|
74
|
+
enval = entity.send(attr)
|
75
|
+
hres[attr] = if enval
|
76
|
+
get_entity_odata_h(entity: enval, template: templ)
|
77
|
+
else
|
78
|
+
# FK is NULL --> nav_value is nil --> return empty json
|
79
|
+
EMPTYH
|
80
|
+
end
|
81
|
+
end
|
82
|
+
when :expand_c
|
83
|
+
arg.each do |attr, templ|
|
84
|
+
next unless (encoll = entity.send(attr))
|
111
85
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
86
|
+
# nav attributes that are a collection (x..n)
|
87
|
+
hres[attr] = get_coll_odata_h(array: encoll, template: templ)
|
88
|
+
# else error ?
|
89
|
+
end
|
90
|
+
when :deferr
|
91
|
+
euri = entity.uri
|
92
|
+
arg.each do |attr|
|
93
|
+
hres[attr] = get_deferred_odata_h(entity_uri: euri, attrib: attr)
|
94
|
+
end
|
95
|
+
end
|
118
96
|
end
|
119
|
-
|
120
|
-
# handle not expanded (deferred) nav attributes
|
121
|
-
handle_entity_deferred_attribs(entity: entity,
|
122
|
-
nav_values_h: nav_values_h,
|
123
|
-
nav_coll_h: nav_coll_h,
|
124
|
-
uribase: uribase)
|
125
|
-
# merge ...
|
126
|
-
hres.merge!(nav_values_h)
|
127
|
-
hres.merge!(nav_coll_h)
|
128
|
-
|
129
97
|
hres
|
130
98
|
end
|
131
99
|
end
|
@@ -175,7 +143,8 @@ module OData
|
|
175
143
|
attr_accessor :xname
|
176
144
|
attr_accessor :xnamespace
|
177
145
|
attr_accessor :xpath_prefix
|
178
|
-
|
146
|
+
attr_accessor :xserver_url
|
147
|
+
attr_accessor :uribase
|
179
148
|
attr_accessor :meta
|
180
149
|
attr_accessor :batch_handler
|
181
150
|
attr_accessor :relman
|
@@ -200,7 +169,8 @@ module OData
|
|
200
169
|
|
201
170
|
DATASERVICEVERSION_RGX = /\A([1234])(?:\.0);*\w*\z/.freeze
|
202
171
|
TRAILING_SLASH = %r{/\z}.freeze
|
203
|
-
DEFAULT_PATH_PREFIX = '/'
|
172
|
+
DEFAULT_PATH_PREFIX = '/'.freeze
|
173
|
+
DEFAULT_SERVER_URL = 'http://localhost:9494'
|
204
174
|
|
205
175
|
# input is the DataServiceVersion request header string, eg.
|
206
176
|
# '2.0;blabla' ---> Version -> 2
|
@@ -243,40 +213,67 @@ module OData
|
|
243
213
|
(@v1.xpath_prefix = @xpath_prefix) if @v1
|
244
214
|
(@v2.xpath_prefix = @xpath_prefix) if @v2
|
245
215
|
end
|
216
|
+
|
217
|
+
def server_url(surl)
|
218
|
+
@xserver_url = surl.sub(TRAILING_SLASH, '')
|
219
|
+
(@v1.xserver_url = @xserver_url) if @v1
|
220
|
+
(@v2.xserver_url = @xserver_url) if @v2
|
221
|
+
end
|
222
|
+
|
246
223
|
# end public API
|
247
224
|
|
225
|
+
def set_uribase
|
226
|
+
@uribase = if @xpath_prefix.empty?
|
227
|
+
@xserver_url
|
228
|
+
else
|
229
|
+
if @xpath_prefix[0] == '/'
|
230
|
+
@xserver_url + @xpath_prefix
|
231
|
+
else
|
232
|
+
@xserver_url + '/' + @xpath_prefix
|
233
|
+
end
|
234
|
+
end
|
235
|
+
(@v1.uribase = @uribase) if @v1
|
236
|
+
(@v2.uribase = @uribase) if @v2
|
237
|
+
end
|
238
|
+
|
248
239
|
def copy_attribs_to(other)
|
249
240
|
other.cmap = @cmap
|
250
241
|
other.collections = @collections
|
242
|
+
other.allowed_transitions = @allowed_transitions
|
251
243
|
other.xtitle = @xtitle
|
252
244
|
other.xname = @xname
|
253
245
|
other.xnamespace = @xnamespace
|
254
246
|
other.xpath_prefix = @xpath_prefix
|
247
|
+
other.xserver_url = @xserver_url
|
248
|
+
other.uribase = @uribase
|
255
249
|
other.meta = ServiceMeta.new(other) # hum ... #todo: versions as well ?
|
256
250
|
other.relman = @relman
|
257
251
|
other.batch_handler = @batch_handler
|
258
252
|
other
|
259
253
|
end
|
260
254
|
|
255
|
+
# this is a central place. We extend Sequel models with OData functionality
|
256
|
+
# The included/extended modules depends on the properties(eg, pks, field types) of the model
|
257
|
+
# we differentiate
|
258
|
+
# * Single/Multi PK
|
259
|
+
# * Media/Non-Media entity
|
260
|
+
# Putting this logic here in modules loaded once on start shall result in less runtime overhead
|
261
261
|
def register_model(modelklass, entity_set_name = nil, is_media = false)
|
262
262
|
# check that the provided klass is a Sequel Model
|
263
|
-
|
264
|
-
|
265
|
-
end
|
263
|
+
|
264
|
+
raise(OData::API::ModelNameError, modelklass) unless modelklass.is_a? Sequel::Model::ClassMethods
|
266
265
|
|
267
266
|
if modelklass.ancestors.include? OData::Entity
|
268
267
|
# modules were already added previously;
|
269
268
|
# cleanup state to avoid having data from previous calls
|
270
269
|
# mostly usefull for testing (eg API)
|
271
270
|
modelklass.reset
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
modelklass.include OData::EntitySinglePK
|
279
|
-
end
|
271
|
+
elsif modelklass.primary_key.is_a?(Array) # first API call... (normal non-testing case)
|
272
|
+
modelklass.extend OData::EntityClassMultiPK
|
273
|
+
modelklass.include OData::EntityMultiPK
|
274
|
+
else
|
275
|
+
modelklass.extend OData::EntityClassSinglePK
|
276
|
+
modelklass.include OData::EntitySinglePK
|
280
277
|
end
|
281
278
|
# Media/Non-media
|
282
279
|
if is_media
|
@@ -326,15 +323,14 @@ module OData
|
|
326
323
|
# example: CrewMember must be matched before Crew otherwise we get error
|
327
324
|
def set_collections_sorted(coll_data)
|
328
325
|
@collections = coll_data
|
329
|
-
if @collections
|
330
|
-
@collections.sort_by! { |klass| klass.entity_set_name.size }.reverse!
|
331
|
-
end
|
326
|
+
@collections.sort_by! { |klass| klass.entity_set_name.size }.reverse! if @collections
|
332
327
|
@collections
|
333
328
|
end
|
334
329
|
|
335
330
|
# to be called at end of publishing block to ensure we get the right names
|
336
331
|
# and additionally build the list of valid attribute path's used
|
337
332
|
# for validation of $orderby or $filter params
|
333
|
+
|
338
334
|
def finalize_publishing
|
339
335
|
# build the cmap
|
340
336
|
@cmap = {}
|
@@ -348,8 +344,36 @@ module OData
|
|
348
344
|
# set default path prefix if path_prefix was not called
|
349
345
|
path_prefix(DEFAULT_PATH_PREFIX) unless @xpath_prefix
|
350
346
|
|
351
|
-
#
|
352
|
-
|
347
|
+
# set default server url if server_url was not called
|
348
|
+
server_url(DEFAULT_SERVER_URL) unless @xserver_url
|
349
|
+
|
350
|
+
set_uribase
|
351
|
+
|
352
|
+
@collections.each(&:finalize_publishing)
|
353
|
+
|
354
|
+
# finalize the uri's and include NoMappingBeforeOutput or MappingBeforeOutput as needed
|
355
|
+
@collections.each { |klass|
|
356
|
+
klass.build_uri(@uribase)
|
357
|
+
if klass.time_cols.empty?
|
358
|
+
klass.include OData::NoMappingBeforeOutput
|
359
|
+
else
|
360
|
+
klass.include OData::MappingBeforeOutput
|
361
|
+
end
|
362
|
+
}
|
363
|
+
|
364
|
+
# build allowed transitions (requires that @collections are filled and sorted for having a
|
365
|
+
# correct base_url_regexp)
|
366
|
+
build_allowed_transitions
|
367
|
+
|
368
|
+
# mixin adapter specific modules where needed
|
369
|
+
case Sequel::Model.db.adapter_scheme
|
370
|
+
when :postgres
|
371
|
+
OData::Filter::FuncTree.include OData::Filter::FuncTreePostgres
|
372
|
+
when :sqlite
|
373
|
+
OData::Filter::FuncTree.include OData::Filter::FuncTreeSqlite
|
374
|
+
else
|
375
|
+
OData::Filter::FuncTree.include OData::Filter::FuncTreeDefault
|
376
|
+
end
|
353
377
|
end
|
354
378
|
|
355
379
|
def execute_deferred_iblocks
|
@@ -374,7 +398,7 @@ module OData
|
|
374
398
|
def service_xml(req)
|
375
399
|
doc = REXML::Document.new
|
376
400
|
# separator required ? ?
|
377
|
-
root = doc.add_element('service', 'xml:base' =>
|
401
|
+
root = doc.add_element('service', 'xml:base' => @uribase)
|
378
402
|
|
379
403
|
root.add_namespace('xmlns:atom', XMLNS::W3_2005_ATOM)
|
380
404
|
root.add_namespace('xmlns:app', XMLNS::W3_2007_APP)
|
@@ -397,7 +421,7 @@ module OData
|
|
397
421
|
def add_metadata_xml_entity_type(schema)
|
398
422
|
@collections.each do |klass|
|
399
423
|
enty = klass.add_metadata_rexml(schema)
|
400
|
-
klass.add_metadata_navs_rexml(enty, @
|
424
|
+
klass.add_metadata_navs_rexml(enty, @relman, @xnamespace)
|
401
425
|
end
|
402
426
|
end
|
403
427
|
|
@@ -485,15 +509,22 @@ module OData
|
|
485
509
|
# methods related to transitions to next state (cf. walker)
|
486
510
|
module Transitions
|
487
511
|
DOLLAR_ID_REGEXP = Regexp.new('\A\/\$').freeze
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
512
|
+
ALLOWED_TRANSITIONS_FIXED = [
|
513
|
+
Safrano::TransitionEnd,
|
514
|
+
Safrano::TransitionMetadata,
|
515
|
+
Safrano::TransitionBatch,
|
516
|
+
Safrano::TransitionContentId
|
517
|
+
].freeze
|
518
|
+
|
519
|
+
def build_allowed_transitions
|
520
|
+
@allowed_transitions = (ALLOWED_TRANSITIONS_FIXED + [
|
494
521
|
Safrano::Transition.new(%r{\A/(#{base_url_regexp})(.*)},
|
495
522
|
trans: 'transition_collection')
|
496
|
-
]
|
523
|
+
]).freeze
|
524
|
+
end
|
525
|
+
|
526
|
+
def allowed_transitions
|
527
|
+
@allowed_transitions
|
497
528
|
end
|
498
529
|
|
499
530
|
def transition_collection(match_result)
|
@@ -540,22 +571,22 @@ module OData
|
|
540
571
|
@data_service_version = '1.0'
|
541
572
|
end
|
542
573
|
|
543
|
-
def get_coll_odata_links_h(array:,
|
574
|
+
def get_coll_odata_links_h(array:, icount: nil)
|
544
575
|
array.map do |w|
|
545
|
-
get_entity_odata_link_h(entity: w
|
576
|
+
get_entity_odata_link_h(entity: w)
|
546
577
|
end
|
547
578
|
end
|
548
579
|
|
549
|
-
def get_coll_odata_h(array:,
|
550
|
-
array.map do |w|
|
580
|
+
def get_coll_odata_h(array:, template:, icount: nil)
|
581
|
+
array.map! do |w|
|
551
582
|
get_entity_odata_h(entity: w,
|
552
|
-
|
553
|
-
uribase: uribase)
|
583
|
+
template: template)
|
554
584
|
end
|
585
|
+
array
|
555
586
|
end
|
556
587
|
|
557
588
|
def get_emptycoll_odata_h
|
558
|
-
|
589
|
+
EMPTY_HASH_IN_ARY
|
559
590
|
end
|
560
591
|
end
|
561
592
|
|
@@ -565,19 +596,19 @@ module OData
|
|
565
596
|
@data_service_version = '2.0'
|
566
597
|
end
|
567
598
|
|
568
|
-
def get_coll_odata_links_h(array:,
|
599
|
+
def get_coll_odata_links_h(array:, icount: nil)
|
569
600
|
res = array.map do |w|
|
570
|
-
get_entity_odata_link_h(entity: w
|
601
|
+
get_entity_odata_link_h(entity: w)
|
571
602
|
end
|
572
603
|
if icount
|
573
|
-
{
|
604
|
+
{ RESULTS_K => res, COUNT_K => icount }
|
574
605
|
else
|
575
|
-
{
|
606
|
+
{ RESULTS_K => res }
|
576
607
|
end
|
577
608
|
end
|
578
609
|
|
579
610
|
def get_emptycoll_odata_h
|
580
|
-
{
|
611
|
+
{ RESULTS_K => EMPTY_HASH_IN_ARY }
|
581
612
|
end
|
582
613
|
end
|
583
614
|
|
@@ -588,9 +619,9 @@ module OData
|
|
588
619
|
@service = service
|
589
620
|
end
|
590
621
|
|
622
|
+
ALLOWED_TRANSITIONS_FIXED = [Safrano::TransitionEnd].freeze
|
591
623
|
def allowed_transitions
|
592
|
-
|
593
|
-
trans: 'transition_end')]
|
624
|
+
ALLOWED_TRANSITIONS_FIXED
|
594
625
|
end
|
595
626
|
|
596
627
|
def transition_end(_match_result)
|