Class: Graphiti::Query
Defined Under Namespace
Classes: RemoteSideloadResource
Constant Summary
collapse
- LINKLESS_FORMATS =
[:json, :xml, "json", "xml"].freeze
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
#initialize(resource, params, *positional, association_name: nil, nested_include: nil, parents: [], action: nil) ⇒ Query
Returns a new instance of Query.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
# File 'lib/graphiti/query.rb', line 9
def initialize(resource, params, *positional, association_name: nil, nested_include: nil, parents: [], action: nil)
if positional.any?
Graphiti::DEPRECATOR.warn("Passing Query.new trailing arguments positionally is deprecated. Use association_name:/nested_include:/parents:/action: keywords.")
association_name ||= positional[0]
nested_include ||= positional[1]
parents = positional[2] if positional.length > 2
action ||= positional[3]
end
@resource = resource
@association_name = association_name
@params = params
@params = @params.permit! if @params.respond_to?(:permit!)
@params = @params.to_h if @params.respond_to?(:to_h)
@params = @params.deep_symbolize_keys
@include_param = nested_include || @params[:include]
@parents = parents
@action = parse_action(action)
@entity_map = Concurrent::Map.new if parents.empty?
@association_owners = Concurrent::Map.new if parents.empty?
@public_id_maps = Concurrent::Map.new if parents.empty?
end
|
Instance Attribute Details
Returns the value of attribute action.
7
8
9
|
# File 'lib/graphiti/query.rb', line 7
def action
@action
end
|
#association_name ⇒ Object
Returns the value of attribute association_name.
7
8
9
|
# File 'lib/graphiti/query.rb', line 7
def association_name
@association_name
end
|
Returns the value of attribute params.
7
8
9
|
# File 'lib/graphiti/query.rb', line 7
def params
@params
end
|
Returns the value of attribute resource.
7
8
9
|
# File 'lib/graphiti/query.rb', line 7
def resource
@resource
end
|
Instance Method Details
#association? ⇒ Boolean
32
33
34
|
# File 'lib/graphiti/query.rb', line 32
def association?
!!@association_name
end
|
#association_owners ⇒ Object
43
44
45
46
47
|
# File 'lib/graphiti/query.rb', line 43
def association_owners
return root.association_owners unless root == self
@association_owners
end
|
#cache_key ⇒ Object
318
319
320
|
# File 'lib/graphiti/query.rb', line 318
def cache_key
"args-#{query_cache_key}"
end
|
#debug_requested? ⇒ Boolean
119
120
121
|
# File 'lib/graphiti/query.rb', line 119
def debug_requested?
Types.flag(@params[:debug])
end
|
#entity_map ⇒ Object
Concurrent::Map because sideload scopes resolve on pool threads
37
38
39
40
41
|
# File 'lib/graphiti/query.rb', line 37
def entity_map
return root.entity_map unless root == self
@entity_map
end
|
214
215
216
|
# File 'lib/graphiti/query.rb', line 214
def
@extra_fields ||= parse_fieldset(@params[:extra_fields] || {})
end
|
204
205
206
207
208
209
210
211
212
|
# File 'lib/graphiti/query.rb', line 204
def fields
@fields ||= begin
hash = parse_fieldset(@params[:fields] || {})
hash.each_pair do |type, fields|
hash[type] += [type] if [type]
end
hash
end
end
|
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
# File 'lib/graphiti/query.rb', line 218
def filters
@filters ||= {}.tap do |hash|
(@params[:filter] || {}).each_pair do |name, value|
name = name.to_sym
if legacy_nested?(name)
value.keys.each do |key|
filter_name = key.to_sym
filter_value = value[key]
if @resource.get_attr!(filter_name, :filterable, request: true)
hash[filter_name] = filter_value
end
end
elsif nested?(name)
name = name.to_s.split(".").last.to_sym
validate!(name, :filterable)
hash[name] = value
elsif top_level? && validate!(name, :filterable)
hash[name] = value
end
end
end
end
|
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
# File 'lib/graphiti/query.rb', line 123
def hash
@hash ||= {}.tap do |h|
h[:filter] = filters
h[:sort] = sorts
h[:page] =
if association?
resource_type = @resource.class.type
h[:extra_fields] = {resource_type => [resource_type]} if .key?(resource_type)
else
h[:fields] = fields
h[:extra_fields] =
end
h[:stats] = stats
h[:include] = sideload_hash
end.reject { |_, value| value.empty? }
end
|
#include_hash ⇒ Object
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
|
# File 'lib/graphiti/query.rb', line 282
def include_hash
@include_hash ||= begin
requested = include_directive.to_hash
allowlist = nil
if @resource.context&.respond_to?(:sideload_allowlist)
allowlist = @resource.context.sideload_allowlist
allowlist = allowlist[@resource.current_action] if allowlist
end
scrubbed = allowlist ? Util::IncludeParams.scrub(requested, allowlist) : requested
scrubbed.filter do |key, value|
sideload = @resource.class.sideload(key)
sideload.nil? || sideload.readable?
end
end
end
|
#includes_requested? ⇒ Boolean
82
83
84
|
# File 'lib/graphiti/query.rb', line 82
def includes_requested?
@include_param.present?
end
|
#links_requested? ⇒ Boolean
86
87
88
89
90
|
# File 'lib/graphiti/query.rb', line 86
def links_requested?
return @links_requested if defined?(@links_requested)
@links_requested = Types.flag(@params[:links])
end
|
#page_links? ⇒ Boolean
Also known as:
104
105
106
107
108
109
110
111
112
|
# File 'lib/graphiti/query.rb', line 104
def page_links?
if action == :find
false
elsif @resource.page_links == :on_demand
page_links_requested?
else
@resource.page_links
end
end
|
#page_links_requested? ⇒ Boolean
114
115
116
117
|
# File 'lib/graphiti/query.rb', line 114
def page_links_requested?
[@params[:page_links], @params[:pagination_links]]
.any? { |value| Types.flag(value) }
end
|
#paginate? ⇒ Boolean
314
315
316
|
# File 'lib/graphiti/query.rb', line 314
def paginate?
![false, "false"].include?(@params[:paginate])
end
|
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
|
# File 'lib/graphiti/query.rb', line 265
def
@pagination ||= {}.tap do |hash|
(@params[:page] || {}).each_pair do |name, value|
if legacy_nested?(name)
value.each_pair do |k, v|
hash[k.to_sym] = cast_page_param(k.to_sym, v)
end
elsif nested?(name)
param_name = name.to_s.split(".").last.to_sym
hash[param_name] = cast_page_param(param_name, value)
elsif top_level? && Scoping::Paginate::PARAMS.include?(name.to_sym)
hash[name.to_sym] = cast_page_param(name.to_sym, value)
end
end
end
end
|
196
197
198
|
# File 'lib/graphiti/query.rb', line 196
def parents
@parents ||= []
end
|
#public_id_maps ⇒ Object
49
50
51
52
53
|
# File 'lib/graphiti/query.rb', line 49
def public_id_maps
return root.public_id_maps unless root == self
@public_id_maps
end
|
#render_link?(mode) ⇒ Boolean
98
99
100
101
102
|
# File 'lib/graphiti/query.rb', line 98
def render_link?(mode)
return false if suppress_links?
(mode == :on_demand) ? links_requested? : mode == true
end
|
#repeated_resource_classes ⇒ Object
Deduplication exists for a row two include paths both resolve, so a
resource class sitting at one node has nothing to collide with.
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
# File 'lib/graphiti/query.rb', line 57
def repeated_resource_classes
return root.repeated_resource_classes unless root == self
@repeated_resource_classes ||= begin
counts = Hash.new(0)
walk = [self]
while (query = walk.pop)
counts[query.resource.class] += 1
query.sideloads.each_pair do |name, sideload_query|
walk << sideload_query
sideload = query.resource.class.sideload(name)
next unless sideload.respond_to?(:children)
sideload.children.each_value { |child| counts[child.resource.class] += 2 }
end
end
counts.select { |_, count| count > 1 }.keys.to_set
end
end
|
#resource_for_sideload(sideload) ⇒ Object
159
160
161
162
163
164
165
|
# File 'lib/graphiti/query.rb', line 159
def resource_for_sideload(sideload)
if @resource.remote?
RemoteSideloadResource.new
else
sideload.resource
end
end
|
200
201
202
|
# File 'lib/graphiti/query.rb', line 200
def root
parents.first || self
end
|
#sideload_hash ⇒ Object
146
147
148
149
150
151
152
|
# File 'lib/graphiti/query.rb', line 146
def sideload_hash
@sideload_hash = {}.tap do |hash|
sideloads.each_pair do |key, value|
hash[key] = sideloads[key].hash
end
end
end
|
#sideloads ⇒ Object
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
# File 'lib/graphiti/query.rb', line 167
def sideloads
@sideloads ||= {}.tap do |hash|
include_hash.each_pair do |key, sub_hash|
sideload = @resource.class.sideload(key)
if sideload || @resource.remote?
sl_resource = resource_for_sideload(sideload)
query_parents = parents + [self]
sub_hash = sub_hash[:include] if sub_hash.key?(:include)
relationship_name = sideload ? sideload.name : key
hash[relationship_name] = Query.new sl_resource,
@params,
association_name: key,
nested_include: sub_hash,
parents: query_parents,
action: :all
else
handle_missing_sideload(key)
end
end
end
end
|
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
# File 'lib/graphiti/query.rb', line 243
def sorts
@sorts ||= begin
return @params[:sort] if @params[:sort].is_a?(Array)
return [] if @params[:sort].nil?
[].tap do |arr|
sort_hashes do |key, value, type|
if legacy_nested?(type)
unless @resource.remote?
@resource.get_attr!(key, :sortable, request: true)
end
arr << {key => value}
elsif !type && top_level? && validate!(key, :sortable)
arr << {key => value}
elsif nested?("#{type}.#{key}")
arr << {key => value}
end
end
end
end
end
|
301
302
303
304
305
306
307
308
309
310
311
312
|
# File 'lib/graphiti/query.rb', line 301
def stats
@stats ||= {}.tap do |hash|
(@params[:stats] || {}).each_pair do |k, v|
if legacy_nested?(k)
raise NotImplementedError.new("Association statistics are not currently supported")
elsif top_level?
v = v.split(",") if v.is_a?(String)
hash[k.to_sym] = Array(v).flatten.map(&:to_sym)
end
end
end
end
|
#suppress_links? ⇒ Boolean
92
93
94
95
96
|
# File 'lib/graphiti/query.rb', line 92
def suppress_links?
return @suppress_links if defined?(@suppress_links)
@suppress_links = LINKLESS_FORMATS.include?(params[:format])
end
|
#top_level? ⇒ Boolean
78
79
80
|
# File 'lib/graphiti/query.rb', line 78
def top_level?
!association?
end
|
#zero_results? ⇒ Boolean
140
141
142
143
144
|
# File 'lib/graphiti/query.rb', line 140
def zero_results?
!@params[:page].nil? &&
!@params[:page][:size].nil? &&
@params[:page][:size].to_i == 0
end
|