Module: ActiveRecordViews::Extension::ClassMethods

Defined in:
lib/active_record_views/extension.rb

Instance Method Summary collapse

Instance Method Details

#ensure_populated!Object



90
91
92
93
94
95
96
97
98
99
# File 'lib/active_record_views/extension.rb', line 90

def ensure_populated!
  ActiveRecordViews.get_view_direct_dependencies(self.connection, self.table_name).each do |class_name|
    klass = class_name.constantize
    klass.ensure_populated!
  end

  if ActiveRecordViews.materialized_view?(self.connection, self.table_name)
    refresh_view! unless view_populated?
  end
end

#is_view(*args) ⇒ Object

Raises:

  • (ArgumentError)


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/active_record_views/extension.rb', line 20

def is_view(*args)
  cattr_accessor :view_options
  self.view_options = args.extract_options!

  raise ArgumentError, "wrong number of arguments (#{args.size} for 0..1)" unless (0..1).cover?(args.size)
  sql = args.shift

  sql ||= begin
    sql_path = ActiveRecordViews.find_sql_file(self.name.underscore)
    ActiveRecordViews.register_for_reload self, sql_path
    ActiveRecordViews.read_sql_file(self, sql_path)
  end

  create_args = [self.table_name, self.name, sql, self.view_options]
  if ActiveRecordViews::Extension.create_enabled
    ActiveRecordViews.create_view self.connection, *create_args
  else
    ActiveRecordViews::Extension.create_queue << create_args
  end
end

#refresh_view!(options = {}) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/active_record_views/extension.rb', line 41

def refresh_view!(options = {})
  options.assert_valid_keys :concurrent

  concurrent = case options.fetch(:concurrent, :auto)
  when false
    false
  when true
    true
  when :auto
    view_options.fetch(:unique_columns, nil) && view_populated? && ActiveRecordViews.supports_concurrent_refresh?(connection)
  else
    raise ArgumentError, 'invalid concurrent option'
  end

  connection.transaction do
    connection.execute "REFRESH MATERIALIZED VIEW#{' CONCURRENTLY' if concurrent} #{connection.quote_table_name self.table_name};"
    connection.execute "UPDATE active_record_views SET refreshed_at = current_timestamp AT TIME ZONE 'UTC' WHERE name = #{connection.quote self.table_name};"
    connection.clear_query_cache
  end
end

#refreshed_atObject



76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/active_record_views/extension.rb', line 76

def refreshed_at
  value = connection.select_value(<<-SQL.squish)
    SELECT refreshed_at
    FROM active_record_views
    WHERE name = #{connection.quote self.table_name};
  SQL

  if value.is_a? String
    value = ActiveSupport::TimeZone['UTC'].parse(value)
  end

  value
end

#view_populated?Boolean

Returns:

  • (Boolean)


62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/active_record_views/extension.rb', line 62

def view_populated?
  value = connection.select_value(<<-SQL.squish)
    SELECT ispopulated
    FROM pg_matviews
    WHERE schemaname = 'public' AND matviewname = #{connection.quote self.table_name};
  SQL

  if value.nil?
    raise ArgumentError, 'not a materialized view'
  end

  value
end