pg_power 1.0.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 (35) hide show
  1. data/README.markdown +212 -0
  2. data/lib/core_ext/active_record/connection_adapters/abstract/schema_statements.rb +139 -0
  3. data/lib/core_ext/active_record/connection_adapters/postgresql_adapter.rb +135 -0
  4. data/lib/core_ext/active_record/schema_dumper.rb +40 -0
  5. data/lib/pg_power.rb +16 -0
  6. data/lib/pg_power/connection_adapters.rb +9 -0
  7. data/lib/pg_power/connection_adapters/abstract_adapter.rb +20 -0
  8. data/lib/pg_power/connection_adapters/abstract_adapter/comment_methods.rb +62 -0
  9. data/lib/pg_power/connection_adapters/abstract_adapter/foreigner_methods.rb +67 -0
  10. data/lib/pg_power/connection_adapters/abstract_adapter/index_methods.rb +6 -0
  11. data/lib/pg_power/connection_adapters/abstract_adapter/schema_methods.rb +18 -0
  12. data/lib/pg_power/connection_adapters/foreign_key_definition.rb +5 -0
  13. data/lib/pg_power/connection_adapters/index_definition.rb +6 -0
  14. data/lib/pg_power/connection_adapters/postgresql_adapter.rb +16 -0
  15. data/lib/pg_power/connection_adapters/postgresql_adapter/comment_methods.rb +79 -0
  16. data/lib/pg_power/connection_adapters/postgresql_adapter/foreigner_methods.rb +190 -0
  17. data/lib/pg_power/connection_adapters/postgresql_adapter/index_methods.rb +42 -0
  18. data/lib/pg_power/connection_adapters/postgresql_adapter/schema_methods.rb +22 -0
  19. data/lib/pg_power/connection_adapters/table.rb +17 -0
  20. data/lib/pg_power/connection_adapters/table/comment_methods.rb +58 -0
  21. data/lib/pg_power/connection_adapters/table/foreigner_methods.rb +51 -0
  22. data/lib/pg_power/engine.rb +46 -0
  23. data/lib/pg_power/migration.rb +4 -0
  24. data/lib/pg_power/migration/command_recorder.rb +13 -0
  25. data/lib/pg_power/migration/command_recorder/comment_methods.rb +52 -0
  26. data/lib/pg_power/migration/command_recorder/foreigner_methods.rb +29 -0
  27. data/lib/pg_power/migration/command_recorder/schema_methods.rb +39 -0
  28. data/lib/pg_power/schema_dumper.rb +21 -0
  29. data/lib/pg_power/schema_dumper/comment_methods.rb +36 -0
  30. data/lib/pg_power/schema_dumper/foreigner_methods.rb +58 -0
  31. data/lib/pg_power/schema_dumper/schema_methods.rb +51 -0
  32. data/lib/pg_power/tools.rb +56 -0
  33. data/lib/pg_power/version.rb +4 -0
  34. data/lib/tasks/pg_power_tasks.rake +4 -0
  35. metadata +213 -0
@@ -0,0 +1,42 @@
1
+ # Provides methods to extend {ActiveRecord::ConnectionAdapters::SchemaStatements}
2
+ # to support index features.
3
+ module PgPower::ConnectionAdapters::PostgreSQLAdapter::IndexMethods
4
+ def supports_partial_index?
5
+ true
6
+ end
7
+
8
+ # Overrides ActiveRecord::ConnectionAdapters::SchemaStatements.index_name
9
+ # to support schema notation. Converts dots in index name to underscores.
10
+ #
11
+ # === Example
12
+ # add_index 'demography.citizens', :country_id
13
+ # # produces
14
+ # CREATE INDEX "index_demography_citizens_on_country_id" ON "demography"."citizens" ("country_id")
15
+ # # instead of
16
+ # CREATE INDEX "index_demography.citizens_on_country_id" ON "demography"."citizens" ("country_id")
17
+ #
18
+ def index_name(table_name, options) #:nodoc:
19
+ super.gsub('.','_')
20
+ end
21
+
22
+ # Overrides ActiveRecord::ConnectionAdapters::SchemaStatements.index_name_for_remove
23
+ # to support schema notation. Prepends the schema name to the index name.
24
+ #
25
+ # === Example
26
+ # drop_index 'demography.citizens', :country_id
27
+ # # produces
28
+ # DROP INDEX "demography"."index_demography_citizens_on_country_id"
29
+ # # instead of
30
+ # DROP INDEX "index_demography_citizens_on_country_id"
31
+ #
32
+ def index_name_for_remove(table_name, options = {})
33
+ index_name = super
34
+
35
+ if table_name.include?('.') # schema notation
36
+ schema = table_name.split('.').first
37
+ "#{schema}.#{index_name}"
38
+ else
39
+ index_name
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,22 @@
1
+ # Provides methods to extend {ActiveRecord::ConnectionAdapters::PostgreSQLAdapter}
2
+ # to support schemas feature.
3
+ module PgPower::ConnectionAdapters::PostgreSQLAdapter::SchemaMethods
4
+ # Creates new schema in DB.
5
+ # @param [String] schema_name
6
+ def create_schema(schema_name)
7
+ ::PgPower::Tools.create_schema(schema_name)
8
+ end
9
+
10
+ # Drops schema in DB.
11
+ # @param [String] schema_name
12
+ def drop_schema(schema_name)
13
+ ::PgPower::Tools.drop_schema(schema_name)
14
+ end
15
+
16
+ # Move table to another schema
17
+ # @param [String] table table name. Can be with schema prefix e.g. "demography.people"
18
+ # @param [String] schema schema where table should be moved to.
19
+ def move_table_to_schema(table, schema)
20
+ ::PgPower::Tools.move_table_to_schema(table, schema)
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ # Provides methods to extend {ActiveRecord::ConnectionAdapters::Table}
2
+ # to support pg_power features.
3
+ module PgPower::ConnectionAdapters::Table
4
+ extend ActiveSupport::Autoload
5
+ extend ActiveSupport::Concern
6
+
7
+ autoload :CommentMethods
8
+ autoload :ForeignerMethods
9
+
10
+ include CommentMethods
11
+ include ForeignerMethods
12
+
13
+
14
+ included do
15
+ alias_method_chain :references, :foreign_keys
16
+ end
17
+ end
@@ -0,0 +1,58 @@
1
+ # Provides methods to extend {ActiveRecord::ConnectionAdapters::Table}
2
+ # to support comments feature.
3
+ module PgPower::ConnectionAdapters::Table::CommentMethods
4
+ # Sets the comment on the table
5
+ #
6
+ # ===== Example
7
+ # ====== Set comment on table
8
+ # t.set_table_comment 'This table stores phone numbers that conform to the North American Numbering Plan.'
9
+ def set_table_comment(comment)
10
+ @base.set_table_comment(@table_name, comment)
11
+ end
12
+
13
+ # Removes any comment from the table
14
+ #
15
+ # ===== Example
16
+ # ====== Remove table comment
17
+ # t.remove_table_comment
18
+ def remove_table_comment
19
+ @base.remove_table_comment(@table_name)
20
+ end
21
+
22
+ # Sets the comment for a given column
23
+ #
24
+ # ===== Example
25
+ # ====== Set comment on the npa column
26
+ # t.set_column_comment :npa, 'Numbering Plan Area Code - Allowed ranges: [2-9] for first digit, [0-9] for second and third digit.'
27
+ def set_column_comment(column_name, comment)
28
+ @base.set_column_comment(@table_name, column_name, comment)
29
+ end
30
+
31
+ # Sets comments on multiple columns. 'comments' is a hash of column_name => comment pairs.
32
+ #
33
+ # ===== Example
34
+ # ====== Setting comments on the columns of the phone_numbers table
35
+ # t.set_column_comments :npa => 'Numbering Plan Area Code - Allowed ranges: [2-9] for first digit, [0-9] for second and third digit.',
36
+ # :nxx => 'Central Office Number'
37
+ def set_column_comments(comments)
38
+ @base.set_column_comments(@table_name, comments)
39
+ end
40
+
41
+ # Removes any comment for a given column
42
+ #
43
+ # ===== Example
44
+ # ====== Remove comment from the npa column
45
+ # t.remove_column_comment :npa
46
+ def remove_column_comment(column_name)
47
+ @base.remove_column_comment(@table_name, column_name)
48
+ end
49
+
50
+ # Removes any comments from the given columns
51
+ #
52
+ # ===== Example
53
+ # ====== Remove comment from the npa and nxx columns
54
+ # t.remove_column_comment :npa, :nxx
55
+ def remove_column_comments(*column_names)
56
+ @base.remove_column_comments(@table_name, *column_names)
57
+ end
58
+ end
@@ -0,0 +1,51 @@
1
+ # Provides methods to extend {ActiveRecord::ConnectionAdapters::Table}
2
+ # to support foreign keys feature.
3
+ module PgPower::ConnectionAdapters::Table::ForeignerMethods
4
+ # Adds a new foreign key to the table. +to_table+ can be a single Symbol, or
5
+ # an Array of Symbols. See SchemaStatements#add_foreign_key
6
+ #
7
+ # ===== Examples
8
+ # ====== Creating a simple foreign key
9
+ # t.foreign_key(:people)
10
+ # ====== Defining the column
11
+ # t.foreign_key(:people, :column => :sender_id)
12
+ # ====== Creating a named foreign key
13
+ # t.foreign_key(:people, :column => :sender_id, :name => 'sender_foreign_key')
14
+ # ====== Defining the column of the +to_table+.
15
+ # t.foreign_key(:people, :column => :sender_id, :primary_key => :person_id)
16
+ def foreign_key(to_table, options = {})
17
+ @base.add_foreign_key(@table_name, to_table, options)
18
+ end
19
+
20
+ # Remove the given foreign key from the table.
21
+ #
22
+ # ===== Examples
23
+ # ====== Remove the suppliers_company_id_fk in the suppliers table.
24
+ # change_table :suppliers do |t|
25
+ # t.remove_foreign_key :companies
26
+ # end
27
+ # ====== Remove the foreign key named accounts_branch_id_fk in the accounts table.
28
+ # change_table :accounts do |t|
29
+ # t.remove_foreign_key :column => :branch_id
30
+ # end
31
+ # ====== Remove the foreign key named party_foreign_key in the accounts table.
32
+ # change_table :accounts do |t|
33
+ # t.remove_index :name => :party_foreign_key
34
+ # end
35
+ def remove_foreign_key(options)
36
+ @base.remove_foreign_key(@table_name, options)
37
+ end
38
+
39
+ # Deprecated
40
+ def references_with_foreign_keys(*args)
41
+ options = args.extract_options!
42
+
43
+ if fk_options = options.delete(:foreign_key)
44
+ p ActiveSupport::Deprecation.send(:deprecation_message, caller,
45
+ ":foreign_key in t.references is deprecated. " \
46
+ "Use t.foreign_key instead")
47
+ end
48
+
49
+ references_without_foreign_keys(*(args.dup << options))
50
+ end
51
+ end
@@ -0,0 +1,46 @@
1
+ module PgPower
2
+ # :nodoc
3
+ class Engine < Rails::Engine
4
+
5
+ initializer 'pg_power' do
6
+ ActiveSupport.on_load(:active_record) do
7
+ # load monkey patches
8
+ ['schema_dumper',
9
+ 'connection_adapters/postgresql_adapter',
10
+ 'connection_adapters/abstract/schema_statements'].each do |path|
11
+ require PgPower::Engine.root + 'lib/core_ext/active_record/' + path
12
+ end
13
+
14
+ ActiveRecord::SchemaDumper.class_eval do
15
+ include PgPower::SchemaDumper
16
+ end
17
+
18
+ if defined?(ActiveRecord::Migration::CommandRecorder)
19
+ ActiveRecord::Migration::CommandRecorder.class_eval do
20
+ include ::PgPower::Migration::CommandRecorder
21
+ end
22
+ end
23
+
24
+ ActiveRecord::ConnectionAdapters::Table.module_eval do
25
+ include PgPower::ConnectionAdapters::Table
26
+ end
27
+
28
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
29
+ include PgPower::ConnectionAdapters::AbstractAdapter
30
+ end
31
+
32
+ if defined?(ActiveRecord::ConnectionAdapters::JdbcAdapter)
33
+ sql_adapter_class = ActiveRecord::ConnectionAdapters::JdbcAdapter
34
+ else
35
+ sql_adapter_class = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
36
+ end
37
+
38
+ sql_adapter_class.class_eval do
39
+ include PgPower::ConnectionAdapters::PostgreSQLAdapter
40
+ end
41
+
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,4 @@
1
+ module PgPower::Migration # :nordoc:
2
+ extend ActiveSupport::Autoload
3
+ autoload :CommandRecorder
4
+ end
@@ -0,0 +1,13 @@
1
+ # Provides methods to extend {ActiveRecord::Migration::CommandRecorder} to
2
+ # support pg_power features.
3
+ module PgPower::Migration::CommandRecorder
4
+ extend ActiveSupport::Autoload
5
+
6
+ autoload :SchemaMethods
7
+ autoload :CommentMethods
8
+ autoload :ForeignerMethods
9
+
10
+ include SchemaMethods
11
+ include CommentMethods
12
+ include ForeignerMethods
13
+ end
@@ -0,0 +1,52 @@
1
+ # Provides methods to extend {ActiveRecord::Migration::CommandRecorder} to
2
+ # support comments feature.
3
+ module PgPower::Migration::CommandRecorder::CommentMethods
4
+ # :nodoc:
5
+ def set_table_comment(*args)
6
+ record(:set_table_comment, args)
7
+ end
8
+
9
+ # :nodoc:
10
+ def remove_table_comment(*args)
11
+ record(:remove_table_comments, args)
12
+ end
13
+
14
+ # :nodoc:
15
+ def set_column_comment(*args)
16
+ record(:set_column_comment, args)
17
+ end
18
+
19
+ # :nodoc:
20
+ def set_column_comments(*args)
21
+ record(:set_column_comments, args)
22
+ end
23
+
24
+ # :nodoc:
25
+ def remove_column_comment(*args)
26
+ record(:remove_column_comment, args)
27
+ end
28
+
29
+ # :nodoc:
30
+ def remove_column_comments(*args)
31
+ record(:remove_column_comments, args)
32
+ end
33
+
34
+ # :nodoc:
35
+ def invert_set_table_comment(args)
36
+ table_name = args.first
37
+ [:remove_table_comment, [table_name]]
38
+ end
39
+
40
+ # :nodoc:
41
+ def invert_set_column_comment(args)
42
+ table_name = args[0]
43
+ column_name = args[1]
44
+ [:remove_column_comment, [table_name, column_name]]
45
+ end
46
+
47
+ # :nodoc:
48
+ def invert_set_column_comments(args)
49
+ i_args = [args[0]] + args[1].collect{|name, value| name }
50
+ [:remove_column_comments, i_args]
51
+ end
52
+ end
@@ -0,0 +1,29 @@
1
+ # Provides methods to extend {ActiveRecord::Migration::CommandRecorder} to
2
+ # support foreign keys feature.
3
+ module PgPower::Migration::CommandRecorder::ForeignerMethods
4
+ # :nodoc:
5
+ def add_foreign_key(*args)
6
+ record(:add_foreign_key, args)
7
+ end
8
+
9
+ # :nodoc:
10
+ def remove_foreign_key(*args)
11
+ record(:remove_foreign_key, args)
12
+ end
13
+
14
+ # :nodoc:
15
+ def invert_add_foreign_key(args)
16
+ from_table, to_table, add_options = *args
17
+ add_options ||= {}
18
+
19
+ if add_options[:name]
20
+ options = {:name => add_options[:name]}
21
+ elsif add_options[:column]
22
+ options = {:column => add_options[:column]}
23
+ else
24
+ options = to_table
25
+ end
26
+
27
+ [:remove_foreign_key, [from_table, options]]
28
+ end
29
+ end
@@ -0,0 +1,39 @@
1
+ # Provides methods to extend {ActiveRecord::Migration::CommandRecorder} to
2
+ # support multi schemas feature.
3
+ module PgPower::Migration::CommandRecorder::SchemaMethods
4
+ # :nodoc:
5
+ def create_schema(*args)
6
+ record(:create_schema, args)
7
+ end
8
+
9
+ # :nodoc:
10
+ def drop_schema(*args)
11
+ record(:drop_schema, args)
12
+ end
13
+
14
+ # :nodoc:
15
+ def move_table_to_schema(*args)
16
+ record(:move_table_to_schema, args)
17
+ end
18
+
19
+ # :nodoc:
20
+ def invert_create_schema(args)
21
+ [:drop_schema, [args.first]]
22
+ end
23
+
24
+ # :nodoc:
25
+ def invert_drop_schema(args)
26
+ [:create_schema, [args.first]]
27
+ end
28
+
29
+ # :nodoc:
30
+ def invert_move_table_to_schema(args)
31
+ table_name = args.first
32
+ current_schema = args.second
33
+
34
+ new_schema, table = ::PgPower::Tools.to_schema_and_table(table_name)
35
+
36
+ invert_args = ["#{current_schema}.#{table}", new_schema]
37
+ [:move_table_to_schema, invert_args]
38
+ end
39
+ end
@@ -0,0 +1,21 @@
1
+ # Provides methods to extend {ActiveRecord::SchemaDumper} to appropriately
2
+ # build schema.rb file with schemas, foreign keys and comments on columns
3
+ # and tables.
4
+ module PgPower::SchemaDumper
5
+ extend ActiveSupport::Autoload
6
+ extend ActiveSupport::Concern
7
+
8
+ autoload :CommentMethods
9
+ autoload :SchemaMethods
10
+ autoload :ForeignerMethods
11
+
12
+ include CommentMethods
13
+ include SchemaMethods
14
+ include ForeignerMethods
15
+
16
+ included do
17
+ alias_method_chain :tables, :schemas
18
+ alias_method_chain :tables, :comments
19
+ alias_method_chain :tables, :foreign_keys
20
+ end
21
+ end
@@ -0,0 +1,36 @@
1
+ # Extends ActiveRecord::SchemaDumper class to dump comments on tables and columns.
2
+ module PgPower::SchemaDumper::CommentMethods
3
+ # Hooks {ActiveRecord::SchemaDumper#table} method to dump comments on
4
+ # table and columns.
5
+ def tables_with_comments(stream)
6
+ tables_without_comments(stream)
7
+
8
+ table_names = @connection.tables.sort
9
+ table_names += get_non_public_schema_table_names.sort
10
+
11
+ table_names.each do |table_name|
12
+ dump_comments(table_name, stream)
13
+ end
14
+ end
15
+
16
+ # Finds all comments related to passed table and writes appropriated
17
+ # statements to stream.
18
+ def dump_comments(table_name, stream)
19
+ unless (comments = @connection.comments(table_name)).empty?
20
+ comment_statements = comments.map do |row|
21
+ column_name = row[0]
22
+ comment = row[1].gsub(/'/, "\\\\'")
23
+ if column_name
24
+ " set_column_comment '#{table_name}', '#{column_name}', '#{comment}'"
25
+ else
26
+ " set_table_comment '#{table_name}', '#{comment}'"
27
+ end
28
+
29
+ end
30
+
31
+ stream.puts comment_statements.join("\n")
32
+ stream.puts
33
+ end
34
+ end
35
+ private :dump_comments
36
+ end