-
Notifications
You must be signed in to change notification settings - Fork 650
/
offdatabase_query_adapter.rb
73 lines (61 loc) · 1.78 KB
/
offdatabase_query_adapter.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# NOTE: Implement further methods from ActiveRecord::Relation here as needed
module Carto
class OffdatabaseQueryAdapter
# @param query ActiveRecord::Relation
# @param order_by_asc_or_desc_by_attribute Hash { key: value, key: value } where
# key = { String => { submodel: String|nil, attribute: String }, ... }
# value = "asc" | "desc"
def initialize(query, order_by_asc_or_desc_by_attribute)
@query = query
@order_by_asc_or_desc_by_attribute = order_by_asc_or_desc_by_attribute
@offset = 0
@limit = nil
end
def offset(offset)
@offset = offset
self
end
def limit(limit)
@limit = limit
self
end
def all
results
end
def map
results.map { |a|
yield(a)
}
end
def count
results.count
end
def size
results.size
end
def first
results.first
end
private
def results
@results ||= get_results
end
# NOTE: Sorting for model associations (which return arrays) or arrays will be done based on length
# e.g. visualization.analyses
def get_results
all = @query.all
@order_by_asc_or_desc_by_attribute.each do |attribute, asc_or_desc|
# Cache attribute type
is_array = all.present? && all.first.send(attribute).respond_to?(:each)
all = all.sort do |x, y|
x_attribute = is_array ? x.send(attribute).count : x.send(attribute)
y_attribute = is_array ? y.send(attribute).count : y.send(attribute)
x_attribute = 0 if x_attribute.nil?
y_attribute = 0 if y_attribute.nil?
asc_or_desc == "asc" ? x_attribute <=> y_attribute : y_attribute <=> x_attribute
end
end
all[@offset, @limit.nil? ? all.count : @limit]
end
end
end