viewy 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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