pg_power 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +27 -5
- data/lib/core_ext/active_record/connection_adapters/abstract/schema_statements.rb +37 -11
- data/lib/pg_power.rb +2 -0
- data/lib/pg_power/connection_adapters/postgresql_adapter/foreigner_methods.rb +39 -23
- data/lib/pg_power/create_index_concurrently.rb +221 -0
- data/lib/pg_power/engine.rb +17 -7
- data/lib/pg_power/errors.rb +6 -0
- data/lib/pg_power/tools.rb +1 -1
- data/lib/pg_power/version.rb +1 -1
- metadata +5 -3
data/README.markdown
CHANGED
@@ -10,6 +10,7 @@ ActiveRecord extension to get more from PostgreSQL:
|
|
10
10
|
* Set/remove comments on columns and tables.
|
11
11
|
* Use foreign keys.
|
12
12
|
* Use partial indexes.
|
13
|
+
* Run index creation concurrently.
|
13
14
|
|
14
15
|
## Environment notes
|
15
16
|
|
@@ -166,9 +167,30 @@ expressions are supported.
|
|
166
167
|
### Examples
|
167
168
|
|
168
169
|
Add an index to a column with a function
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
add_index(:comments, "lower(text)")
|
173
|
+
```
|
174
|
+
|
175
|
+
## Concurrent index creation
|
176
|
+
|
177
|
+
PostgreSQL supports concurent index creation. We added that feature to migration
|
178
|
+
DSL on index and foreign keys creation.
|
179
|
+
|
180
|
+
### Examples
|
181
|
+
|
182
|
+
Add an index concurrently to a table
|
183
|
+
|
169
184
|
```ruby
|
170
|
-
add_index
|
185
|
+
add_index :table, :column_id, :concurrently => true
|
171
186
|
```
|
187
|
+
|
188
|
+
Add an index concurrently along with foreign key
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
add_foreign_key :table1, :table2, :column => :column_id, :concurrent_index => true
|
192
|
+
```
|
193
|
+
|
172
194
|
## Tools
|
173
195
|
|
174
196
|
PgPower::Tools provides number of useful methods:
|
@@ -206,10 +228,10 @@ Support for JRuby:
|
|
206
228
|
|
207
229
|
## Copyright and License
|
208
230
|
|
209
|
-
Copyright (c) 2012 TMX Credit.
|
210
|
-
Initial foreign key code taken from foreigner, Copyright (c) 2009 Matthew Higgins
|
211
|
-
pg_comment Copyright (c) 2011 Arthur Shagall
|
212
|
-
Partial index Copyright (c) 2012 Marcelo Silveira
|
231
|
+
* Copyright (c) 2012 TMX Credit.
|
232
|
+
* Initial foreign key code taken from foreigner, Copyright (c) 2009 Matthew Higgins
|
233
|
+
* pg_comment Copyright (c) 2011 Arthur Shagall
|
234
|
+
* Partial index Copyright (c) 2012 Marcelo Silveira
|
213
235
|
|
214
236
|
Released under the MIT License. See the MIT-LICENSE file for more details.
|
215
237
|
|
@@ -9,13 +9,37 @@ module ActiveRecord
|
|
9
9
|
# an Array of Symbols.
|
10
10
|
#
|
11
11
|
# ====== Creating a partial index
|
12
|
-
# add_index(:accounts, [:branch_id, :party_id],
|
12
|
+
# add_index(:accounts, [:branch_id, :party_id],
|
13
|
+
# :unique => true, :concurrently => true, :where => 'active')
|
13
14
|
# generates
|
14
|
-
# CREATE UNIQUE INDEX
|
15
|
+
# CREATE UNIQUE INDEX CONCURRENTLY
|
16
|
+
# index_accounts_on_branch_id_and_party_id
|
17
|
+
# ON
|
18
|
+
# accounts(branch_id, party_id)
|
19
|
+
# WHERE
|
20
|
+
# active
|
15
21
|
#
|
16
22
|
def add_index(table_name, column_name, options = {})
|
17
|
-
|
18
|
-
|
23
|
+
name, type, creation_method, columns, opts = add_index_options(table_name, column_name, options)
|
24
|
+
|
25
|
+
# GOTCHA:
|
26
|
+
# It ensures that there is no existing index only for the case when the index
|
27
|
+
# is created concurrently to avoid changing the error behavior for default
|
28
|
+
# index creation.
|
29
|
+
# -- zekefast 2012-09-25
|
30
|
+
# GOTCHA:
|
31
|
+
# This check prevents invalid index creation, so after migration failed
|
32
|
+
# here there is no need to go to database and clean it from invalid
|
33
|
+
# indexes. But note that this handles only one of the cases when index
|
34
|
+
# creation can fail!!! All other case should be procesed manually.
|
35
|
+
# -- zekefast 2012-09-25
|
36
|
+
if options.has_key?(:concurrently) && index_exists?(table_name, column_name, options)
|
37
|
+
raise ::PgPower::IndexExistsError, "Index #{name} for `#{table_name}.#{column_name}` " \
|
38
|
+
"column can not be created concurrently, because such index already exists."
|
39
|
+
end
|
40
|
+
|
41
|
+
execute "CREATE #{type} INDEX #{creation_method} #{quote_column_name(name)} " \
|
42
|
+
"ON #{quote_table_name(table_name)} (#{columns})#{opts}"
|
19
43
|
end
|
20
44
|
|
21
45
|
# Checks to see if an index exists on a table for a given index definition.
|
@@ -24,7 +48,7 @@ module ActiveRecord
|
|
24
48
|
# # Check that a partial index exists
|
25
49
|
# index_exists?(:suppliers, :company_id, :where => 'active')
|
26
50
|
#
|
27
|
-
# # GIVEN:
|
51
|
+
# # GIVEN: 'index_suppliers_on_company_id' UNIQUE, btree (company_id) WHERE active
|
28
52
|
# index_exists?(:suppliers, :company_id, :unique => true, :where => 'active') => true
|
29
53
|
# index_exists?(:suppliers, :company_id, :unique => true) => false
|
30
54
|
#
|
@@ -88,14 +112,16 @@ module ActiveRecord
|
|
88
112
|
# Added support for partial indexes implemented using the :where option
|
89
113
|
#
|
90
114
|
def add_index_options(table_name, column_name, options = {})
|
91
|
-
column_names
|
92
|
-
index_name
|
115
|
+
column_names = Array(column_name)
|
116
|
+
index_name = index_name(table_name, :column => column_names)
|
117
|
+
index_creation_method = nil
|
93
118
|
|
94
119
|
if Hash === options # legacy support, since this param was a string
|
95
|
-
index_type = options[:unique] ?
|
120
|
+
index_type = options[:unique] ? 'UNIQUE' : ''
|
121
|
+
index_creation_method = options[:concurrently] ? 'CONCURRENTLY' : ''
|
96
122
|
index_name = options[:name].to_s if options.key?(:name)
|
97
123
|
if supports_partial_index?
|
98
|
-
index_options = options[:where] ? " WHERE #{options[:where]}" :
|
124
|
+
index_options = options[:where] ? " WHERE #{options[:where]}" : ''
|
99
125
|
end
|
100
126
|
else
|
101
127
|
index_type = options
|
@@ -107,9 +133,9 @@ module ActiveRecord
|
|
107
133
|
if index_name_exists?(table_name, index_name, false)
|
108
134
|
raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists"
|
109
135
|
end
|
110
|
-
index_columns = quoted_columns_for_index(column_names, options).join(
|
136
|
+
index_columns = quoted_columns_for_index(column_names, options).join(', ')
|
111
137
|
|
112
|
-
[index_name, index_type, index_columns, index_options]
|
138
|
+
[index_name, index_type, index_creation_method, index_columns, index_options]
|
113
139
|
end
|
114
140
|
protected :add_index_options
|
115
141
|
|
data/lib/pg_power.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "pg_power/engine"
|
2
|
+
require "pg_power/errors"
|
2
3
|
|
3
4
|
# Rails engine which allows to use some PostgreSQL features:
|
4
5
|
# * Schemas.
|
@@ -13,4 +14,5 @@ module PgPower
|
|
13
14
|
autoload :Tools
|
14
15
|
autoload :Migration
|
15
16
|
autoload :ConnectionAdapters
|
17
|
+
autoload :CreateIndexConcurrently
|
16
18
|
end
|
@@ -1,8 +1,4 @@
|
|
1
1
|
module PgPower # :nodoc:
|
2
|
-
# Raised when an unexpected index exists
|
3
|
-
class IndexExistsError < StandardError
|
4
|
-
end
|
5
|
-
|
6
2
|
# Provides methods to extend {ActiveRecord::ConnectionAdapters::PostgreSQLAdapter}
|
7
3
|
# to support foreign keys feature.
|
8
4
|
module ConnectionAdapters::PostgreSQLAdapter::ForeignerMethods
|
@@ -70,30 +66,51 @@ module PgPower # :nodoc:
|
|
70
66
|
#
|
71
67
|
# Ensures that an index is created for the foreign key, unless :exclude_index is true.
|
72
68
|
#
|
73
|
-
# Raises a [PgPower::IndexExistsError] when :exclude_index is true, but the index already exists.
|
74
|
-
#
|
75
69
|
# == Options:
|
76
70
|
# * :column
|
77
71
|
# * :primary_key
|
78
72
|
# * :dependent
|
79
|
-
# * :exclude_index
|
73
|
+
# * :exclude_index [Boolean]
|
74
|
+
# * :concurrent_index [Boolean]
|
80
75
|
#
|
81
|
-
# @param [String, Symbol]
|
82
|
-
# @param [String, Symbol]
|
83
|
-
# @param [Hash]
|
76
|
+
# @param [String, Symbol] from_table
|
77
|
+
# @param [String, Symbol] to_table
|
78
|
+
# @param [Hash] options
|
79
|
+
# @option options [String, Symbol] :column
|
80
|
+
# @option options [String, Symbol] :primary_key
|
81
|
+
# @option options [Hash] :dependent
|
82
|
+
# @option options [Boolean] :exclude_index
|
83
|
+
# @option options [Boolean] :concurrent_index
|
84
84
|
#
|
85
|
+
# @raise [PgPower::IndexExistsError] when :exclude_index is true, but the index already exists
|
85
86
|
def add_foreign_key(from_table, to_table, options = {})
|
86
|
-
options[:column]
|
87
|
-
options[:exclude_index]
|
87
|
+
options[:column] ||= id_column_name_from_table_name(to_table)
|
88
|
+
options[:exclude_index] ||= false
|
88
89
|
|
89
|
-
if index_exists?(from_table, options[:column])
|
90
|
-
raise PgPower::IndexExistsError,
|
90
|
+
if index_exists?(from_table, options[:column]) && !options[:exclude_index]
|
91
|
+
raise PgPower::IndexExistsError,
|
92
|
+
"The index, #{index_name(from_table, options[:column])}, already exists." \
|
93
|
+
" Use :exclude_index => true when adding the foreign key."
|
91
94
|
end
|
92
95
|
|
93
96
|
sql = "ALTER TABLE #{quote_table_name(from_table)} #{add_foreign_key_sql(from_table, to_table, options)}"
|
94
97
|
execute(sql)
|
95
98
|
|
96
|
-
|
99
|
+
# GOTCHA:
|
100
|
+
# Index can not be created concurrently inside transaction in PostgreSQL.
|
101
|
+
# So, in case of concurrently created index with foreign key only
|
102
|
+
# foreign key will be created inside migration transaction and after
|
103
|
+
# closing transaction queries for index creation will be send to database.
|
104
|
+
# That's why I prevent here normal index creation in case of
|
105
|
+
# `concurrent_index` option is given.
|
106
|
+
# NOTE: Index creation after closing migration transaction could lead
|
107
|
+
# to weird effects when transaction moves smoothly, but index
|
108
|
+
# creation with error. In that case transaction will not be rolled back.
|
109
|
+
# As it was closed before even index was attempted to create.
|
110
|
+
# -- zekefast 2012-09-12
|
111
|
+
unless options[:exclude_index] || options[:concurrent_index]
|
112
|
+
add_index(from_table, options[:column])
|
113
|
+
end
|
97
114
|
end
|
98
115
|
|
99
116
|
# Returns chunk of SQL to add foreign key based on table names and options.
|
@@ -130,13 +147,13 @@ module PgPower # :nodoc:
|
|
130
147
|
#
|
131
148
|
def remove_foreign_key(from_table, to_table_or_options_hash, options={})
|
132
149
|
if Hash === to_table_or_options_hash
|
133
|
-
options
|
134
|
-
column
|
135
|
-
foreign_key_name =
|
136
|
-
column
|
150
|
+
options = to_table_or_options_hash
|
151
|
+
column = options[:column]
|
152
|
+
foreign_key_name = foreign_key_name(from_table, column, options)
|
153
|
+
column ||= id_column_name_from_foreign_key_metadata(from_table, foreign_key_name)
|
137
154
|
else
|
138
|
-
column
|
139
|
-
foreign_key_name =
|
155
|
+
column = id_column_name_from_table_name(to_table_or_options_hash)
|
156
|
+
foreign_key_name = foreign_key_name(from_table, column)
|
140
157
|
end
|
141
158
|
|
142
159
|
execute "ALTER TABLE #{quote_table_name(from_table)} #{remove_foreign_key_sql(foreign_key_name)}"
|
@@ -154,7 +171,6 @@ module PgPower # :nodoc:
|
|
154
171
|
def id_column_name_from_table_name(table)
|
155
172
|
"#{table.to_s.split('.').last.singularize}_id"
|
156
173
|
end
|
157
|
-
private :id_column_name_from_table_name
|
158
174
|
|
159
175
|
# Extracts the foreign key column id from the foreign key metadata
|
160
176
|
# @param [String, Symbol] from_table
|
@@ -165,7 +181,7 @@ module PgPower # :nodoc:
|
|
165
181
|
this_key.options[:column]
|
166
182
|
end
|
167
183
|
private :id_column_name_from_foreign_key_metadata
|
168
|
-
|
184
|
+
|
169
185
|
# Builds default name for constraint
|
170
186
|
def foreign_key_name(table, column, options = {})
|
171
187
|
if options[:name]
|
@@ -0,0 +1,221 @@
|
|
1
|
+
# Adds ability to configure in migration how index will be created.
|
2
|
+
# See more details how to create index concurrently in PostgreSQL at
|
3
|
+
# (see http://www.postgresql.org/docs/9.2/static/sql-createindex.html#SQL-CREATEINDEX-CONCURRENTLY).
|
4
|
+
#
|
5
|
+
# There are several things you should be aware when use option to create index
|
6
|
+
# concurrently.
|
7
|
+
# Index can not be created concurrently inside transaction and such indexes
|
8
|
+
# creation will be postponed till migration transaction will be closed.
|
9
|
+
# In case of migration failure and transaction was rolled back indexes will not
|
10
|
+
# be created concurrently. But if indexes which should be created concurrently
|
11
|
+
# run with errors migration's transaction won't be rolled back. Error in that
|
12
|
+
# case will be raised and migration process will be stoped.
|
13
|
+
#
|
14
|
+
# Migrations can not ensure that all indexes that tend to be created
|
15
|
+
# concurrently were created even if the query for such index creation run
|
16
|
+
# without errors. Such indexes creation are deferred because of its nature.
|
17
|
+
# So, it's up to you to ensure that indexes was really created or remove
|
18
|
+
# partially created invalid indexes.
|
19
|
+
#
|
20
|
+
# :concurrent_index option conflicts with :exclude_index option in method
|
21
|
+
# `add_foreign_key`. So, if you put them together exception will be raised.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
#
|
25
|
+
# class AddIndexToNameForUsers < ActiveRecord::Migration
|
26
|
+
# def change
|
27
|
+
# add_index :users, :name, :concurrently => true
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# # or with foreign key
|
32
|
+
#
|
33
|
+
# class AddForeignKeyToRoleIdForUsers < ActiveRecord::Migration
|
34
|
+
# def change
|
35
|
+
# add_foreign_key :users, :roles, :concurrent_index => true
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
module PgPower::CreateIndexConcurrently
|
40
|
+
# Provides ability to postpone index creation queries in migrations.
|
41
|
+
#
|
42
|
+
# Overrides `add_index` and `add_foreign_key` methods for migration to be
|
43
|
+
# able to prevent indexes creation inside scope of transaction if they have to
|
44
|
+
# be created concurrently.
|
45
|
+
# Allows to run creation of postponed indexes.
|
46
|
+
#
|
47
|
+
# This module included into ActiveRecord::Migration class to extend it with
|
48
|
+
# new features.
|
49
|
+
#
|
50
|
+
# All postponed index creation queries are stored inside migration instance.
|
51
|
+
module Migration
|
52
|
+
# @attribute postponed_queries
|
53
|
+
# @return [Array] list of arguments to call `add_index` method.
|
54
|
+
# @private
|
55
|
+
attr_accessor :postponed_queries
|
56
|
+
private :postponed_queries, :postponed_queries=
|
57
|
+
|
58
|
+
|
59
|
+
# Adds a new index to the table. +column_name+ can be a single Symbol, or
|
60
|
+
# an Array of Symbols.
|
61
|
+
#
|
62
|
+
# @param [Symbol, String] table_name
|
63
|
+
# @param [Symbol, String, Array<Symbol, String>] column_name
|
64
|
+
# @param [optional, Hash] options
|
65
|
+
# @option options [Boolean] :unique
|
66
|
+
# @option options [Boolean] :concurrently
|
67
|
+
# @option options [String] :where
|
68
|
+
#
|
69
|
+
# @return [nil]
|
70
|
+
#
|
71
|
+
# @see ActiveRecord::ConnectionAdapters::SchemaStatements.add_index in pg_power gem
|
72
|
+
def add_index(table_name, column_name, options = {}, &block)
|
73
|
+
table_name = ::ActiveRecord::Migrator.proper_table_name(table_name)
|
74
|
+
# GOTCHA:
|
75
|
+
# checks if index should be created concurretnly then put it into
|
76
|
+
# the queue to wait till queue processing will be called (should be
|
77
|
+
# happended after closing transaction).
|
78
|
+
# Otherwise just delegate call to PgPower's `add_index`.
|
79
|
+
# Block is given for future compatibility.
|
80
|
+
# -- zekefast 2012-09-12
|
81
|
+
unless options[:concurrently]
|
82
|
+
return connection.add_index(table_name, column_name, options, &block)
|
83
|
+
end
|
84
|
+
|
85
|
+
enque(table_name, column_name, options, &block)
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
|
89
|
+
# Adds foreign key.
|
90
|
+
#
|
91
|
+
# == Options:
|
92
|
+
# * :column
|
93
|
+
# * :primary_key
|
94
|
+
# * :dependent
|
95
|
+
# * :exclude_index [Boolean]
|
96
|
+
# * :concurrent_index [Boolean]
|
97
|
+
#
|
98
|
+
# @param [String, Symbol] from_table
|
99
|
+
# @param [String, Symbol] to_table
|
100
|
+
# @param [Hash] options
|
101
|
+
# @option options [String, Symbol] :column
|
102
|
+
# @option options [String, Symbol] :primary_key
|
103
|
+
# @option options [Hash] :dependent
|
104
|
+
# @option options [Boolean] :exclude_index
|
105
|
+
# @option options [Boolean] :concurrent_index
|
106
|
+
#
|
107
|
+
# @raise [ArgumentError] in case of conflicted option were set
|
108
|
+
#
|
109
|
+
# @see ::PgPower::ConnectionAdapters::PostgreSQLAdapter::ForeignerMethods.add_foreign_key
|
110
|
+
def add_foreign_key(from_table, to_table, options = {}, &block)
|
111
|
+
from_table = ::ActiveRecord::Migrator.proper_table_name(from_table)
|
112
|
+
if options[:concurrent_index]
|
113
|
+
if options[:exclude_index]
|
114
|
+
raise ArgumentError, 'Conflicted options(exclude_index, concurrent_index) was found, both are set to true.'
|
115
|
+
end
|
116
|
+
|
117
|
+
options[:column] ||= connection.id_column_name_from_table_name(to_table)
|
118
|
+
options = options.merge(:concurrently => options[:concurrent_index])
|
119
|
+
enque(from_table, options[:column], options)
|
120
|
+
end
|
121
|
+
|
122
|
+
# GOTCHA:
|
123
|
+
# proceed foreign key creation, but giving :concurrent_index => true
|
124
|
+
# prevent normal index creation in PgPower's `add_foreign_key`.
|
125
|
+
# So, postponed creation could be done after transaction.
|
126
|
+
# -- zekefast 2012-09-12
|
127
|
+
connection.add_foreign_key(from_table, to_table, options, &block)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Execute all postponed index creation.
|
131
|
+
#
|
132
|
+
# @return [::PgPower::CreateIndexConcurrently::Migration]
|
133
|
+
def process_postponed_queries
|
134
|
+
Array(@postponed_queries).each do |arguments, block|
|
135
|
+
connection.add_index(*arguments, &block)
|
136
|
+
end
|
137
|
+
|
138
|
+
clear_queue
|
139
|
+
|
140
|
+
self
|
141
|
+
end
|
142
|
+
|
143
|
+
# Clean postponed queries' queue.
|
144
|
+
#
|
145
|
+
# @return [::PgPower::CreateIndexConcurrently::Migration] migration
|
146
|
+
def clear_queue
|
147
|
+
@postponed_queries = []
|
148
|
+
|
149
|
+
self
|
150
|
+
end
|
151
|
+
private :clear_queue
|
152
|
+
|
153
|
+
# Add to the queue add_index call parameters to be able execute call later.
|
154
|
+
#
|
155
|
+
# @param [Array] arguments
|
156
|
+
# @param [Proc] block
|
157
|
+
#
|
158
|
+
# @return [::PgPower::CreateIndexConcurrently::Migration]
|
159
|
+
def enque(*arguments, &block)
|
160
|
+
@postponed_queries ||= []
|
161
|
+
@postponed_queries << [arguments, block]
|
162
|
+
|
163
|
+
self
|
164
|
+
end
|
165
|
+
private :enque
|
166
|
+
end
|
167
|
+
|
168
|
+
# Allows to call `process_postponed_queries` on MigrationProxy instances.
|
169
|
+
# So, (see ::PgPower::CreateIndexConcurrently::Migrator) could run index
|
170
|
+
# creation concurrently.
|
171
|
+
#
|
172
|
+
# Default delegation in (see ActiveRecord::MigrationProxy) allows to call
|
173
|
+
# only several methods.
|
174
|
+
module MigrationProxy
|
175
|
+
def self.included(klass)
|
176
|
+
klass.delegate :process_postponed_queries, :to => :migration
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# Runs posponed index creation for each migration.
|
181
|
+
#
|
182
|
+
# This module included into (see ::ActiveRecord::Migrator) class to make possible
|
183
|
+
# to execute queries for postponed index creation after closing migration's
|
184
|
+
# transaction.
|
185
|
+
#
|
186
|
+
# @see ::ActiveRecord::Migrator.migrate
|
187
|
+
# @see ::ActiveRecord::Migrator.ddl_transaction
|
188
|
+
module Migrator
|
189
|
+
extend ActiveSupport::Concern
|
190
|
+
|
191
|
+
def self.included(klass)
|
192
|
+
klass.alias_method_chain :ddl_transaction, :postponed_queries
|
193
|
+
end
|
194
|
+
|
195
|
+
# Override (see ::ActiveRecord::Migrator.ddl_transaction) to call
|
196
|
+
# (see ::PgPower::CreateIndexConcurrently::Migration.process_postponed_queries)
|
197
|
+
# immediately after transaction.
|
198
|
+
#
|
199
|
+
# @see ::ActiveRecord::Migrator.ddl_transaction
|
200
|
+
def ddl_transaction_with_postponed_queries(*args, &block)
|
201
|
+
ddl_transaction_without_postponed_queries(*args, &block)
|
202
|
+
|
203
|
+
# GOTCHA:
|
204
|
+
# This might be a bit tricky, but I've decided that this is the best
|
205
|
+
# way to retrieve migration instance after closing transaction.
|
206
|
+
# The problem that (see ::ActiveRecord::Migrator) doesn't provide any
|
207
|
+
# access to recently launched migration. All logic to iterate through
|
208
|
+
# set of migrations incapsulated in (see ::ActiveRecord::Migrator.migrate)
|
209
|
+
# method.
|
210
|
+
# So, to get access to migration you need to override `migrate` method
|
211
|
+
# and duplicated all logic inside it, plus add call to
|
212
|
+
# `process_postponed_queries`.
|
213
|
+
# I've decided this is less forward compatible then retrieving
|
214
|
+
# value of `migration` variable in context where block
|
215
|
+
# given to `ddl_transaction` method was created.
|
216
|
+
# -- zekefast 2012-09-12
|
217
|
+
migration = block.binding.eval('migration')
|
218
|
+
migration.process_postponed_queries
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
data/lib/pg_power/engine.rb
CHANGED
@@ -9,12 +9,10 @@ module PgPower
|
|
9
9
|
'errors',
|
10
10
|
'connection_adapters/postgresql_adapter',
|
11
11
|
'connection_adapters/abstract/schema_statements'].each do |path|
|
12
|
-
require PgPower::Engine.root + 'lib/core_ext/active_record/' + path
|
12
|
+
require ::PgPower::Engine.root + 'lib/core_ext/active_record/' + path
|
13
13
|
end
|
14
14
|
|
15
|
-
ActiveRecord::SchemaDumper.class_eval
|
16
|
-
include PgPower::SchemaDumper
|
17
|
-
end
|
15
|
+
ActiveRecord::SchemaDumper.class_eval { include ::PgPower::SchemaDumper }
|
18
16
|
|
19
17
|
if defined?(ActiveRecord::Migration::CommandRecorder)
|
20
18
|
ActiveRecord::Migration::CommandRecorder.class_eval do
|
@@ -22,12 +20,24 @@ module PgPower
|
|
22
20
|
end
|
23
21
|
end
|
24
22
|
|
23
|
+
# Follow three include statements add support for concurrently
|
24
|
+
# index creation in migrations.
|
25
|
+
ActiveRecord::Migration.class_eval do
|
26
|
+
include ::PgPower::CreateIndexConcurrently::Migration
|
27
|
+
end
|
28
|
+
ActiveRecord::Migrator.class_eval do
|
29
|
+
include ::PgPower::CreateIndexConcurrently::Migrator
|
30
|
+
end
|
31
|
+
ActiveRecord::MigrationProxy.class_eval do
|
32
|
+
include ::PgPower::CreateIndexConcurrently::MigrationProxy
|
33
|
+
end
|
34
|
+
|
25
35
|
ActiveRecord::ConnectionAdapters::Table.module_eval do
|
26
|
-
include PgPower::ConnectionAdapters::Table
|
36
|
+
include ::PgPower::ConnectionAdapters::Table
|
27
37
|
end
|
28
38
|
|
29
39
|
ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
|
30
|
-
include PgPower::ConnectionAdapters::AbstractAdapter
|
40
|
+
include ::PgPower::ConnectionAdapters::AbstractAdapter
|
31
41
|
end
|
32
42
|
|
33
43
|
if defined?(ActiveRecord::ConnectionAdapters::JdbcAdapter)
|
@@ -37,7 +47,7 @@ module PgPower
|
|
37
47
|
end
|
38
48
|
|
39
49
|
sql_adapter_class.class_eval do
|
40
|
-
include PgPower::ConnectionAdapters::PostgreSQLAdapter
|
50
|
+
include ::PgPower::ConnectionAdapters::PostgreSQLAdapter
|
41
51
|
end
|
42
52
|
|
43
53
|
end
|
data/lib/pg_power/tools.rb
CHANGED
data/lib/pg_power/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_power
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-09-
|
14
|
+
date: 2012-09-26 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: pg
|
@@ -173,7 +173,9 @@ files:
|
|
173
173
|
- lib/pg_power/connection_adapters/table.rb
|
174
174
|
- lib/pg_power/connection_adapters/table/comment_methods.rb
|
175
175
|
- lib/pg_power/connection_adapters/table/foreigner_methods.rb
|
176
|
+
- lib/pg_power/create_index_concurrently.rb
|
176
177
|
- lib/pg_power/engine.rb
|
178
|
+
- lib/pg_power/errors.rb
|
177
179
|
- lib/pg_power/migration.rb
|
178
180
|
- lib/pg_power/migration/command_recorder.rb
|
179
181
|
- lib/pg_power/migration/command_recorder/comment_methods.rb
|
@@ -200,7 +202,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
200
202
|
version: '0'
|
201
203
|
segments:
|
202
204
|
- 0
|
203
|
-
hash:
|
205
|
+
hash: -621483421206137072
|
204
206
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
205
207
|
none: false
|
206
208
|
requirements:
|