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
|
# File 'lib/snaptime/harvester.rb', line 3
def self.harvest_for(record)
selects = []
queries = snaptime_queries(record.class, [record.natural_id], nil)
queries.each do |klass, keys_and_values|
keys_and_values.each do |key, values|
selects << select_for(klass, key, values)
end
end
rel = Snaptime.model_class
rel = rel.from(
"#{union_selects(*selects)} inner_snaptimes"
)
rel = rel.select(Arel.sql("LISTAGG(record_lookups, ';') WITHIN GROUP(ORDER BY record_lookups)").as('record_lookups'))
Snaptime.consolidation_fields.each do |field, options|
if options[:aggregate_with].nil?
rel = rel.select(field)
elsif options[:aggregate_with] == :max
rel = rel.select(Arel.sql(field.to_s).maximum.as(field.to_s))
elsif options[:aggregate_with] == :max_coalesce_0
rel = rel.select(
Arel.sql(
Arel::Nodes::NamedFunction.new('coalesce', [Arel.sql(field.to_s), Arel.sql(0.to_s)]).to_sql
).maximum.as(field.to_s)
)
elsif options[:aggregate_with] == :min
rel = rel.select(Arel.sql(field.to_s).minimum.as(field.to_s))
elsif options[:aggregate_with] == :min_coalesce_0
rel = rel.select(
Arel.sql(
Arel::Nodes::NamedFunction.new('coalesce', [Arel.sql(field.to_s), Arel.sql(0.to_s)]).to_sql
).minimum.as(field.to_s)
)
elsif options[:aggregate_with] == :sum
rel = rel.select(Arel.sql(field.to_s).sum.as(field.to_s))
end
end
grouping_fields = Snaptime.consolidation_fields.select { |_k, v| v[:aggregate_with].nil? }.keys.collect(&:to_s)
rel = rel.order(Arel::Table.new(:inner_snaptimes)[:valid_from].desc)
rel = rel.group(*grouping_fields)
all_keys = [:record_lookups] + Snaptime.consolidation_fields.keys
all_fields = all_keys.collect do |key|
Arel::Table.new(:snaptimes)[key]
end
outer_rel = Snaptime.model_class.select(all_fields).from("(#{rel.to_sql}) snaptimes")
return outer_rel
end
|