Class: Safrano::OData::Collection

Inherits:
Object
  • Object
show all
Includes:
Transitions::GetNextTrans::ByLongestMatch
Defined in:
lib/odata/collection.rb

Direct Known Subclasses

NavigatedCollection

Constant Summary collapse

D =
'd'
DJ_OPEN =
'{"d":'
DJ_CLOSE =
'}'
EMPTYH =
{}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Transitions::GetNextTrans::ByLongestMatch

#get_next_transresult

Constructor Details

#initialize(modelk) ⇒ Collection

Returns a new instance of Collection.



21
22
23
24
# File 'lib/odata/collection.rb', line 21

def initialize(modelk)
  @modelk = modelk
  @allowed_transitions = @modelk.allowed_transitions
end

Instance Attribute Details

#cxObject

Returns the value of attribute cx.



8
9
10
# File 'lib/odata/collection.rb', line 8

def cx
  @cx
end

#inlinecountObject (readonly)

Returns the value of attribute inlinecount.



17
18
19
# File 'lib/odata/collection.rb', line 17

def inlinecount
  @inlinecount
end

#modelkObject (readonly)

Returns the value of attribute modelk.



19
20
21
# File 'lib/odata/collection.rb', line 19

def modelk
  @modelk
end

#paramsObject (readonly)

url params



11
12
13
# File 'lib/odata/collection.rb', line 11

def params
  @params
end

#uparmsObject (readonly)

url parameters processing object (mostly convert to sequel exprs). exposed for testing only



15
16
17
# File 'lib/odata/collection.rb', line 15

def uparms
  @uparms
end

Instance Method Details

#allowed_transitionsObject



26
27
28
# File 'lib/odata/collection.rb', line 26

def allowed_transitions
  @modelk.allowed_transitions
end

#datasetObject

this is redefined in NavigatedCollection



40
41
42
# File 'lib/odata/collection.rb', line 40

def dataset
  @modelk.dataset
end

#find_by_odata_key(pkid) ⇒ Object

pkid can be a single value for single-pk models, or an array. type checking/convertion is done in check_odata_key_type



60
61
62
63
# File 'lib/odata/collection.rb', line 60

def find_by_odata_key(pkid)
  lkup = @modelk.pk_lookup_expr(pkid)
  dataset[lkup]
end

#initialize_dataset(dtset = nil) ⇒ Object



65
66
67
# File 'lib/odata/collection.rb', line 65

def initialize_dataset(dtset = nil)
  @cx = @cx || dtset || @modelk
end

#initialize_uparmsObject



69
70
71
# File 'lib/odata/collection.rb', line 69

def initialize_uparms
  @uparms = UrlParameters4Coll.new(@cx, @params)
end

#odata_get(req) ⇒ Object

on model class level we return the collection



139
140
141
142
143
144
145
146
147
148
# File 'lib/odata/collection.rb', line 139

def odata_get(req)
  @params ||= req.params
  initialize_dataset
  initialize_uparms
  @uparms.check_all.if_valid do |_ret|
    odata_get_apply_params.if_valid do |_ret|
      odata_get_output(req)
    end
  end.tap_error { |e| return e.odata_get(req) }.result
end

#odata_get_apply_paramsObject



73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/odata/collection.rb', line 73

def odata_get_apply_params
  @uparms.apply_to_dataset(@cx).map_result! do |dataset|
    @cx = dataset
    odata_get_inlinecount_w_sequel
    if (skipp = @params['$skip'])
      @cx = @cx.offset(skipp) if skipp != '0'
    end
    @cx = @cx.limit(@params['$top']) if @params['$top']

    @cx
  end
end

#odata_get_inlinecount_w_sequelObject



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/odata/collection.rb', line 109

def odata_get_inlinecount_w_sequel
  return unless (icp = @params['$inlinecount'])

  @inlinecount = if icp == 'allpages'
                   if @modelk.is_a? Sequel::Model::ClassMethods
                     @cx.count
                   else
                     @cx.dataset.count
                   end
                 end
end

#odata_get_output(req) ⇒ Object

finally return the requested output according to format, options etc



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/odata/collection.rb', line 122

def odata_get_output(req)
  output = if req.walker.do_count
             [200, CT_TEXT, @cx.count.to_s]
           elsif req.accept?(APPJSON)
             # json is default content type so we dont need to specify it here again
             if req.walker.do_links
               [200, EMPTYH, [to_odata_links_json(service: req.service)]]
             else
               [200, EMPTYH, [to_odata_json(request: req)]]
             end
           else # TODO: other formats
             406
           end
  Contract.valid(output)
end

#odata_post(req) ⇒ Object



150
151
152
# File 'lib/odata/collection.rb', line 150

def odata_post(req)
  @modelk.odata_create_entity_and_relation(req)
end

#to_odata_json(request:) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/odata/collection.rb', line 91

def to_odata_json(request:)
  template = @modelk.output_template(expand_list: @uparms.expand.template,
                                     select: @uparms.select)
  # TODO: Error handling if database contains binary BLOB data that cant be
  # interpreted as UTF-8 then JSON will fail here
  innerj = request.service.get_coll_odata_h(array: @cx.all,
                                            template: template,
                                            icount: @inlinecount).to_json

  "#{DJ_OPEN}#{innerj}#{DJ_CLOSE}"
end


103
104
105
106
107
# File 'lib/odata/collection.rb', line 103

def to_odata_links_json(service:)
  innerj = service.get_coll_odata_links_h(array: @cx.all,
                                          icount: @inlinecount).to_json
  "#{DJ_OPEN}#{innerj}#{DJ_CLOSE}"
end

#transition_count(_match_result) ⇒ Object



34
35
36
# File 'lib/odata/collection.rb', line 34

def transition_count(_match_result)
  [self, :end_with_count]
end

#transition_end(_match_result) ⇒ Object



30
31
32
# File 'lib/odata/collection.rb', line 30

def transition_end(_match_result)
  Safrano::Transition::RESULT_END
end

#transition_id(match_result) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/odata/collection.rb', line 44

def transition_id(match_result)
  if (rawid = match_result[1])
    @modelk.parse_odata_key(rawid).tap_error do
      return Safrano::Transition::RESULT_BAD_REQ_ERR
    end.if_valid do |casted_id|
      (y = find_by_odata_key(casted_id)) ? [y, :run] : Safrano::Transition::RESULT_NOT_FOUND_ERR
    end
  else
    Safrano::Transition::RESULT_SERVER_TR_ERR
  end
end