viewy 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c1796596ee3676d14308739bce83b2578bf45c96
4
- data.tar.gz: 4f2a4a1c577ca5e08dd0f79aacdbdcb34c09c221
3
+ metadata.gz: f7fd8d70558ffa6fe9bc84f9350d7920caf13d96
4
+ data.tar.gz: c2a3c6b8a585610a7fd02b638a559ef93b75b689
5
5
  SHA512:
6
- metadata.gz: 6c98415f23bbbf74f7235b97fcf906a0d2c9e9196f4e410a4be84052879ef651e287eab3743589159460c9f6591b06527bb9b4e99be444f5d5dca4230dd6d90b
7
- data.tar.gz: 32b3c33a89c6e462d65a9b131f9bb8bccab58b82f21e55bdf118b08ea82defce73b4e6eaced63855bbc498eea4f1a3450363d4d00f793b44571a7ff83ef8c726
6
+ metadata.gz: 09cc98dd4ca4bcd07a3218c21444e2c86ba60977f3f8043992130506d7a778770ee2b0484a2cf6ebd2c43752df4ca2a3813dbf35318e1996eb76c0ff2eb1447b
7
+ data.tar.gz: 2a74e4c34a3131aa729e170ea07f352f5d15ef3b667445f2cf3a20b275f70a330d45f7e70d0e8e01c14c69df67bde13df6622813ff480e2214f82973e087f923
data/lib/viewy.rb CHANGED
@@ -2,6 +2,7 @@ require 'viewy/engine'
2
2
  require 'viewy/models'
3
3
  require 'viewy/acts_as_view'
4
4
  require 'viewy/acts_as_materialized_view'
5
+ require 'viewy/dependency_management'
5
6
  require 'viewy/dependency_manager'
6
7
 
7
8
  module Viewy
@@ -14,7 +14,7 @@ module Viewy
14
14
  def refresh!
15
15
  view_dep = Viewy::Models::MaterializedViewDependency.find(table_name)
16
16
  view_dep.view_dependencies.each do |view_dependency|
17
- connection.execute("REFRESH MATERIALIZED VIEW #{view_dependency}")
17
+ ActiveRecord::Base.connection.execute("REFRESH MATERIALIZED VIEW #{view_dependency}")
18
18
  end
19
19
  refresh_without_dependencies!
20
20
  end
@@ -25,7 +25,7 @@ module Viewy
25
25
  #
26
26
  # @return [PG::Result] the result of the refresh statement on the materialized view
27
27
  def refresh_without_dependencies!
28
- connection.execute("REFRESH MATERIALIZED VIEW #{table_name}")
28
+ ActiveRecord::Base.connection.execute("REFRESH MATERIALIZED VIEW #{table_name}")
29
29
  end
30
30
  end
31
31
  end
@@ -14,7 +14,7 @@ module Viewy
14
14
  def refresh!
15
15
  view_dep = Viewy::Models::MaterializedViewDependency.find(table_name)
16
16
  view_dep.view_dependencies.each do |view_dependency|
17
- connection.execute("REFRESH MATERIALIZED VIEW #{view_dependency}")
17
+ ActiveRecord::Base.connection.execute("REFRESH MATERIALIZED VIEW #{view_dependency}")
18
18
  end
19
19
  end
20
20
  end
@@ -0,0 +1,7 @@
1
+ require_relative 'dependency_management/view_refresher'
2
+
3
+ module Viewy
4
+ module DependencyManagement
5
+
6
+ end
7
+ end
@@ -0,0 +1,72 @@
1
+ require 'tsort'
2
+
3
+ module Viewy
4
+ module DependencyManagement
5
+ # Provides a means of refreshing materialized views in the order in which they were created
6
+ #
7
+ # @!attribute connection [r]
8
+ # @return [ActiveRecord::ConnectionAdapters::PostgreSQLAdapter] the underlying Postgres connection
9
+ class ViewRefresher
10
+ include TSort
11
+
12
+ attr_reader :connection
13
+
14
+ alias_method :ordered_views, :tsort
15
+ private :tsort, :ordered_views
16
+
17
+ # @param connection [ActiveRecord::ConnectionAdapters::PostgreSQLAdapter] An ActiveRecord connection
18
+ # to a Postgres Database
19
+ def initialize(connection)
20
+ @connection = connection
21
+ end
22
+
23
+ # This method will refresh all materialized views in order of dependency
24
+ def refresh_all_materialized_views
25
+ ordered_views.each do |view_name|
26
+ refresh_materialized_view(view_name)
27
+ end
28
+ end
29
+
30
+ # Refreshes a single materialized view
31
+ #
32
+ # @param view_name [String] the name of a materialized view
33
+ def refresh_materialized_view(view_name)
34
+ connection.execute(refresh_sql(view_name))
35
+ end
36
+
37
+ # Note: this method memoizes the result of the first call
38
+ #
39
+ # @return [Hash] a hash with materialized view names as keys and their dependencies as an array of names
40
+ private def views
41
+ @views ||= generate_view_hash
42
+ end
43
+
44
+ # @return [Hash] a hash with materialized view names as keys and their dependencies as an array of names
45
+ private def generate_view_hash
46
+ views = Viewy::Models::MaterializedViewDependency.all.select(&:materialized_view).map do |dep|
47
+ [dep.view_name, dep.view_dependencies]
48
+ end
49
+ Hash[views]
50
+ end
51
+
52
+ private def tsort_each_node
53
+ views.each_key do |view|
54
+ yield view
55
+ end
56
+ end
57
+
58
+ # @param name [String] the name of a materialized view
59
+ private def tsort_each_child(view, &block)
60
+ views[view].each(&block)
61
+ end
62
+
63
+ # @param name [String] the name of a materialized view
64
+ # @return [String] the SQL statement needed to refresh the passed view
65
+ def refresh_sql(name)
66
+ <<-SQL.strip
67
+ REFRESH MATERIALIZED VIEW #{name}
68
+ SQL
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,50 +1,50 @@
1
- require 'tsort'
2
-
3
1
  module Viewy
2
+ # Provides an interface for managing the dependencies of views within the application.
3
+ #
4
+ # NOTE: the dependencies view is refreshed when an instance is initialized and this can take a little while to run.
4
5
  class DependencyManager
5
- include TSort
6
-
6
+ # @param connection [ActiveRecord::ConnectionAdapters::PostgreSQLAdapter] An ActiveRecord connection
7
+ # to a Postgres Database
7
8
  def initialize
8
- connection.execute(refresh_sql('materialized_view_dependencies'))
9
- end
10
-
11
- def connection
12
- ActiveRecord::Base.connection
9
+ view_refresher.refresh_materialized_view('materialized_view_dependencies')
13
10
  end
14
11
 
12
+ # This method will refresh all materialized views in order of dependency
13
+ #
14
+ # @raise [ActiveRecord::StatementInvalidError] raised if a view is somehow not refreshed correctly
15
15
  def refresh_all_materialized_views
16
- ordered_views.each do |view_name|
17
- connection.execute(refresh_sql(view_name))
18
- end
19
- end
20
-
21
- private def views
22
- @views ||= generate_view_hash
23
- end
24
-
25
- private def generate_view_hash
26
- views = Viewy::Models::MaterializedViewDependency.all.select(&:materialized_view).map do |dep|
27
- [dep.view_name, dep.view_dependencies]
28
- end
29
- Hash[views]
30
- end
31
-
32
- private def tsort_each_node
33
- views.each_key do |view|
34
- yield view
35
- end
36
- end
37
-
38
- private def tsort_each_child(view, &block)
39
- views[view].each(&block)
40
- end
41
-
42
- private def refresh_sql(name)
43
- <<-SQL.strip
44
- REFRESH MATERIALIZED VIEW #{name}
45
- SQL
16
+ view_refresher.refresh_all_materialized_views
17
+ end
18
+
19
+ # Replaces the named view (or materialized view) with the new definition SQL.
20
+ # This will do the following
21
+ #
22
+ # 1. drop all view which depend on the view being replaced
23
+ # 2. drop the view being replaced
24
+ # 3. recreate the view with the passed sql
25
+ # 4. re-create all of the views which depended on the replaced view
26
+ #
27
+ # NOTE: this is provided as a convenience for managing dependencies, and the user should not expect that the
28
+ # re-created views will function if they rely on parts of the replaced view that are removed.
29
+ #
30
+ # @param view_name [String] the name of the view being replaced
31
+ # @param new_definition_sql [String] the SQL definition of the new view
32
+ #
33
+ # @raise [ActiveRecord::StatementInvalidError] raised if a dependent view is somehow not refreshed correctly
34
+ # @return [PG::Result] the result of the refresh statement on the materialized view
35
+ def replace_view(view_name, new_definition_sql)
36
+ connection.execute("SELECT replace_view('#{view_name}', $$#{new_definition_sql}$$)")
37
+ end
38
+
39
+ # @return [Viewy::DependencyManagement::ViewRefresher] a memoized view refresher object
40
+ private def view_refresher
41
+ @view_refresher ||= Viewy::DependencyManagement::ViewRefresher.new(connection)
42
+ end
43
+
44
+ # @return [ActiveRecord::ConnectionAdapters::PostgreSQLAdapter] An ActiveRecord connection
45
+ # to a Postgres Database
46
+ private def connection
47
+ ActiveRecord::Base.connection
46
48
  end
47
-
48
- alias_method :ordered_views, :tsort
49
49
  end
50
50
  end
data/lib/viewy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Viewy
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: viewy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emerson Huitt
@@ -83,6 +83,8 @@ files:
83
83
  - lib/viewy.rb
84
84
  - lib/viewy/acts_as_materialized_view.rb
85
85
  - lib/viewy/acts_as_view.rb
86
+ - lib/viewy/dependency_management.rb
87
+ - lib/viewy/dependency_management/view_refresher.rb
86
88
  - lib/viewy/dependency_manager.rb
87
89
  - lib/viewy/engine.rb
88
90
  - lib/viewy/materialized_views.rb