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.
- data/README.markdown +212 -0
- data/lib/core_ext/active_record/connection_adapters/abstract/schema_statements.rb +139 -0
- data/lib/core_ext/active_record/connection_adapters/postgresql_adapter.rb +135 -0
- data/lib/core_ext/active_record/schema_dumper.rb +40 -0
- data/lib/pg_power.rb +16 -0
- data/lib/pg_power/connection_adapters.rb +9 -0
- data/lib/pg_power/connection_adapters/abstract_adapter.rb +20 -0
- data/lib/pg_power/connection_adapters/abstract_adapter/comment_methods.rb +62 -0
- data/lib/pg_power/connection_adapters/abstract_adapter/foreigner_methods.rb +67 -0
- data/lib/pg_power/connection_adapters/abstract_adapter/index_methods.rb +6 -0
- data/lib/pg_power/connection_adapters/abstract_adapter/schema_methods.rb +18 -0
- data/lib/pg_power/connection_adapters/foreign_key_definition.rb +5 -0
- data/lib/pg_power/connection_adapters/index_definition.rb +6 -0
- data/lib/pg_power/connection_adapters/postgresql_adapter.rb +16 -0
- data/lib/pg_power/connection_adapters/postgresql_adapter/comment_methods.rb +79 -0
- data/lib/pg_power/connection_adapters/postgresql_adapter/foreigner_methods.rb +190 -0
- data/lib/pg_power/connection_adapters/postgresql_adapter/index_methods.rb +42 -0
- data/lib/pg_power/connection_adapters/postgresql_adapter/schema_methods.rb +22 -0
- data/lib/pg_power/connection_adapters/table.rb +17 -0
- data/lib/pg_power/connection_adapters/table/comment_methods.rb +58 -0
- data/lib/pg_power/connection_adapters/table/foreigner_methods.rb +51 -0
- data/lib/pg_power/engine.rb +46 -0
- data/lib/pg_power/migration.rb +4 -0
- data/lib/pg_power/migration/command_recorder.rb +13 -0
- data/lib/pg_power/migration/command_recorder/comment_methods.rb +52 -0
- data/lib/pg_power/migration/command_recorder/foreigner_methods.rb +29 -0
- data/lib/pg_power/migration/command_recorder/schema_methods.rb +39 -0
- data/lib/pg_power/schema_dumper.rb +21 -0
- data/lib/pg_power/schema_dumper/comment_methods.rb +36 -0
- data/lib/pg_power/schema_dumper/foreigner_methods.rb +58 -0
- data/lib/pg_power/schema_dumper/schema_methods.rb +51 -0
- data/lib/pg_power/tools.rb +56 -0
- data/lib/pg_power/version.rb +4 -0
- data/lib/tasks/pg_power_tasks.rake +4 -0
- 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,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
|