viewy 0.0.9 → 0.0.10

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: 4f4635fbdb32ad47ab83ca1d5dfefd749cff4372
4
- data.tar.gz: dbf922b26c5ccd6c53d1dcf0a0f784a390212671
3
+ metadata.gz: 7519012d78dc8bb9829b1240e3916e9a2b452631
4
+ data.tar.gz: d95c4be5a030addf42acb30e06699bad9738a1fe
5
5
  SHA512:
6
- metadata.gz: 6573e51501306fd23d8fa4b8aaf329666124522ff8dbc19e45ad6e747c6910cd4224c2f5bac2665c480f29b2cf399bfadb1ba4e5b4426e80cde675ec183be31e
7
- data.tar.gz: ce10805be334f3faf47494eb971e6134ad1194664c5d409a4584dfa4b02a0a130615196e2de23634a8828972abca012098204610777c2a01bd3b7b0eed61490c
6
+ metadata.gz: cad94ef6b55fbc24569d64fe7a46110ae2608beb7852ebe7f917f1dd34a4d6723cb93f2e20bb5f3ba705bc30953b9e86916ccd435c4c4e28c4fcae226b7fea7c
7
+ data.tar.gz: 2bb352187f487f89c2c07fcac9efa981c60b121927b8dc26e83500c68b2eecf80cac82c4321b0ccf66ea3430cecd4d4f2b8173d0d5683c12c1eb56f3e4388142
@@ -42,8 +42,8 @@ class UpdateDependencyViews < ActiveRecord::Migration
42
42
 
43
43
  def down
44
44
  dependency_sql = <<-SQL
45
- DROP MATERIALIZED VIEW materialized_view_dependencies;
46
45
  DROP MATERIALIZED VIEW all_view_dependencies;
46
+ DROP MATERIALIZED VIEW materialized_view_dependencies;
47
47
 
48
48
  CREATE MATERIALIZED VIEW materialized_view_dependencies AS
49
49
  WITH normal_view_dependencies AS (
@@ -0,0 +1,139 @@
1
+ class UpdateViewReplaceFunction < ActiveRecord::Migration
2
+ def up
3
+ function_sql = <<-SQL
4
+ CREATE OR REPLACE FUNCTION replace_view(view_name TEXT, new_sql TEXT) RETURNS VOID AS $$
5
+ DECLARE
6
+ ordered_oids INTEGER[] := ARRAY(
7
+ SELECT oid FROM
8
+ (
9
+ WITH RECURSIVE dependency_graph(oid, depth, path, cycle) AS (
10
+ SELECT oid, 1, ARRAY[oid], FALSE
11
+ FROM pg_class
12
+ WHERE relname = view_name
13
+ UNION
14
+ SELECT
15
+ rewrites.ev_class,
16
+ dg.depth + 1,
17
+ dg.path || rewrites.ev_class,
18
+ rewrites.ev_class = ANY(dg.path)
19
+ FROM dependency_graph dg
20
+ JOIN pg_depend dependents ON dependents.refobjid = dg.oid
21
+ JOIN pg_rewrite rewrites ON rewrites.oid = dependents.objid
22
+ WHERE NOT dg.cycle
23
+ )
24
+ SELECT dependency_graph.OID, MIN(depth) AS min_depth FROM dependency_graph GROUP BY dependency_graph.OID ORDER BY min_depth
25
+ ) ordered_dependents
26
+ );
27
+ create_statements TEXT[] := '{}';
28
+ current_statement TEXT;
29
+ view_drop_statement TEXT;
30
+ object_id INT;
31
+ BEGIN
32
+ FOREACH object_id IN ARRAY ordered_oids LOOP
33
+ SELECT
34
+ (CASE
35
+ WHEN (SELECT TRUE FROM pg_views WHERE viewname = relname) THEN
36
+ 'CREATE OR REPLACE VIEW ' || pg_class.relname || ' AS ' || pg_get_viewdef(oid)
37
+ WHEN (SELECT TRUE FROM pg_matviews WHERE matviewname = relname) THEN
38
+ 'CREATE MATERIALIZED VIEW ' || pg_class.relname || ' AS ' || pg_get_viewdef(oid) || ' WITH NO DATA'
39
+ END)
40
+ INTO current_statement
41
+ FROM pg_class
42
+ WHERE oid = object_id
43
+ AND pg_class.relname != view_name;
44
+ IF current_statement IS NOT NULL THEN
45
+ create_statements = create_statements || current_statement;
46
+ END IF;
47
+ END LOOP;
48
+ ALTER EVENT TRIGGER view_dependencies_update DISABLE;
49
+ SELECT
50
+ (
51
+ CASE
52
+ WHEN (SELECT TRUE FROM pg_views WHERE viewname = view_name) THEN
53
+ 'DROP VIEW ' || view_name || ' CASCADE;'
54
+ WHEN (SELECT TRUE FROM pg_matviews WHERE matviewname = view_name) THEN
55
+ 'DROP MATERIALIZED VIEW ' || view_name || ' CASCADE;'
56
+ END
57
+ )
58
+ INTO view_drop_statement;
59
+ EXECUTE view_drop_statement;
60
+ EXECUTE new_sql;
61
+ FOREACH current_statement IN ARRAY create_statements LOOP
62
+ EXECUTE current_statement;
63
+ END LOOP;
64
+ ALTER EVENT TRIGGER view_dependencies_update ENABLE ALWAYS;
65
+ END;
66
+ $$ LANGUAGE plpgsql;
67
+ SQL
68
+ execute function_sql
69
+ end
70
+
71
+ def down
72
+ function_sql = <<-SQL
73
+ CREATE OR REPLACE FUNCTION replace_view(view_name TEXT, new_sql TEXT) RETURNS VOID AS $$
74
+ DECLARE
75
+ ordered_oids INTEGER[] := ARRAY(
76
+ SELECT oid FROM
77
+ (
78
+ WITH RECURSIVE dependency_graph(oid, depth, path, cycle) AS (
79
+ SELECT oid, 1, ARRAY[oid], FALSE
80
+ FROM pg_class
81
+ WHERE relname = view_name
82
+ UNION
83
+ SELECT
84
+ rewrites.ev_class,
85
+ dg.depth + 1,
86
+ dg.path || rewrites.ev_class,
87
+ rewrites.ev_class = ANY(dg.path)
88
+ FROM dependency_graph dg
89
+ JOIN pg_depend dependents ON dependents.refobjid = dg.oid
90
+ JOIN pg_rewrite rewrites ON rewrites.oid = dependents.objid
91
+ WHERE NOT dg.cycle
92
+ )
93
+ SELECT dependency_graph.OID, MIN(depth) AS min_depth FROM dependency_graph GROUP BY dependency_graph.OID ORDER BY min_depth
94
+ ) ordered_dependents
95
+ );
96
+ create_statements TEXT[] := '{}';
97
+ current_statement TEXT;
98
+ view_drop_statement TEXT;
99
+ object_id INT;
100
+ BEGIN
101
+ FOREACH object_id IN ARRAY ordered_oids LOOP
102
+ SELECT
103
+ (CASE
104
+ WHEN (SELECT TRUE FROM pg_views WHERE viewname = relname) THEN
105
+ 'CREATE OR REPLACE VIEW ' || pg_class.relname || ' AS ' || pg_get_viewdef(oid)
106
+ WHEN (SELECT TRUE FROM pg_matviews WHERE matviewname = relname) THEN
107
+ 'CREATE MATERIALIZED VIEW ' || pg_class.relname || ' AS ' || pg_get_viewdef(oid)
108
+ END)
109
+ INTO current_statement
110
+ FROM pg_class
111
+ WHERE oid = object_id
112
+ AND pg_class.relname != view_name;
113
+ IF current_statement IS NOT NULL THEN
114
+ create_statements = create_statements || current_statement;
115
+ END IF;
116
+ END LOOP;
117
+ ALTER EVENT TRIGGER view_dependencies_update DISABLE;
118
+ SELECT
119
+ (
120
+ CASE
121
+ WHEN (SELECT TRUE FROM pg_views WHERE viewname = view_name) THEN
122
+ 'DROP VIEW ' || view_name || ' CASCADE;'
123
+ WHEN (SELECT TRUE FROM pg_matviews WHERE matviewname = view_name) THEN
124
+ 'DROP MATERIALIZED VIEW ' || view_name || ' CASCADE;'
125
+ END
126
+ )
127
+ INTO view_drop_statement;
128
+ EXECUTE view_drop_statement;
129
+ EXECUTE new_sql;
130
+ FOREACH current_statement IN ARRAY create_statements LOOP
131
+ EXECUTE current_statement;
132
+ END LOOP;
133
+ ALTER EVENT TRIGGER view_dependencies_update ENABLE ALWAYS;
134
+ END;
135
+ $$ LANGUAGE plpgsql;
136
+ SQL
137
+ execute function_sql
138
+ end
139
+ end
@@ -5,4 +5,28 @@ namespace :viewy do
5
5
  Viewy.refresh_all_dependency_information
6
6
  puts 'View dependency information refresh complete.'
7
7
  end
8
+
9
+ task :include_triggers_in_structure, :environment do
10
+ version_sql = <<-SQL
11
+ SHOW server_version;
12
+ SQL
13
+ result = Viewy.connection.execute(version_sql)
14
+ unless result.values[0][0].match(/9\.4/)
15
+ puts 'Updating structure.sql to include event triggers'
16
+ path = File.expand_path('db/structure.sql', Rails.root)
17
+ File.open(path, 'a') do |structure_sql|
18
+ event_triggers = Viewy::EventTriggers.new
19
+ structure_sql.puts
20
+ structure_sql.puts event_triggers.event_triggers_sql
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ Rake::Task['db:structure:dump'].enhance do
27
+ if Rake::Task.task_defined?('viewy:include_triggers_in_structure')
28
+ Rake::Task['viewy:include_triggers_in_structure'].invoke
29
+ else
30
+ Rake::Task['app:viewy:include_triggers_in_structure'].invoke
31
+ end
8
32
  end
@@ -4,6 +4,7 @@ require 'viewy/acts_as_view'
4
4
  require 'viewy/acts_as_materialized_view'
5
5
  require 'viewy/dependency_management'
6
6
  require 'viewy/dependency_manager'
7
+ require 'viewy/event_triggers'
7
8
 
8
9
  # Viewy provides a means of interacting with views in a Postgres database in a way that allows the manipulation
9
10
  # of views and their dependencies
@@ -28,8 +28,9 @@ module Viewy
28
28
  #
29
29
  # @raise [ActiveRecord::StatementInvalidError] raised if a dependent view is somehow not refreshed correctly
30
30
  # @return [PG::Result] the result of the refresh statement on the materialized view
31
- def replace_view(view_name, new_definition_sql)
31
+ def replace_view(view_name, new_definition_sql, &block)
32
32
  Viewy.connection.execute("SELECT replace_view('#{view_name}', $$#{new_definition_sql}$$)")
33
+ block.call if block_given?
33
34
  end
34
35
 
35
36
  # @return [Viewy::DependencyManagement::ViewRefresher] a memoized view refresher object
@@ -0,0 +1,17 @@
1
+ module Viewy
2
+ # This provides a handle for dealing with Viewy specific event triggers, which are no longer exported from Postgres as of 9.5.1
3
+ # See http://www.postgresql.org/message-id/8795.1452631064@sss.pgh.pa.us for more information
4
+ #
5
+ # NOTE: this should be updated any time a migration changes the triggers
6
+ class EventTriggers
7
+ # @return [String] the sql needed to create the view triggers needed for viewy to function
8
+ def event_triggers_sql
9
+ <<-SQL
10
+ CREATE EVENT TRIGGER view_dependencies_update
11
+ ON DDL_COMMAND_END
12
+ WHEN TAG IN ('DROP VIEW', 'DROP MATERIALIZED VIEW', 'CREATE VIEW', 'CREATE MATERIALIZED VIEW', 'ALTER VIEW', 'ALTER MATERIALIZED VIEW')
13
+ EXECUTE PROCEDURE refresh_materialized_view_dependencies();
14
+ SQL
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module Viewy
2
- VERSION = '0.0.9'
2
+ VERSION = '0.0.10'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: viewy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emerson Huitt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-01 00:00:00.000000000 Z
11
+ date: 2016-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -80,6 +80,7 @@ files:
80
80
  - db/migrate/20150929144540_add_view_replace_function.rb
81
81
  - db/migrate/20150929205301_add_view_dependencies.rb
82
82
  - db/migrate/20151005150022_update_dependency_views.rb
83
+ - db/migrate/20160512173021_update_view_replace_function.rb
83
84
  - lib/tasks/viewy_tasks.rake
84
85
  - lib/viewy.rb
85
86
  - lib/viewy/acts_as_materialized_view.rb
@@ -89,6 +90,7 @@ files:
89
90
  - lib/viewy/dependency_management/view_sorter.rb
90
91
  - lib/viewy/dependency_manager.rb
91
92
  - lib/viewy/engine.rb
93
+ - lib/viewy/event_triggers.rb
92
94
  - lib/viewy/models.rb
93
95
  - lib/viewy/models/materialized_view_dependency.rb
94
96
  - lib/viewy/models/view_dependency.rb