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.
@@ -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(:comments, "lower(text)")
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], :unique => true, :where => "active")
12
+ # add_index(:accounts, [:branch_id, :party_id],
13
+ # :unique => true, :concurrently => true, :where => 'active')
13
14
  # generates
14
- # CREATE UNIQUE INDEX index_accounts_on_branch_id_and_party_id ON accounts(branch_id, party_id) WHERE active
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
- index_name, index_type, index_columns, index_options = add_index_options(table_name, column_name, options)
18
- execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{index_columns})#{index_options}"
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: "index_suppliers_on_company_id" UNIQUE, btree (company_id) WHERE active
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 = Array(column_name)
92
- index_name = index_name(table_name, :column => column_names)
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] ? "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
 
@@ -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 [Boolean]
73
+ # * :exclude_index [Boolean]
74
+ # * :concurrent_index [Boolean]
80
75
  #
81
- # @param [String, Symbol] from_table
82
- # @param [String, Symbol] to_table
83
- # @param [Hash] options
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] ||= id_column_name_from_table_name(to_table)
87
- options[:exclude_index] ||= false
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]) and !options[:exclude_index]
90
- raise PgPower::IndexExistsError, "The index, #{index_name(from_table, options[:column])}, already exists. Use :exclude_index => true when adding the foreign key."
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
- add_index(from_table, options[:column]) unless options[:exclude_index]
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 = to_table_or_options_hash
134
- column = options[:column]
135
- foreign_key_name = foreign_key_name(from_table, column, options)
136
- column ||= id_column_name_from_foreign_key_metadata(from_table, foreign_key_name)
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 = id_column_name_from_table_name(to_table_or_options_hash)
139
- foreign_key_name = foreign_key_name(from_table, column)
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
@@ -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 do
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
@@ -0,0 +1,6 @@
1
+ module PgPower # :nodoc:
2
+
3
+ # Raised when an unexpected index exists
4
+ class IndexExistsError < StandardError; end
5
+
6
+ end
@@ -38,7 +38,7 @@ module PgPower
38
38
 
39
39
 
40
40
 
41
- # Return databas connections
41
+ # Return database connections
42
42
  def connection
43
43
  ActiveRecord::Base.connection
44
44
  end
@@ -1,4 +1,4 @@
1
1
  module PgPower
2
2
  # Version of pg_power gem.
3
- VERSION = "1.0.1"
3
+ VERSION = "1.1.0"
4
4
  end
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.1
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-12 00:00:00.000000000 Z
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: 3609710966930791506
205
+ hash: -621483421206137072
204
206
  required_rubygems_version: !ruby/object:Gem::Requirement
205
207
  none: false
206
208
  requirements: