Class: APIQL
- Inherits:
-
Object
show all
- Extended by:
- CRUD
- Defined in:
- lib/apiql.rb
Defined Under Namespace
Modules: CRUD, Rails
Classes: CacheMissed, Context, Entity, Error, HashEntity
Constant Summary
collapse
- @@cache =
{}
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from CRUD
model
Constructor Details
#initialize(binder, *fields) ⇒ APIQL
Returns a new instance of APIQL.
239
240
241
242
|
# File 'lib/apiql.rb', line 239
def initialize(binder, *fields)
@context = ::APIQL::Context.new(binder, *fields)
@context.inject_delegators(self)
end
|
Instance Attribute Details
#context ⇒ Object
Returns the value of attribute context.
83
84
85
|
# File 'lib/apiql.rb', line 83
def context
@context
end
|
Class Method Details
.cache(params) ⇒ Object
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# File 'lib/apiql.rb', line 103
def cache(params)
request_id = params[:apiql]
request = params[:apiql_request]
if request.present?
request = compile(request)
redis&.set("api-ql-cache-#{request_id}", request.to_json)
@@cache = {} if @@cache.count > 1000
@@cache[request_id] = request
else
request = @@cache[request_id]
request ||= JSON.parse(redis.get("api-ql-cache-#{request_id}")) rescue nil
raise CacheMissed unless request.present? && request.is_a?(::Array)
end
request
end
|
.eager_loads(schema) ⇒ Object
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
# File 'lib/apiql.rb', line 129
def eager_loads(schema)
result = []
schema&.each do |call|
if call.is_a? Hash
call.each do |function, sub_schema|
next if function.include? '('
function = function.split(':').last.strip if function.include? ':'
function = function.split('.').first if function.include? '.'
sub = eager_loads(sub_schema)
if sub.present?
result.push(function => sub)
else
result.push function
end
end
end
end
result
end
|
.mount(klass, as: nil) ⇒ Object
89
90
91
92
93
94
95
96
97
98
99
|
# File 'lib/apiql.rb', line 89
def mount(klass, as: nil)
as ||= klass.name.split('::').last.underscore
as += '.' if as.present?
klass.instance_methods(false).each do |method|
klass.alias_method("#{as}#{method}", method)
klass.remove_method(method) if as.present?
end
include klass
end
|
.simple_class?(value) ⇒ Boolean
121
122
123
124
125
126
127
|
# File 'lib/apiql.rb', line 121
def simple_class?(value)
value.nil? ||
value.is_a?(TrueClass) || value.is_a?(FalseClass) ||
value.is_a?(Symbol) || value.is_a?(String) ||
value.is_a?(Integer) || value.is_a?(Float) || value.is_a?(BigDecimal) ||
value.is_a?(Hash)
end
|
Instance Method Details
#eager_load ⇒ Object
244
245
246
247
248
249
250
|
# File 'lib/apiql.rb', line 244
def eager_load
result = @eager_load
@eager_load = []
result
end
|
#render(schema) ⇒ Object
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
|
# File 'lib/apiql.rb', line 252
def render(schema)
result = {}
schema.map do |call|
if call.is_a? ::Hash
call.each do |function, sub_schema|
reg = function.match(/\A((?<alias>[\w\.]+):\s*)?(?<name>[\w\.]+)(\((?<params>.*?)\))?\z/)
raise Error, function unless reg.present?
name = reg[:alias] || reg[:name]
function = reg[:name]
params = @context.parse_params(reg[:params].presence)
@eager_load = APIQL::eager_loads(sub_schema)
data = public_send(function, *params)
if @eager_load.present? && !data.is_a?(::Hash) && !data.is_a?(::Array)
if data.respond_to?(:eager_load)
data = data.eager_load(eager_load)
elsif data.respond_to?(:id)
data = data.class.eager_load(eager_load).find(data.id)
end
end
if result[name].is_a? ::Hash
result = result.deep_merge({
name => @context.render_value(data, sub_schema)
})
else
result[name] = @context.render_value(data, sub_schema)
end
end
else
reg = call.match(/\A((?<alias>[\w\.]+):\s*)?(?<name>[\w\.]+)(\((?<params>.*?)\))?\z/)
raise Error, call unless reg.present?
name = reg[:alias] || reg[:name]
function = reg[:name]
params = @context.parse_params(reg[:params].presence)
@eager_load = []
data = public_send(function, *params)
if data.is_a? Array
if data.any? { |item| !APIQL::simple_class?(item) }
data = nil
end
elsif !APIQL::simple_class?(data)
data = nil
end
if result[name].is_a? ::Hash
result = result.deep_merge({
name => data
})
else
result[name] = data
end
end
end
result
end
|