pg_assets 1.0

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.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +32 -0
  4. data/lib/pg_assets/helpers/views_migration_helper.rb +59 -0
  5. data/lib/pg_assets/models/concerns/loadable_asset.rb +28 -0
  6. data/lib/pg_assets/models/pg_constraint.rb +46 -0
  7. data/lib/pg_assets/models/pg_function.rb +46 -0
  8. data/lib/pg_assets/models/pg_mat_view.rb +29 -0
  9. data/lib/pg_assets/models/pg_trigger.rb +46 -0
  10. data/lib/pg_assets/models/pg_view.rb +29 -0
  11. data/lib/pg_assets/railtie.rb +29 -0
  12. data/lib/pg_assets/services/pg_asset_manager.rb +100 -0
  13. data/lib/pg_assets/version.rb +3 -0
  14. data/lib/pg_assets.rb +15 -0
  15. data/test/assets/constraint_check.sql +4 -0
  16. data/test/assets/constraint_multiple.sql +5 -0
  17. data/test/assets/constraint_unique.sql +4 -0
  18. data/test/assets/function1.sql +5 -0
  19. data/test/assets/function2.sql +5 -0
  20. data/test/assets/materialized_view_with_table.sql +7 -0
  21. data/test/assets/matview1.sql +2 -0
  22. data/test/assets/matview2.sql +2 -0
  23. data/test/assets/trigger1.sql +12 -0
  24. data/test/assets/trigger2.sql +12 -0
  25. data/test/assets/view1.sql +2 -0
  26. data/test/assets/view2.sql +2 -0
  27. data/test/assets/view_with_table.sql +7 -0
  28. data/test/dummy/README.rdoc +28 -0
  29. data/test/dummy/Rakefile +6 -0
  30. data/test/dummy/app/assets/javascripts/application.js +13 -0
  31. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  32. data/test/dummy/app/controllers/application_controller.rb +5 -0
  33. data/test/dummy/app/helpers/application_helper.rb +2 -0
  34. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  35. data/test/dummy/bin/bundle +3 -0
  36. data/test/dummy/bin/rails +4 -0
  37. data/test/dummy/bin/rake +4 -0
  38. data/test/dummy/config/application.rb +23 -0
  39. data/test/dummy/config/boot.rb +5 -0
  40. data/test/dummy/config/database.yml +19 -0
  41. data/test/dummy/config/environment.rb +5 -0
  42. data/test/dummy/config/environments/development.rb +32 -0
  43. data/test/dummy/config/environments/production.rb +80 -0
  44. data/test/dummy/config/environments/test.rb +39 -0
  45. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  46. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  47. data/test/dummy/config/initializers/inflections.rb +16 -0
  48. data/test/dummy/config/initializers/mime_types.rb +5 -0
  49. data/test/dummy/config/initializers/secret_token.rb +12 -0
  50. data/test/dummy/config/initializers/session_store.rb +3 -0
  51. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  52. data/test/dummy/config/locales/en.yml +23 -0
  53. data/test/dummy/config/routes.rb +56 -0
  54. data/test/dummy/config.ru +4 -0
  55. data/test/dummy/log/test.log +41514 -0
  56. data/test/dummy/public/404.html +58 -0
  57. data/test/dummy/public/422.html +58 -0
  58. data/test/dummy/public/500.html +57 -0
  59. data/test/dummy/public/favicon.ico +0 -0
  60. data/test/helpers/views_migration_helper_test.rb +99 -0
  61. data/test/models/pg_constraint_test.rb +53 -0
  62. data/test/models/pg_func_test.rb +38 -0
  63. data/test/models/pg_mat_view_test.rb +44 -0
  64. data/test/models/pg_trigger_test.rb +38 -0
  65. data/test/models/pg_view_test.rb +44 -0
  66. data/test/services/pg_asset_manager_test.rb +117 -0
  67. data/test/test_helper.rb +34 -0
  68. metadata +219 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8cba0b518d1da36d660f56d1a21fc6e28f7b7a68
4
+ data.tar.gz: 3fb8db5ba3b1bd95d6768375eebc72b1bfe43f29
5
+ SHA512:
6
+ metadata.gz: 03554c5b57a795eb147f83e74b727ff52230ba36d200f4ea5126dfc6207be5075753e2ebe8bb96cb5819110eae5ef6470e31e1e275782768cd8ac38b80433190
7
+ data.tar.gz: bfa495c49572b603a05b83cda31b9127c85e5a6c43348025731862be459a575b664cbc6e26ce0298da38bc257a512b27b7903a7a8080f450ef027df140a2748b
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'PgAssets'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+ Bundler::GemHelper.install_tasks
21
+
22
+ require 'rake/testtask'
23
+
24
+ Rake::TestTask.new(:test) do |t|
25
+ t.libs << 'lib'
26
+ t.libs << 'test'
27
+ t.pattern = 'test/**/*_test.rb'
28
+ t.verbose = false
29
+ end
30
+
31
+
32
+ task default: :test
@@ -0,0 +1,59 @@
1
+ # This is to help you migrate things where there is a db dependency.
2
+ #
3
+ # Just include it in your migration, then pass your migration changes to it
4
+ # in a block, like this:
5
+ # in your migration like this
6
+ #
7
+ #
8
+ # class BringThePain < ActiveRecord::Migration
9
+ # include PGAssets::ViewsMigrationHelper
10
+ #
11
+ # def change
12
+ # touching_view :a_view do
13
+ # change_column :sweet_table, :column_1, :text, :null => false
14
+ # end
15
+ # end
16
+ # end
17
+ #
18
+ # You may also want to re-define the view if, for instance, you drop a column
19
+ #
20
+ # class BringThePain < ActiveRecord::Migration
21
+ # include PGAssets::ViewsMigrationHelper
22
+ #
23
+ # def change
24
+ # new_defn = 'SELECT id, column_1, column_3 FROM sweet_table'
25
+ #
26
+ # touching_view :a_view, new_defn do
27
+ # remove_column :sweet_table, :column_2
28
+ # end
29
+ # end
30
+ # end
31
+ module PGAssets
32
+ module ViewsMigrationHelper
33
+ def touching_view(view_name, new_defn=nil, &proc)
34
+ view = ::PGAssets::Services::PGAssetManager.specific_view(view_name.to_sym)
35
+ view.remove
36
+
37
+ proc.call
38
+
39
+ if new_defn.nil?
40
+ view.reinstall
41
+ else
42
+ view.reinstall(defn=new_defn)
43
+ end
44
+ end
45
+
46
+ def touching_materialized_view(view_name, new_defn=nil, &proc)
47
+ matview = ::PGAssets::Services::PGAssetManager.specific_matview(view_name.to_sym)
48
+ matview.remove
49
+
50
+ proc.call
51
+
52
+ if new_defn.nil?
53
+ matview.reinstall
54
+ else
55
+ matview.reinstall(defn=new_defn)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,28 @@
1
+ module PGAssets
2
+ module LoadableAsset
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ attr_accessor :cached_defn
7
+
8
+ def self.readonly?
9
+ true
10
+ end
11
+
12
+ def remove
13
+ ActiveRecord::Base.connection.execute sql_for_remove
14
+ end
15
+
16
+ def reinstall(defn=sql_for_reinstall)
17
+ ActiveRecord::Base.connection.execute defn
18
+ end
19
+
20
+ private
21
+
22
+ def get_attribute_from_sql(sql, attribute)
23
+ res = ActiveRecord::Base.connection.execute sql
24
+ res.first[attribute.to_s]
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,46 @@
1
+ module PGAssets
2
+ class PGConstraint < ActiveRecord::Base
3
+ include LoadableAsset
4
+
5
+ self.table_name = 'pg_catalog.pg_constraint'
6
+
7
+ after_find do
8
+ self.cached_defn = get_constraint_defn
9
+ end
10
+
11
+ scope :ours, -> {
12
+ joins('JOIN pg_catalog.pg_namespace ON (pg_constraint.connamespace = pg_namespace.oid)').
13
+ where('pg_namespace.nspname NOT IN (?)', ['pg_catalog', 'information_schema']).
14
+ where('conrelid != 0') #exclude non-table constraints. Not sure what to do with domain constraints yet
15
+ }
16
+
17
+ def identity
18
+ "#{conname} on #{get_table_name}"
19
+ end
20
+
21
+ def sql_for_remove
22
+ sql = "ALTER TABLE #{get_table_name} DROP CONSTRAINT IF EXISTS #{conname}"
23
+ end
24
+
25
+ def sql_for_reinstall
26
+ sql = "ALTER TABLE #{get_table_name} ADD CONSTRAINT #{conname} #{cached_defn}"
27
+ end
28
+
29
+ private
30
+
31
+ def get_oid
32
+ sql = "SELECT oid FROM pg_catalog.pg_constraint WHERE conname = '#{conname}' AND connamespace = '#{connamespace}'"
33
+ get_attribute_from_sql sql, :oid
34
+ end
35
+
36
+ def get_table_name
37
+ sql = "SELECT relname FROM pg_catalog.pg_class WHERE oid = #{conrelid}"
38
+ get_attribute_from_sql sql, :relname
39
+ end
40
+
41
+ def get_constraint_defn
42
+ sql = "SELECT pg_get_constraintdef(#{get_oid}, true) AS constraintdef"
43
+ get_attribute_from_sql sql, :constraintdef
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ module PGAssets
2
+ class PGFunction < ActiveRecord::Base
3
+ include LoadableAsset
4
+
5
+ self.table_name = 'pg_catalog.pg_proc'
6
+
7
+ after_find do
8
+ self.cached_defn = get_function_defn
9
+ end
10
+
11
+ scope :ours, -> {
12
+ joins('JOIN pg_catalog.pg_namespace ON (pg_proc.pronamespace = pg_namespace.oid)').
13
+ where('pg_namespace.nspname NOT IN (?)', ['pg_catalog', 'information_schema'])
14
+ }
15
+
16
+ def identity
17
+ proname
18
+ end
19
+
20
+ # TODO get this to work with bomboclaat schemas
21
+ def sql_for_remove
22
+ sql = "DROP FUNCTION IF EXISTS #{proname}(#{get_function_args})"
23
+ end
24
+
25
+ def sql_for_reinstall
26
+ cached_defn
27
+ end
28
+
29
+ private
30
+
31
+ def get_oid
32
+ sql = "SELECT oid FROM pg_catalog.pg_proc WHERE proname = '#{proname}' AND pronamespace = '#{pronamespace}'"
33
+ get_attribute_from_sql sql, :oid
34
+ end
35
+
36
+ def get_function_defn
37
+ sql = "SELECT pg_get_functiondef(#{get_oid}) AS functiondef"
38
+ get_attribute_from_sql sql, :functiondef
39
+ end
40
+
41
+ def get_function_args
42
+ sql = "SELECT pg_get_function_identity_arguments(#{get_oid}) AS functionargs"
43
+ get_attribute_from_sql sql, :functionargs
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,29 @@
1
+ module PGAssets
2
+ class PGMatView < ActiveRecord::Base
3
+ include LoadableAsset
4
+
5
+ self.table_name = 'pg_catalog.pg_matviews'
6
+
7
+ after_find do
8
+ self.cached_defn = definition
9
+ end
10
+
11
+ scope :ours, -> { where.not(schemaname: ['pg_catalog', 'information_schema']) }
12
+
13
+ def self.by_name(name)
14
+ where(matviewname: name.to_s)
15
+ end
16
+
17
+ def identity
18
+ schemaname + '.' + matviewname
19
+ end
20
+
21
+ def sql_for_remove
22
+ sql = "DROP MATERIALIZED VIEW IF EXISTS #{schemaname}.#{matviewname}"
23
+ end
24
+
25
+ def sql_for_reinstall(defn=cached_defn)
26
+ sql = "CREATE MATERIALIZED VIEW #{schemaname}.#{matviewname} AS #{defn}"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,46 @@
1
+ module PGAssets
2
+ class PGTrigger < ActiveRecord::Base
3
+ include LoadableAsset
4
+
5
+ attr_accessor :trigger_table_name
6
+
7
+ self.table_name = 'pg_catalog.pg_trigger'
8
+
9
+ after_find do
10
+ self.cached_defn = get_trigger_defn
11
+ end
12
+
13
+ # this is wrong. this should join on pg_class to get the table, and then
14
+ # pg_schema to get the schema, and then exclude those other schemas
15
+ scope :ours, -> { where(tgisinternal: false) }
16
+
17
+ def identity
18
+ "#{tgname} ON #{get_trigger_table_name}"
19
+ end
20
+
21
+ def sql_for_remove
22
+ sql = "DROP TRIGGER IF EXISTS #{tgname} ON #{get_trigger_table_name}"
23
+ end
24
+
25
+ def sql_for_reinstall
26
+ sql = cached_defn
27
+ end
28
+
29
+ private
30
+
31
+ def get_trigger_table_name
32
+ sql = "SELECT relname AS name FROM pg_class WHERE oid = #{tgrelid}"
33
+ get_attribute_from_sql sql, :name
34
+ end
35
+
36
+ def get_oid
37
+ sql = "SELECT oid FROM pg_catalog.pg_trigger WHERE tgrelid = #{tgrelid} AND tgname = '#{tgname}'"
38
+ get_attribute_from_sql sql, :oid
39
+ end
40
+
41
+ def get_trigger_defn
42
+ sql = "SELECT pg_get_triggerdef(#{get_oid}, true) AS triggerdef"
43
+ get_attribute_from_sql sql, :triggerdef
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,29 @@
1
+ module PGAssets
2
+ class PGView < ActiveRecord::Base
3
+ include LoadableAsset
4
+
5
+ self.table_name = 'pg_catalog.pg_views'
6
+
7
+ after_find do
8
+ self.cached_defn = definition
9
+ end
10
+
11
+ scope :ours, -> { where.not(schemaname: ['pg_catalog', 'information_schema']) }
12
+
13
+ def self.by_name(name)
14
+ where(viewname: name.to_s)
15
+ end
16
+
17
+ def identity
18
+ schemaname + '.' + viewname
19
+ end
20
+
21
+ def sql_for_remove
22
+ sql = "DROP VIEW IF EXISTS #{schemaname}.#{viewname}"
23
+ end
24
+
25
+ def sql_for_reinstall(defn=cached_defn)
26
+ sql = "CREATE OR REPLACE VIEW #{schemaname}.#{viewname} AS #{defn}"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ require 'pg_assets'
2
+ require 'rails'
3
+
4
+ module PgAssets
5
+ class Railtie < Rails::Railtie
6
+ railtie_name :pg_assets
7
+
8
+ UNREGISTERED_TYPES = {
9
+ regproc: 'text',
10
+ pg_node_tree: 'text',
11
+ aclitem: 'text'
12
+ }
13
+
14
+ rake_tasks do
15
+ load '../../tasks/pg_assets.rake'
16
+ end
17
+
18
+ # some of the column types in the pg_catalog views are not registered.
19
+ # We don't really need them, but we'll register them so we don't get ugly
20
+ # error messages
21
+ initializer 'pg_assets.register_types' do
22
+ UNREGISTERED_TYPES.each_pair do |pgtype, aliastype|
23
+ unless ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID.registered_type?(pgtype)
24
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID.alias_type(pgtype.to_s, aliastype)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,100 @@
1
+ module PGAssets
2
+ module Services
3
+ class PGAssetManager
4
+
5
+ def self.views
6
+ PGView.ours.to_a.sort_by { |v| v.identity }
7
+ end
8
+
9
+ def self.specific_view(name)
10
+ PGView.ours.by_name(name).first
11
+ end
12
+
13
+ def self.matviews
14
+ PGMatView.ours.to_a.sort_by { |v| v.identity }
15
+ end
16
+
17
+ def self.specific_matview(name)
18
+ PGMatView.ours.by_name(name).first
19
+ end
20
+
21
+ def self.triggers
22
+ PGTrigger.ours.to_a.sort_by { |t| t.identity }
23
+ end
24
+
25
+ def self.functions
26
+ PGFunction.ours.to_a.sort_by { |f| f.identity }
27
+ end
28
+
29
+ def self.constraints
30
+ PGConstraint.ours.to_a.sort_by { |f| f.identity }
31
+ end
32
+
33
+ def self.assets_dump
34
+ newline = "\n"
35
+ assets = ''
36
+
37
+ assets << '------------------------------ PG ASSETS ------------------------------' + newline
38
+ assets << '-- BRO, DON\'T MODIFY THIS DIRECTLY' + newline
39
+ assets << '-- IF YOU MODIFY THIS DIRECTLY,' + newline
40
+ assets << '-- YOU\'RE GONNA HAVE A BAD TIME' + newline
41
+ assets << '-----------------------------------------------------------------------' + newline
42
+
43
+ views.each do |v|
44
+ assets << newline
45
+ assets << newline
46
+ assets << '-----------------------------------------------------------------------' + newline
47
+ assets << '---------- VIEW: ' + v.identity + newline
48
+ assets << '-----------------------------------------------------------------------' + newline
49
+ assets << v.sql_for_reinstall
50
+ end
51
+
52
+ matviews.each do |mv|
53
+ assets << newline
54
+ assets << newline
55
+ assets << '-----------------------------------------------------------------------' + newline
56
+ assets << '---------- MATERIALIZED VIEW: ' + mv.identity + newline
57
+ assets << '-----------------------------------------------------------------------' + newline
58
+ assets << mv.sql_for_reinstall
59
+ end
60
+
61
+ functions.each do |f|
62
+ assets << newline
63
+ assets << newline
64
+ assets << '-----------------------------------------------------------------------' + newline
65
+ assets << '---------- FUNCTION: ' + f.identity + newline
66
+ assets << '-----------------------------------------------------------------------' + newline
67
+ assets << f.sql_for_reinstall + ';' + newline
68
+ end
69
+
70
+ triggers.each do |t|
71
+ assets << newline
72
+ assets << newline
73
+ assets << '-----------------------------------------------------------------------' + newline
74
+ assets << '---------- TRIGGER: ' + t.identity + newline
75
+ assets << '-----------------------------------------------------------------------' + newline
76
+ assets << t.sql_for_remove + ';' + newline
77
+ assets << newline
78
+ assets << t.sql_for_reinstall + ';' + newline
79
+ end
80
+
81
+ constraints.each do |c|
82
+ assets << newline
83
+ assets << newline
84
+ assets << '-----------------------------------------------------------------------' + newline
85
+ assets << '---------- CONSTRAINT: ' + c.identity + newline
86
+ assets << '-----------------------------------------------------------------------' + newline
87
+ assets << c.sql_for_reinstall + ';' + newline
88
+ end
89
+
90
+ assets
91
+ end
92
+
93
+ def self.assets_load(assets)
94
+ ActiveRecord::Base.transaction do
95
+ ActiveRecord::Base.connection.execute assets
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,3 @@
1
+ module PgAssets
2
+ VERSION = "1.0"
3
+ end
data/lib/pg_assets.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'pg'
2
+
3
+ require File.expand_path('../pg_assets/models/concerns/loadable_asset', __FILE__)
4
+ require File.expand_path('../pg_assets/models/pg_constraint', __FILE__)
5
+ require File.expand_path('../pg_assets/models/pg_trigger', __FILE__)
6
+ require File.expand_path('../pg_assets/models/pg_mat_view', __FILE__)
7
+ require File.expand_path('../pg_assets/models/pg_view', __FILE__)
8
+ require File.expand_path('../pg_assets/models/pg_function', __FILE__)
9
+ require File.expand_path('../pg_assets/services/pg_asset_manager', __FILE__)
10
+ require File.expand_path('../pg_assets/helpers/views_migration_helper', __FILE__)
11
+ require File.expand_path('../pg_assets/version', __FILE__)
12
+
13
+ module PgAssets
14
+ require 'pg_assets/railtie' if defined?(Rails)
15
+ end
@@ -0,0 +1,4 @@
1
+ CREATE TABLE table_with_check_constraint (
2
+ test integer CHECK (test > 0),
3
+ test2 text
4
+ );
@@ -0,0 +1,5 @@
1
+ CREATE TABLE table_with_multiple_constraint (
2
+ test integer CHECK (test > 1),
3
+ CHECK (test < 2),
4
+ test2 text UNIQUE NOT NULL
5
+ );
@@ -0,0 +1,4 @@
1
+ CREATE TABLE table_with_unique_constraint (
2
+ test integer UNIQUE,
3
+ test2 text
4
+ );
@@ -0,0 +1,5 @@
1
+ CREATE OR REPLACE FUNCTION function1() RETURNS text AS $$
2
+ BEGIN
3
+ RETURN 'so simple';
4
+ END;
5
+ $$ LANGUAGE plpgsql;
@@ -0,0 +1,5 @@
1
+ CREATE OR REPLACE FUNCTION function2(integer, text, integer) RETURNS text AS $$
2
+ BEGIN
3
+ RETURN 'not so simple';
4
+ END;
5
+ $$ LANGUAGE plpgsql;
@@ -0,0 +1,7 @@
1
+ CREATE TABLE table_for_view (
2
+ test integer,
3
+ test2 text
4
+ );
5
+
6
+ CREATE MATERIALIZED VIEW matview_from_table AS
7
+ SELECT test, test2 FROM table_for_view;
@@ -0,0 +1,2 @@
1
+ CREATE MATERIALIZED VIEW matview1 AS
2
+ SELECT 1;
@@ -0,0 +1,2 @@
1
+ CREATE MATERIALIZED VIEW matview2 AS
2
+ SELECT 1;
@@ -0,0 +1,12 @@
1
+ CREATE TABLE test (
2
+ test text
3
+ );
4
+
5
+ CREATE OR REPLACE FUNCTION womp() RETURNS trigger AS $$
6
+ BEGIN
7
+ RETURN NEW;
8
+ END;
9
+ $$ LANGUAGE plpgsql;
10
+
11
+ CREATE TRIGGER trigger1 BEFORE INSERT OR UPDATE ON test
12
+ FOR EACH ROW EXECUTE PROCEDURE womp();
@@ -0,0 +1,12 @@
1
+ CREATE TABLE test2 (
2
+ test text
3
+ );
4
+
5
+ CREATE OR REPLACE FUNCTION womp2() RETURNS trigger AS $$
6
+ BEGIN
7
+ RETURN NEW;
8
+ END;
9
+ $$ LANGUAGE plpgsql;
10
+
11
+ CREATE TRIGGER trigger2 BEFORE INSERT OR UPDATE ON test2
12
+ FOR EACH ROW EXECUTE PROCEDURE womp2();
@@ -0,0 +1,2 @@
1
+ CREATE OR REPLACE VIEW view1 AS
2
+ SELECT 1;
@@ -0,0 +1,2 @@
1
+ CREATE OR REPLACE VIEW view2 AS
2
+ SELECT 1;
@@ -0,0 +1,7 @@
1
+ CREATE TABLE table_for_view (
2
+ test integer,
3
+ test2 text
4
+ );
5
+
6
+ CREATE OR REPLACE VIEW view_from_table AS
7
+ SELECT test, test2 FROM table_for_view;
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Dummy::Application.load_tasks
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,5 @@
1
+ class ApplicationController < ActionController::Base
2
+ # Prevent CSRF attacks by raising an exception.
3
+ # For APIs, you may want to use :null_session instead.
4
+ protect_from_forgery with: :exception
5
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end