Class: Monocle::View

Inherits:
Object
  • Object
show all
Defined in:
lib/monocle/view.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ View

Returns a new instance of View.



10
11
12
13
# File 'lib/monocle/view.rb', line 10

def initialize(name)
  @name = name
  @dependants = []
end

Instance Attribute Details

#dependantsObject

Returns the value of attribute dependants.



5
6
7
# File 'lib/monocle/view.rb', line 5

def dependants
  @dependants
end

#nameObject (readonly)

Returns the value of attribute name.



4
5
6
# File 'lib/monocle/view.rb', line 4

def name
  @name
end

Instance Method Details

#createObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/monocle/view.rb', line 37

def create
  debug "Creating #{name}..."
  execute create_command
  Migration.find_or_create_by version: slug
  dependants.each &:create
  true
rescue ActiveRecord::StatementInvalid => e
  # We may have another new view coming that this view depend on
  # if the relation name is included on our list of views, we create
  # that first and then retry
  if e.message =~ /PG::UndefinedTable/ &&
     e.message.scan(/relation \"(\w+)\" does not exist/) &&
     list.keys.include?($1.to_sym)
     warn "Can't create #{name} because it depends on #{$1}, creating that first..."
     list.fetch($1.to_sym).create
     retry
  else
    fail e
  end
end

#create_commandObject



85
86
87
# File 'lib/monocle/view.rb', line 85

def create_command
  @create_command ||= File.read(path_for_sql)
end

#dropObject



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/monocle/view.rb', line 19

def drop
  debug "Dropping #{name}..."
  execute drop_command
  true
rescue ActiveRecord::StatementInvalid => e
  # We have dependants, can't drop this directly.
  if e.message =~ /PG::DependentObjectsStillExist/
    # Find the views in the main list, drop them
    self.dependants = get_dependants_from_error e
    debug "Can't drop #{name}, it has dependants: #{dependants.map(&:name).join(', ')}"
    dependants.each &:drop
    # And try this again
    retry
  else
    fail e
  end
end

#drop_commandObject



80
81
82
83
# File 'lib/monocle/view.rb', line 80

def drop_command
  _materialized = 'MATERIALIZED' if materialized?
  "DROP #{_materialized} VIEW IF EXISTS #{name};"
end

#materialized?Boolean

Returns:

  • (Boolean)


15
16
17
# File 'lib/monocle/view.rb', line 15

def materialized?
  !!(@materialized ||= create_command =~ /MATERIALIZED VIEW/i)
end

#migrateObject



58
59
60
61
62
63
64
65
66
67
# File 'lib/monocle/view.rb', line 58

def migrate
  if versions.include?(slug)
    debug "Skipping #{name} as it's already up to date."
    true
  else
    status = drop && create
    info "#{name} migrated to #{slug}!"
    status
  end
end

#path_for_sqlObject



89
90
91
# File 'lib/monocle/view.rb', line 89

def path_for_sql
  @path_for_sql ||= File.join views_path, "#{name}.sql"
end

#refresh(concurrently: false) ⇒ Object



69
70
71
72
73
74
# File 'lib/monocle/view.rb', line 69

def refresh(concurrently: false)
  # We don't refresh normal views
  return false unless materialized?
  _concurrently = "CONCURRENTLY" if concurrently
  execute "REFRESH MATERIALIZED VIEW #{_concurrently} #{name}"
end

#slugObject



76
77
78
# File 'lib/monocle/view.rb', line 76

def slug
  @slug ||= VersionGenerator.new(path_for_sql).generate
end