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
74
75
76
77
78
79
80
81
82
83
84
85
86
|
# File 'lib/chrono_model/time_machine/timeline.rb', line 9
def timeline(record = nil, options = {})
rid =
if record
if record.respond_to?(:rid)
record.rid
else
record.id
end
end
assocs =
if options.key?(:with)
timeline_associations_from(options[:with])
else
timeline_associations
end
models = []
models.push self if chrono?
models.concat(assocs.map { |a| a.klass.history })
return [] if models.empty?
fields = models.inject([]) { |a, m| a.concat m.quoted_history_fields }
relation = except(:order)
.select("DISTINCT UNNEST(ARRAY[#{fields.join(',')}]) AS ts")
if assocs.present?
assocs.each do |ass|
association_quoted_table_name = connection.quote_table_name(ass.table_name)
relation =
if ass.belongs_to?
relation.joins("LEFT JOIN #{association_quoted_table_name} ON #{association_quoted_table_name}.#{ass.association_primary_key} = #{quoted_table_name}.#{ass.association_foreign_key}")
else
relation.joins("LEFT JOIN #{association_quoted_table_name} ON #{association_quoted_table_name}.#{ass.foreign_key} = #{quoted_table_name}.#{primary_key}")
end
end
end
relation_order =
if options[:reverse]
'DESC'
else
'ASC'
end
relation = relation.order("ts #{relation_order}")
relation = relation.from("public.#{quoted_table_name}") unless chrono?
relation = relation.where(id: rid) if rid
sql = +"SELECT ts FROM ( #{relation.to_sql} ) AS foo WHERE ts IS NOT NULL"
if options.key?(:before)
sql << " AND ts < '#{Conversions.time_to_utc_string(options[:before])}'"
end
if options.key?(:after)
sql << " AND ts > '#{Conversions.time_to_utc_string(options[:after])}'"
end
if rid && !options[:with]
sql <<
if chrono?
%{ AND ts <@ ( SELECT tsrange(min(lower(validity)), max(upper(validity)), '[]') FROM #{quoted_table_name} WHERE id = #{rid} ) }
else
%[ AND ts < NOW() ]
end
end
sql << " LIMIT #{options[:limit].to_i}" if options.key?(:limit)
connection.on_schema(Adapter::HISTORY_SCHEMA) do
connection.select_values(sql, "#{name} periods")
end
end
|