pg_saurus 3.5.0 → 3.6.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.
- checksums.yaml +5 -5
- data/lib/core_ext/active_record/connection_adapters/abstract/schema_statements.rb +157 -155
- data/lib/pg_saurus/connection_adapters/abstract_adapter.rb +0 -6
- data/lib/pg_saurus/connection_adapters/abstract_adapter/schema_methods.rb +4 -4
- data/lib/pg_saurus/connection_adapters/postgresql_adapter.rb +0 -10
- data/lib/pg_saurus/connection_adapters/postgresql_adapter/foreign_key_methods.rb +7 -7
- data/lib/pg_saurus/connection_adapters/postgresql_adapter/schema_methods.rb +7 -7
- data/lib/pg_saurus/create_index_concurrently.rb +2 -9
- data/lib/pg_saurus/engine.rb +17 -2
- data/lib/pg_saurus/migration/set_role_method.rb +30 -28
- data/lib/pg_saurus/schema_dumper.rb +0 -13
- data/lib/pg_saurus/schema_dumper/comment_methods.rb +2 -2
- data/lib/pg_saurus/schema_dumper/extension_methods.rb +2 -2
- data/lib/pg_saurus/schema_dumper/foreign_key_methods.rb +1 -1
- data/lib/pg_saurus/schema_dumper/function_methods.rb +2 -2
- data/lib/pg_saurus/schema_dumper/schema_methods.rb +2 -2
- data/lib/pg_saurus/schema_dumper/trigger_methods.rb +2 -2
- data/lib/pg_saurus/schema_dumper/view_methods.rb +2 -2
- data/lib/pg_saurus/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a04193fb420ad671f1ee5a9a43a051ff6bbeeddde6dbd2f113cf6c4eff1dbfc8
|
4
|
+
data.tar.gz: 4433591bdb134a720112d186eaf78f96547054862ef56ffb3aa7f1f6622a211a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 365019237474f3eaf8084a5bce6ad12ed641f80fd1a931a36beca0694813a965d708fc86e9e36e7038e8ea02ba9a4706a3b66f3012fffefe137b0b692ddf32b5
|
7
|
+
data.tar.gz: 0b917b79f68c042dbfe6c47539c58e48a1d0b13f6017602280cf8ef0ff73ed80549658ef137934751225d22e322ed4230f09a719509c36168a4b526dbcec6cea
|
@@ -1,184 +1,186 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module ConnectionAdapters # :nodoc:
|
3
|
-
module
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
3
|
+
module PostgreSQL # :nodoc:
|
4
|
+
module SchemaStatements # :nodoc:
|
5
|
+
# Regexp used to find the function name and function argument of a
|
6
|
+
# function call:
|
7
|
+
FUNCTIONAL_INDEX_REGEXP = /(\w+)\(((?:'.+'(?:::\w+)?, *)*)(\w+)\)/
|
8
|
+
|
9
|
+
# Regexp used to find the operator name (or operator string, e.g. "DESC NULLS LAST"):
|
10
|
+
OPERATOR_REGEXP = /(.+?)\s([\w\s]+)$/
|
11
|
+
|
12
|
+
# Redefine original add_index method to handle :concurrently option.
|
13
|
+
#
|
14
|
+
# Adds a new index to the table. +column_name+ can be a single Symbol, or
|
15
|
+
# an Array of Symbols.
|
16
|
+
#
|
17
|
+
# ====== Creating a partial index
|
18
|
+
# add_index(:accounts, [:branch_id, :party_id], :using => 'BTree'
|
19
|
+
# :unique => true, :concurrently => true, :where => 'active')
|
20
|
+
# generates
|
21
|
+
# CREATE UNIQUE INDEX CONCURRENTLY
|
22
|
+
# index_accounts_on_branch_id_and_party_id
|
23
|
+
# ON
|
24
|
+
# accounts(branch_id, party_id)
|
25
|
+
# WHERE
|
26
|
+
# active
|
27
|
+
#
|
28
|
+
def add_index(table_name, column_name, options = {})
|
29
|
+
creation_method = options.delete(:concurrently) ? 'CONCURRENTLY' : nil
|
30
|
+
|
31
|
+
# Whether to skip the quoting of columns. Used only for expressions like JSON indexes in which
|
32
|
+
# the column is difficult to target for quoting.
|
33
|
+
skip_column_quoting = options.delete(:skip_column_quoting) or false
|
34
|
+
|
35
|
+
index_name,
|
36
|
+
index_type,
|
37
|
+
index_columns,
|
38
|
+
index_options,
|
39
|
+
index_algorithm,
|
40
|
+
index_using = add_index_options(table_name, column_name, options)
|
41
|
+
|
42
|
+
# GOTCHA:
|
43
|
+
# It ensures that there is no existing index only for the case when the index
|
44
|
+
# is created concurrently to avoid changing the error behavior for default
|
45
|
+
# index creation.
|
46
|
+
# -- zekefast 2012-09-25
|
47
|
+
# GOTCHA:
|
48
|
+
# This check prevents invalid index creation, so after migration failed
|
49
|
+
# here there is no need to go to database and clean it from invalid
|
50
|
+
# indexes. But note that this handles only one of the cases when index
|
51
|
+
# creation can fail!!! All other case should be procesed manually.
|
52
|
+
# -- zekefast 2012-09-25
|
53
|
+
if creation_method.present? && index_exists?(table_name, column_name, options)
|
54
|
+
raise ::PgSaurus::IndexExistsError,
|
55
|
+
"Index #{index_name} for `#{table_name}.#{column_name}` " \
|
56
|
+
"column can not be created concurrently, because such index already exists."
|
57
|
+
end
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
59
|
+
statements = []
|
60
|
+
statements << "CREATE #{index_type} INDEX"
|
61
|
+
statements << creation_method if creation_method.present?
|
62
|
+
statements << index_algorithm if index_algorithm.present?
|
63
|
+
statements << quote_column_name(index_name)
|
64
|
+
statements << "ON"
|
65
|
+
statements << quote_table_name(table_name)
|
66
|
+
statements << index_using if index_using.present?
|
67
|
+
statements << "(#{index_columns})" if index_columns.present? unless skip_column_quoting
|
68
|
+
statements << "(#{column_name})" if column_name.present? and skip_column_quoting
|
69
|
+
statements << index_options if index_options.present?
|
70
|
+
|
71
|
+
sql = statements.join(' ')
|
72
|
+
execute(sql)
|
73
|
+
end
|
73
74
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
75
|
+
# Check to see if an index exists on a table for a given index definition.
|
76
|
+
#
|
77
|
+
# === Examples
|
78
|
+
# # Check that a partial index exists
|
79
|
+
# index_exists?(:suppliers, :company_id, :where => 'active')
|
80
|
+
#
|
81
|
+
# # GIVEN: 'index_suppliers_on_company_id' UNIQUE, btree (company_id) WHERE active
|
82
|
+
# index_exists?(:suppliers, :company_id, :unique => true, :where => 'active') => true
|
83
|
+
# index_exists?(:suppliers, :company_id, :unique => true) => false
|
84
|
+
#
|
85
|
+
def index_exists?(table_name, column_name, options = {})
|
86
|
+
column_names = Array.wrap(column_name)
|
87
|
+
index_name = options.key?(:name) ? options[:name].to_s : index_name(table_name, :column => column_names)
|
88
|
+
|
89
|
+
# Always compare the index name
|
90
|
+
default_comparator = lambda { |index| index.name == index_name }
|
91
|
+
comparators = [default_comparator]
|
92
|
+
|
93
|
+
# Add a comparator for each index option that is part of the query
|
94
|
+
index_options = [:unique, :where]
|
95
|
+
index_options.each do |index_option|
|
96
|
+
comparators << if options.key?(index_option)
|
97
|
+
lambda do |index|
|
98
|
+
pg_where_clause = index.send(index_option)
|
99
|
+
# pg does nothing to boolean clauses, e.g. 'where active' => 'where active'
|
100
|
+
if pg_where_clause.is_a?(TrueClass) or pg_where_clause.is_a?(FalseClass)
|
101
|
+
pg_where_clause == options[index_option]
|
102
|
+
else
|
103
|
+
# pg adds parentheses around non-boolean clauses, e.g. 'where color IS NULL' => 'where (color is NULL)'
|
104
|
+
pg_where_clause.gsub!(/[()]/,'')
|
105
|
+
# pg casts string comparison ::text. e.g. "where color = 'black'" => "where ((color)::text = 'black'::text)"
|
106
|
+
pg_where_clause.gsub!(/::text/,'')
|
107
|
+
# prevent case from impacting the comparison
|
108
|
+
pg_where_clause.downcase == options[index_option].downcase
|
109
|
+
end
|
108
110
|
end
|
111
|
+
else
|
112
|
+
# If the given index_option is not an argument to the index_exists? query,
|
113
|
+
# select only those pg indexes that do not have the component
|
114
|
+
lambda { |index| index.send(index_option).blank? }
|
109
115
|
end
|
110
|
-
else
|
111
|
-
# If the given index_option is not an argument to the index_exists? query,
|
112
|
-
# select only those pg indexes that do not have the component
|
113
|
-
lambda { |index| index.send(index_option).blank? }
|
114
116
|
end
|
115
|
-
end
|
116
117
|
|
117
|
-
|
118
|
-
|
119
|
-
|
118
|
+
# Search all indexes for any that match all comparators
|
119
|
+
indexes(table_name).any? do |index|
|
120
|
+
comparators.inject(true) { |ret, comparator| ret && comparator.call(index) }
|
121
|
+
end
|
120
122
|
end
|
121
|
-
end
|
122
123
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
124
|
+
# Derive the name of the index from the given table name and options hash.
|
125
|
+
def index_name(table_name, options) #:nodoc:
|
126
|
+
if Hash === options # legacy support
|
127
|
+
if options[:column]
|
128
|
+
column_names = Array.wrap(options[:column]).map {|c| expression_index_name(c)}
|
129
|
+
"index_#{table_name}_on_#{column_names * '_and_'}"
|
130
|
+
elsif options[:name]
|
131
|
+
options[:name]
|
132
|
+
else
|
133
|
+
raise ArgumentError, "You must specify the index name"
|
134
|
+
end
|
131
135
|
else
|
132
|
-
|
136
|
+
index_name(table_name, :column => options)
|
133
137
|
end
|
134
|
-
else
|
135
|
-
index_name(table_name, :column => options)
|
136
138
|
end
|
137
|
-
end
|
138
139
|
|
139
|
-
|
140
|
-
|
141
|
-
|
140
|
+
# Override super method to provide support for expression column names.
|
141
|
+
def quoted_columns_for_index(column_names, options = {})
|
142
|
+
column_names.map do |name|
|
143
|
+
column_name, operator_name = split_column_name(name)
|
144
|
+
|
145
|
+
result_name = if column_name =~ FUNCTIONAL_INDEX_REGEXP
|
146
|
+
"#{$1}(#{$2}#{quote_column_name($3)})"
|
147
|
+
else
|
148
|
+
quote_column_name(column_name)
|
149
|
+
end
|
150
|
+
|
151
|
+
result_name += " " + operator_name if operator_name
|
152
|
+
|
153
|
+
result_name
|
154
|
+
end
|
155
|
+
end
|
156
|
+
protected :quoted_columns_for_index
|
157
|
+
|
158
|
+
# Map an expression to a name appropriate for an index.
|
159
|
+
def expression_index_name(name)
|
142
160
|
column_name, operator_name = split_column_name(name)
|
143
161
|
|
144
162
|
result_name = if column_name =~ FUNCTIONAL_INDEX_REGEXP
|
145
|
-
"#{$1}
|
163
|
+
"#{$1.downcase}_#{$3}"
|
146
164
|
else
|
147
|
-
|
165
|
+
column_name
|
148
166
|
end
|
149
167
|
|
150
|
-
result_name += "
|
168
|
+
result_name += "_" + operator_name.parameterize.underscore if operator_name
|
151
169
|
|
152
170
|
result_name
|
153
171
|
end
|
154
|
-
|
155
|
-
protected :quoted_columns_for_index
|
156
|
-
|
157
|
-
# Map an expression to a name appropriate for an index.
|
158
|
-
def expression_index_name(name)
|
159
|
-
column_name, operator_name = split_column_name(name)
|
172
|
+
private :expression_index_name
|
160
173
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
result_name
|
170
|
-
end
|
171
|
-
private :expression_index_name
|
172
|
-
|
173
|
-
# Split column name to name and operator class if possible.
|
174
|
-
def split_column_name(name)
|
175
|
-
if name =~ OPERATOR_REGEXP
|
176
|
-
return $1, $2
|
177
|
-
else
|
178
|
-
return name, nil
|
174
|
+
# Split column name to name and operator class if possible.
|
175
|
+
def split_column_name(name)
|
176
|
+
if name =~ OPERATOR_REGEXP
|
177
|
+
return $1, $2
|
178
|
+
else
|
179
|
+
return name, nil
|
180
|
+
end
|
179
181
|
end
|
182
|
+
private :split_column_name
|
180
183
|
end
|
181
|
-
private :split_column_name
|
182
184
|
end
|
183
185
|
end
|
184
186
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# Extends ActiveRecord::ConnectionAdapters::AbstractAdapter class.
|
2
2
|
module PgSaurus::ConnectionAdapters::AbstractAdapter
|
3
3
|
extend ActiveSupport::Autoload
|
4
|
-
extend ActiveSupport::Concern
|
5
4
|
|
6
5
|
autoload :CommentMethods
|
7
6
|
autoload :SchemaMethods
|
@@ -14,9 +13,4 @@ module PgSaurus::ConnectionAdapters::AbstractAdapter
|
|
14
13
|
include IndexMethods
|
15
14
|
include FunctionMethods
|
16
15
|
include TriggerMethods
|
17
|
-
|
18
|
-
included do
|
19
|
-
alias_method_chain :create_table, :schema_option
|
20
|
-
alias_method_chain :drop_table , :schema_option
|
21
|
-
end
|
22
16
|
end
|
@@ -3,18 +3,18 @@
|
|
3
3
|
module PgSaurus::ConnectionAdapters::AbstractAdapter::SchemaMethods
|
4
4
|
|
5
5
|
# Provide :schema option to +create_table+ method.
|
6
|
-
def
|
6
|
+
def create_table(table_name, options = {}, &block)
|
7
7
|
options = options.dup
|
8
8
|
schema_name = options.delete(:schema)
|
9
9
|
table_name = "#{schema_name}.#{table_name}" if schema_name
|
10
|
-
|
10
|
+
super(table_name, options, &block)
|
11
11
|
end
|
12
12
|
|
13
13
|
# Provide :schema option to +drop_table+ method.
|
14
|
-
def
|
14
|
+
def drop_table(table_name, options = {})
|
15
15
|
options = options.dup
|
16
16
|
schema_name = options.delete(:schema)
|
17
17
|
table_name = "#{schema_name}.#{table_name}" if schema_name
|
18
|
-
|
18
|
+
super(table_name, options)
|
19
19
|
end
|
20
20
|
end
|
@@ -26,16 +26,6 @@ module PgSaurus::ConnectionAdapters::PostgreSQLAdapter
|
|
26
26
|
include TriggerMethods
|
27
27
|
|
28
28
|
included do
|
29
|
-
alias_method_chain :tables, :non_public_schema_tables
|
30
|
-
alias_method_chain :add_index, :concurrently
|
31
|
-
alias_method_chain :drop_table, :schema_option
|
32
|
-
alias_method_chain :rename_table, :schema_option
|
33
|
-
|
34
|
-
alias_method_chain :add_foreign_key, :index
|
35
|
-
alias_method_chain :remove_foreign_key, :index
|
36
|
-
alias_method_chain :foreign_key_column_for, :schema
|
37
|
-
alias_method_chain :foreign_keys, :schema
|
38
|
-
|
39
29
|
::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.module_eval do
|
40
30
|
def from_schema
|
41
31
|
options[:from_schema] || 'public'
|
@@ -24,7 +24,7 @@ module PgSaurus # :nodoc:
|
|
24
24
|
# See activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
|
25
25
|
# Creates index on the FK column by default. Pass in the option :exclude_index => true
|
26
26
|
# to disable this.
|
27
|
-
def
|
27
|
+
def add_foreign_key(from_table, to_table, options = {})
|
28
28
|
exclude_index = (options.has_key?(:exclude_index) ? options.delete(:exclude_index) : false)
|
29
29
|
column = options[:column] || foreign_key_column_for(to_table)
|
30
30
|
|
@@ -34,7 +34,7 @@ module PgSaurus # :nodoc:
|
|
34
34
|
" Use :exclude_index => true when adding the foreign key."
|
35
35
|
end
|
36
36
|
|
37
|
-
|
37
|
+
super from_table, to_table, options
|
38
38
|
|
39
39
|
unless exclude_index
|
40
40
|
add_index from_table, column
|
@@ -42,24 +42,24 @@ module PgSaurus # :nodoc:
|
|
42
42
|
end
|
43
43
|
|
44
44
|
# See activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
|
45
|
-
def
|
45
|
+
def remove_foreign_key(from_table, options_or_to_table = {})
|
46
46
|
if options_or_to_table.is_a?(Hash) && options_or_to_table[:remove_index]
|
47
47
|
column = options_or_to_table[:column]
|
48
48
|
remove_index from_table, column
|
49
49
|
end
|
50
50
|
|
51
|
-
|
51
|
+
super(from_table, options_or_to_table)
|
52
52
|
end
|
53
53
|
|
54
54
|
# See: activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
|
55
|
-
def
|
55
|
+
def foreign_key_column_for(table_name)
|
56
56
|
table = table_name.to_s.split('.').last
|
57
57
|
|
58
|
-
|
58
|
+
super table
|
59
59
|
end
|
60
60
|
|
61
61
|
# see activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
|
62
|
-
def
|
62
|
+
def foreign_keys(table_name)
|
63
63
|
namespace = table_name.to_s.split('.').first
|
64
64
|
table_name = table_name.to_s.split('.').last
|
65
65
|
|
@@ -35,11 +35,11 @@ module PgSaurus::ConnectionAdapters::PostgreSQLAdapter::SchemaMethods
|
|
35
35
|
end
|
36
36
|
|
37
37
|
# Provide :schema option to +drop_table+ method.
|
38
|
-
def
|
38
|
+
def drop_table(table_name, options = {})
|
39
39
|
options = options.dup
|
40
40
|
schema_name = options.delete(:schema)
|
41
41
|
table_name = "#{schema_name}.#{table_name}" if schema_name
|
42
|
-
|
42
|
+
super(table_name, options)
|
43
43
|
end
|
44
44
|
|
45
45
|
# Make method +tables+ return tables not only from public schema.
|
@@ -51,8 +51,8 @@ module PgSaurus::ConnectionAdapters::PostgreSQLAdapter::SchemaMethods
|
|
51
51
|
# See: https://github.com/TMXCredit/pg_power/pull/42
|
52
52
|
#
|
53
53
|
# @return [Array<String>] table names
|
54
|
-
def
|
55
|
-
public_tables =
|
54
|
+
def tables(*args)
|
55
|
+
public_tables = super(*args)
|
56
56
|
|
57
57
|
non_public_tables =
|
58
58
|
query(<<-SQL, 'SCHEMA').map { |row| row[0] }
|
@@ -65,14 +65,14 @@ module PgSaurus::ConnectionAdapters::PostgreSQLAdapter::SchemaMethods
|
|
65
65
|
end
|
66
66
|
|
67
67
|
# Provide :schema option to +rename_table+ method.
|
68
|
-
def
|
68
|
+
def rename_table(table_name, new_name, options = {})
|
69
69
|
schema_name = options[:schema]
|
70
70
|
if schema_name
|
71
71
|
in_schema schema_name do
|
72
|
-
|
72
|
+
super(table_name, new_name)
|
73
73
|
end
|
74
74
|
else
|
75
|
-
|
75
|
+
super(table_name, new_name)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
@@ -146,20 +146,13 @@ module PgSaurus::CreateIndexConcurrently
|
|
146
146
|
# @see ::ActiveRecord::Migrator.migrate
|
147
147
|
# @see ::ActiveRecord::Migrator.ddl_transaction
|
148
148
|
module Migrator
|
149
|
-
extend ActiveSupport::Concern
|
150
|
-
|
151
|
-
# :nodoc:
|
152
|
-
def self.included(klass)
|
153
|
-
klass.alias_method_chain :ddl_transaction, :postponed_queries
|
154
|
-
end
|
155
|
-
|
156
149
|
# Override (see ::ActiveRecord::Migrator.ddl_transaction) to call
|
157
150
|
# (see ::PgSaurus::CreateIndexConcurrently::Migration.process_postponed_queries)
|
158
151
|
# immediately after transaction.
|
159
152
|
#
|
160
153
|
# @see ::ActiveRecord::Migrator.ddl_transaction
|
161
|
-
def
|
162
|
-
|
154
|
+
def ddl_transaction(*args, &block)
|
155
|
+
super(*args, &block)
|
163
156
|
|
164
157
|
# GOTCHA:
|
165
158
|
# This might be a bit tricky, but I've decided that this is the best
|
data/lib/pg_saurus/engine.rb
CHANGED
@@ -12,9 +12,20 @@ module PgSaurus
|
|
12
12
|
require ::PgSaurus::Engine.root + 'lib/core_ext/active_record/' + path
|
13
13
|
end
|
14
14
|
|
15
|
-
ActiveRecord::SchemaDumper.class_eval
|
15
|
+
ActiveRecord::SchemaDumper.class_eval do
|
16
|
+
prepend ::PgSaurus::SchemaDumper::SchemaMethods
|
17
|
+
prepend ::PgSaurus::SchemaDumper::ExtensionMethods
|
18
|
+
prepend ::PgSaurus::SchemaDumper::ViewMethods
|
19
|
+
prepend ::PgSaurus::SchemaDumper::FunctionMethods
|
20
|
+
prepend ::PgSaurus::SchemaDumper::CommentMethods
|
21
|
+
prepend ::PgSaurus::SchemaDumper::TriggerMethods
|
22
|
+
prepend ::PgSaurus::SchemaDumper::ForeignKeyMethods
|
23
|
+
|
24
|
+
include ::PgSaurus::SchemaDumper
|
25
|
+
end
|
16
26
|
|
17
27
|
ActiveRecord::Migration.class_eval do
|
28
|
+
prepend ::PgSaurus::Migration::SetRoleMethod::Extension
|
18
29
|
include ::PgSaurus::Migration::SetRoleMethod
|
19
30
|
end
|
20
31
|
|
@@ -30,7 +41,7 @@ module PgSaurus
|
|
30
41
|
include ::PgSaurus::CreateIndexConcurrently::Migration
|
31
42
|
end
|
32
43
|
ActiveRecord::Migrator.class_eval do
|
33
|
-
|
44
|
+
prepend PgSaurus::CreateIndexConcurrently::Migrator
|
34
45
|
end
|
35
46
|
ActiveRecord::MigrationProxy.class_eval do
|
36
47
|
include ::PgSaurus::CreateIndexConcurrently::MigrationProxy
|
@@ -41,6 +52,7 @@ module PgSaurus
|
|
41
52
|
end
|
42
53
|
|
43
54
|
ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
|
55
|
+
prepend ::PgSaurus::ConnectionAdapters::AbstractAdapter::SchemaMethods
|
44
56
|
include ::PgSaurus::ConnectionAdapters::AbstractAdapter
|
45
57
|
end
|
46
58
|
|
@@ -51,6 +63,9 @@ module PgSaurus
|
|
51
63
|
end
|
52
64
|
|
53
65
|
sql_adapter_class.class_eval do
|
66
|
+
prepend ::PgSaurus::ConnectionAdapters::PostgreSQLAdapter::SchemaMethods
|
67
|
+
prepend ::PgSaurus::ConnectionAdapters::PostgreSQLAdapter::ForeignKeyMethods
|
68
|
+
|
54
69
|
include ::PgSaurus::ConnectionAdapters::PostgreSQLAdapter
|
55
70
|
end
|
56
71
|
|
@@ -28,8 +28,6 @@ module PgSaurus
|
|
28
28
|
@keep_default_role
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
32
|
-
alias_method_chain :exec_migration, :role
|
33
31
|
end
|
34
32
|
|
35
33
|
# Get role
|
@@ -42,33 +40,37 @@ module PgSaurus
|
|
42
40
|
self.class.keep_default_role?
|
43
41
|
end
|
44
42
|
|
45
|
-
#
|
46
|
-
#
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
43
|
+
# Module to be prepended into ActiveRecord::Migration which allows
|
44
|
+
# enhancing the exec_migration method.
|
45
|
+
module Extension
|
46
|
+
# Wrap original `exec_migration` to run migration with set role.
|
47
|
+
#
|
48
|
+
# @param conn [ActiveRecord::ConnectionAdapters::PostgreSQLAdapter]
|
49
|
+
# @param direction [Symbol] :up or :down
|
50
|
+
#
|
51
|
+
# @return [void]
|
52
|
+
def exec_migration(conn, direction)
|
53
|
+
if role
|
54
|
+
begin
|
55
|
+
conn.execute "SET ROLE #{role}"
|
56
|
+
super(conn, direction)
|
57
|
+
ensure
|
58
|
+
conn.execute "RESET ROLE"
|
59
|
+
end
|
60
|
+
elsif PgSaurus.config.ensure_role_set && !keep_default_role?
|
61
|
+
msg =
|
62
|
+
"Role for migration #{self.class} is not set\n\n" \
|
63
|
+
"You've configured PgSaurus with ensure_role_set=true. \n" \
|
64
|
+
"That means that every migration must explicitly set role with set_role method.\n\n" \
|
65
|
+
"Example:\n" \
|
66
|
+
" class CreateNewTable < ActiveRecord::Migration\n" \
|
67
|
+
" set_role \"superhero\"\n" \
|
68
|
+
" end\n\n" \
|
69
|
+
"If you want to set ensure_role_set=false, take a look at config/initializers/pg_saurus.rb\n\n"
|
70
|
+
raise PgSaurus::RoleNotSetError, msg
|
71
|
+
else
|
72
|
+
super(conn, direction)
|
58
73
|
end
|
59
|
-
elsif PgSaurus.config.ensure_role_set && !keep_default_role?
|
60
|
-
msg =
|
61
|
-
"Role for migration #{self.class} is not set\n\n" \
|
62
|
-
"You've configured PgSaurus with ensure_role_set=true. \n" \
|
63
|
-
"That means that every migration must explicitly set role with set_role method.\n\n" \
|
64
|
-
"Example:\n" \
|
65
|
-
" class CreateNewTable < ActiveRecord::Migration\n" \
|
66
|
-
" set_role \"superhero\"\n" \
|
67
|
-
" end\n\n" \
|
68
|
-
"If you want to set ensure_role_set=false, take a look at config/initializers/pg_saurus.rb\n\n"
|
69
|
-
raise PgSaurus::RoleNotSetError, msg
|
70
|
-
else
|
71
|
-
exec_migration_without_role(conn, direction)
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
@@ -3,7 +3,6 @@
|
|
3
3
|
# and tables.
|
4
4
|
module PgSaurus::SchemaDumper
|
5
5
|
extend ActiveSupport::Autoload
|
6
|
-
extend ActiveSupport::Concern
|
7
6
|
|
8
7
|
autoload :ExtensionMethods
|
9
8
|
autoload :CommentMethods
|
@@ -20,16 +19,4 @@ module PgSaurus::SchemaDumper
|
|
20
19
|
include ViewMethods
|
21
20
|
include FunctionMethods
|
22
21
|
include TriggerMethods
|
23
|
-
|
24
|
-
included do
|
25
|
-
alias_method_chain :header, :schemas
|
26
|
-
alias_method_chain :header, :extensions
|
27
|
-
|
28
|
-
alias_method_chain :tables, :views
|
29
|
-
alias_method_chain :tables, :functions
|
30
|
-
alias_method_chain :tables, :triggers
|
31
|
-
alias_method_chain :tables, :comments
|
32
|
-
|
33
|
-
alias_method_chain :foreign_keys, :indexes
|
34
|
-
end
|
35
22
|
end
|
@@ -2,8 +2,8 @@
|
|
2
2
|
module PgSaurus::SchemaDumper::CommentMethods
|
3
3
|
# Hook ActiveRecord::SchemaDumper#table method to dump comments on
|
4
4
|
# table and columns.
|
5
|
-
def
|
6
|
-
|
5
|
+
def tables(stream)
|
6
|
+
super(stream)
|
7
7
|
|
8
8
|
# Dump table and column comments
|
9
9
|
@connection.tables.sort.each do |table_name|
|
@@ -2,8 +2,8 @@
|
|
2
2
|
module PgSaurus::SchemaDumper::ExtensionMethods
|
3
3
|
# Hook ActiveRecord::SchemaDumper#header method to dump extensions in all
|
4
4
|
# schemas except for pg_catalog.
|
5
|
-
def
|
6
|
-
|
5
|
+
def header(stream)
|
6
|
+
super(stream)
|
7
7
|
dump_extensions(stream)
|
8
8
|
stream
|
9
9
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module PgSaurus::SchemaDumper::ForeignKeyMethods
|
4
4
|
|
5
5
|
# See activerecord/lib/active_record/schema_dumper.rb
|
6
|
-
def
|
6
|
+
def foreign_keys(table, stream)
|
7
7
|
if (foreign_keys = @connection.foreign_keys(table)).any?
|
8
8
|
add_foreign_key_statements = foreign_keys.map do |foreign_key|
|
9
9
|
|
@@ -2,12 +2,12 @@
|
|
2
2
|
module PgSaurus::SchemaDumper::FunctionMethods
|
3
3
|
|
4
4
|
# :nodoc
|
5
|
-
def
|
5
|
+
def tables(stream)
|
6
6
|
# Functions must be dumped before tables.
|
7
7
|
# Some indexes may use defined functions.
|
8
8
|
dump_functions stream
|
9
9
|
|
10
|
-
|
10
|
+
super(stream)
|
11
11
|
|
12
12
|
stream
|
13
13
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# Extends ActiveRecord::SchemaDumper class to dump views
|
2
2
|
module PgSaurus::SchemaDumper::ViewMethods
|
3
3
|
# Dump create view statements
|
4
|
-
def
|
5
|
-
|
4
|
+
def tables(stream)
|
5
|
+
super(stream)
|
6
6
|
views(stream)
|
7
7
|
stream
|
8
8
|
end
|
data/lib/pg_saurus/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_saurus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Potapov Sergey
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2019-
|
16
|
+
date: 2019-07-16 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: pg
|
@@ -273,7 +273,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
273
273
|
version: '0'
|
274
274
|
requirements: []
|
275
275
|
rubyforge_project:
|
276
|
-
rubygems_version: 2.
|
276
|
+
rubygems_version: 2.7.9
|
277
277
|
signing_key:
|
278
278
|
specification_version: 4
|
279
279
|
summary: ActiveRecord extensions for PostgreSQL.
|