nandi 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba61fdd052ec58212031846c92ad947cb1f7cb8c033271b101f5973a2b7074f6
4
- data.tar.gz: b0c30216fb5544927d1d3b47ef0ad87d935a9ea8859c37a8779662a65f88d9f5
3
+ metadata.gz: ff51dca733bf2e4a5bff9ff71ac930c6d849fa734106a31b1244777fb25db9c0
4
+ data.tar.gz: ceeaebbaee681e1a4e6e857ec32289d59d821b9c627f899b371b607c214b077a
5
5
  SHA512:
6
- metadata.gz: f4c0ecfcb5e1a84c4a8b2e0721f4e48a8abff3f6bde78f04184544e9004987a4f155eebb3342b780fc793bc2d5104a8a98d7d25c6fcc9f8da43cdd70e0b5f9fd
7
- data.tar.gz: aedffb405097c5d9e988e001eab0c929ed0fab64b1b9b04a534051fa59aa16634c3c9071bf5daf31b7c416bfa94679b020685bd8c201c78d0552ebbcf60e0a75
6
+ metadata.gz: aa53ecf85370d256a09197547d0d99ceb4a3f731620f25341ea05b44364749ba452a3f375554f180879426b1b757f0b551cca1e86ede08f755070adcb62a879f
7
+ data.tar.gz: 80f8945b42a0931dced7e02e83ff0c43e4173009d9d5e6f74c876f18f5fe037280488cd524fce8683301001a86eacdcc9df6674ea649ef1ae71f2b9a1fa6c2f5
data/README.md CHANGED
@@ -202,10 +202,10 @@ class AddReferenceOnFoosToBars < ActiveRecord::Migration[5.2]
202
202
  set_statement_timeout(1_500)
203
203
 
204
204
  def up
205
- add_reference(:foos, :bar)
205
+ add_column(:foos, :bar_id, :bigint)
206
206
  end
207
207
  def down
208
- remove_reference(:foos, :bar)
208
+ remove_column(:foos, :bar_id)
209
209
  end
210
210
  end
211
211
 
@@ -268,10 +268,9 @@ Add a foreign key constraint. The generated SQL will include the NOT VALID param
268
268
  ### `#add_index(table, fields, **kwargs)`
269
269
  Adds a new index to the database.
270
270
 
271
- Nandi will:
272
-
271
+ Nandi will
273
272
  - add the `CONCURRENTLY` option, which means the change takes a less restrictive lock at the cost of not running in a DDL transaction
274
- - use the `BTREE` index type which is the safest to create.
273
+ - default to the `BTREE` index type, as it is commonly a good fit.
275
274
 
276
275
  Because index creation is particularly failure-prone, and because we cannot run in a transaction and therefore risk partially applied migrations that (in a Rails environment) require manual intervention, Nandi Validates that, if there is a add_index statement in the migration, it must be the only statement.
277
276
 
@@ -286,6 +285,12 @@ create_table :widgets do |t|
286
285
  end
287
286
  ```
288
287
 
288
+ ### `#add_reference(table, ref_name, **extra_args)`
289
+ Adds a new reference column. Nandi will validate that the foreign key flag is not set to true; use `add_foreign_key` and `validate_foreign_key` instead! Nandi will also set the `index: false` flag, as index creation is unsafe unless done concurrently in a separate migration.
290
+
291
+ ### `#remove_reference(table, ref_name, **extra_args)`
292
+ Removes a reference column.
293
+
289
294
  ### `#remove_column(table, name, **extra_args)`
290
295
  Remove an existing column.
291
296
 
@@ -64,7 +64,7 @@ module Nandi
64
64
  key = if k.is_a?(Symbol)
65
65
  symbol_key(k)
66
66
  else
67
- format_value(k) + " =>"
67
+ "#{format_value(k)} =>"
68
68
  end
69
69
  "#{key} #{format_value(v)}"
70
70
  end
@@ -5,6 +5,8 @@ require "nandi/instructions/remove_index"
5
5
  require "nandi/instructions/create_table"
6
6
  require "nandi/instructions/drop_table"
7
7
  require "nandi/instructions/add_column"
8
+ require "nandi/instructions/add_reference"
9
+ require "nandi/instructions/remove_reference"
8
10
  require "nandi/instructions/remove_column"
9
11
  require "nandi/instructions/add_foreign_key"
10
12
  require "nandi/instructions/drop_constraint"
@@ -21,11 +21,10 @@ module Nandi
21
21
  name: name,
22
22
 
23
23
  # Overrides and extra options
24
- **@extra_args,
24
+ **extra_args_with_default_index_type,
25
25
 
26
26
  # Mandatory values
27
27
  algorithm: :concurrently,
28
- using: :btree,
29
28
  }
30
29
  end
31
30
 
@@ -38,13 +37,19 @@ module Nandi
38
37
  private
39
38
 
40
39
  def name
41
- :"idx_#{table.to_s}_on_#{field_names}"
40
+ :"idx_#{table}_on_#{field_names}"
42
41
  end
43
42
 
44
43
  def field_names
45
44
  field_names = fields.respond_to?(:map) ? fields.map(&:to_s).join("_") : fields
46
45
  field_names.to_s.scan(/\w+/).join("_")
47
46
  end
47
+
48
+ def extra_args_with_default_index_type
49
+ {
50
+ using: :btree,
51
+ }.merge(@extra_args)
52
+ end
48
53
  end
49
54
  end
50
55
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nandi
4
+ module Instructions
5
+ class AddReference
6
+ DEFAULT_EXTRA_ARGS = { index: false }.freeze
7
+ attr_reader :table, :ref_name, :extra_args
8
+
9
+ def initialize(table:, ref_name:, **kwargs)
10
+ @table = table
11
+ @ref_name = ref_name
12
+ @extra_args = DEFAULT_EXTRA_ARGS.merge(kwargs)
13
+ end
14
+
15
+ def procedure
16
+ :add_reference
17
+ end
18
+
19
+ def lock
20
+ Nandi::Migration::LockWeights::ACCESS_EXCLUSIVE
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nandi
4
+ module Instructions
5
+ class RemoveReference
6
+ attr_reader :table, :ref_name, :extra_args
7
+
8
+ def initialize(table:, ref_name:, **kwargs)
9
+ @table = table
10
+ @ref_name = ref_name
11
+ @extra_args = kwargs
12
+ end
13
+
14
+ def procedure
15
+ :remove_reference
16
+ end
17
+
18
+ def lock
19
+ Nandi::Migration::LockWeights::ACCESS_EXCLUSIVE
20
+ end
21
+ end
22
+ end
23
+ end
@@ -43,6 +43,7 @@ module Nandi
43
43
 
44
44
  class << self
45
45
  attr_reader :lock_timeout, :statement_timeout
46
+
46
47
  # For sake both of correspondence with Postgres syntax and familiarity
47
48
  # with activerecord-safe_migrations's identically named macros, we
48
49
  # disable this cop.
@@ -111,7 +112,7 @@ module Nandi
111
112
  # Nandi will:
112
113
  # * add the `CONCURRENTLY` option, which means the change takes a less
113
114
  # restrictive lock at the cost of not running in a DDL transaction
114
- # * use the `BTREE` index type which is the safest to create.
115
+ # * default to the `BTREE` index type, as it is commonly a good fit.
115
116
  #
116
117
  # Because index creation is particularly failure-prone, and because
117
118
  # we cannot run in a transaction and therefore risk partially applied
@@ -188,6 +189,31 @@ module Nandi
188
189
  )
189
190
  end
190
191
 
192
+ # Adds a new reference column. Nandi will validate that the foreign key flag
193
+ # is not set to true; use `add_foreign_key` and `validate_foreign_key` instead!
194
+ # @param table [Symbol, String] The name of the table to add the column to
195
+ # @param ref_name [Symbol, String] The referenced column name
196
+ # @param kwargs [Hash] Arbitrary options to be passed to the backend.
197
+ def add_reference(table, ref_name, **kwargs)
198
+ current_instructions << Instructions::AddReference.new(
199
+ table: table,
200
+ ref_name: ref_name,
201
+ **kwargs,
202
+ )
203
+ end
204
+
205
+ # Removes a reference column.
206
+ # @param table [Symbol, String] The name of the table to remove the reference from
207
+ # @param ref_name [Symbol, String] The referenced column name
208
+ # @param kwargs [Hash] Arbitrary options to be passed to the backend.
209
+ def remove_reference(table, ref_name, **kwargs)
210
+ current_instructions << Instructions::RemoveReference.new(
211
+ table: table,
212
+ ref_name: ref_name,
213
+ **kwargs,
214
+ )
215
+ end
216
+
191
217
  # Remove an existing column.
192
218
  # @param table [Symbol, String] The name of the table to remove the column
193
219
  # from.
@@ -82,6 +82,18 @@ module Nandi
82
82
  formatted_property :extra_args
83
83
  end
84
84
 
85
+ class AddReferenceCell < Base
86
+ formatted_property :table
87
+ formatted_property :ref_name
88
+ formatted_property :extra_args
89
+ end
90
+
91
+ class RemoveReferenceCell < Base
92
+ formatted_property :table
93
+ formatted_property :ref_name
94
+ formatted_property :extra_args
95
+ end
96
+
85
97
  class RemoveColumnCell < Base
86
98
  formatted_property :table
87
99
  formatted_property :name
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "nandi/validation/add_column_validator"
4
+ require "nandi/validation/add_reference_validator"
4
5
  require "nandi/validation/remove_index_validator"
5
6
  require "nandi/validation/each_validator"
6
7
  require "nandi/validation/result"
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nandi/validation/failure_helpers"
4
+
5
+ module Nandi
6
+ module Validation
7
+ class AddReferenceValidator
8
+ include Nandi::Validation::FailureHelpers
9
+
10
+ def self.call(instruction)
11
+ new(instruction).call
12
+ end
13
+
14
+ def initialize(instruction)
15
+ @instruction = instruction
16
+ end
17
+
18
+ def call
19
+ foreign_key = instruction.extra_args.fetch(:foreign_key, false)
20
+ index = instruction.extra_args.fetch(:index, false)
21
+
22
+ collect_errors(
23
+ assert(
24
+ !foreign_key,
25
+ foreign_key_message,
26
+ ),
27
+ assert(
28
+ !index,
29
+ index_message,
30
+ ),
31
+ )
32
+ end
33
+
34
+ private
35
+
36
+ def index_message
37
+ "Indexing a reference column on creation can make the table unavailable." \
38
+ "Use the `add_index` method in a separate migration to index the column."
39
+ end
40
+
41
+ def foreign_key_message
42
+ "Adding a foreign key constraint must be done in two separate migrations. " \
43
+ "Use the `add_foreign_key` and `validate_foreign_key` methods, or the " \
44
+ "nandi:foreign_key generator, to do this."
45
+ end
46
+
47
+ attr_reader :instruction
48
+ end
49
+ end
50
+ end
@@ -21,6 +21,8 @@ module Nandi
21
21
  RemoveIndexValidator.call(instruction)
22
22
  when :add_column
23
23
  AddColumnValidator.call(instruction)
24
+ when :add_reference
25
+ AddReferenceValidator.call(instruction)
24
26
  else
25
27
  success
26
28
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nandi
4
- VERSION = "0.9.0"
4
+ VERSION = "0.10.0"
5
5
  end
@@ -0,0 +1,5 @@
1
+ add_reference(
2
+ <%= table %>,
3
+ <%= ref_name %>,
4
+ <%= extra_args %>
5
+ )
@@ -0,0 +1,5 @@
1
+ remove_reference(
2
+ <%= table %>,
3
+ <%= ref_name %>,
4
+ <%= extra_args %>
5
+ )
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nandi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GoCardless Engineering
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-16 00:00:00.000000000 Z
11
+ date: 2020-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -100,28 +100,28 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 2.3.14
103
+ version: 2.15.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 2.3.14
110
+ version: 2.15.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: pry-byebug
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 3.7.0
117
+ version: 3.9.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 3.7.0
124
+ version: 3.9.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rails
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -140,22 +140,22 @@ dependencies:
140
140
  name: rake
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '12.3'
146
143
  - - ">="
147
144
  - !ruby/object:Gem::Version
148
145
  version: 12.3.3
146
+ - - "~>"
147
+ - !ruby/object:Gem::Version
148
+ version: '13.0'
149
149
  type: :development
150
150
  prerelease: false
151
151
  version_requirements: !ruby/object:Gem::Requirement
152
152
  requirements:
153
- - - "~>"
154
- - !ruby/object:Gem::Version
155
- version: '12.3'
156
153
  - - ">="
157
154
  - !ruby/object:Gem::Version
158
155
  version: 12.3.3
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '13.0'
159
159
  - !ruby/object:Gem::Dependency
160
160
  name: rspec
161
161
  requirement: !ruby/object:Gem::Requirement
@@ -190,14 +190,14 @@ dependencies:
190
190
  requirements:
191
191
  - - "~>"
192
192
  - !ruby/object:Gem::Version
193
- version: '0.61'
193
+ version: '1.0'
194
194
  type: :development
195
195
  prerelease: false
196
196
  version_requirements: !ruby/object:Gem::Requirement
197
197
  requirements:
198
198
  - - "~>"
199
199
  - !ruby/object:Gem::Version
200
- version: '0.61'
200
+ version: '1.0'
201
201
  - !ruby/object:Gem::Dependency
202
202
  name: yard
203
203
  requirement: !ruby/object:Gem::Requirement
@@ -252,6 +252,7 @@ files:
252
252
  - lib/nandi/instructions/add_column.rb
253
253
  - lib/nandi/instructions/add_foreign_key.rb
254
254
  - lib/nandi/instructions/add_index.rb
255
+ - lib/nandi/instructions/add_reference.rb
255
256
  - lib/nandi/instructions/change_column_default.rb
256
257
  - lib/nandi/instructions/create_table.rb
257
258
  - lib/nandi/instructions/drop_constraint.rb
@@ -260,6 +261,7 @@ files:
260
261
  - lib/nandi/instructions/remove_column.rb
261
262
  - lib/nandi/instructions/remove_index.rb
262
263
  - lib/nandi/instructions/remove_not_null_constraint.rb
264
+ - lib/nandi/instructions/remove_reference.rb
263
265
  - lib/nandi/instructions/validate_constraint.rb
264
266
  - lib/nandi/lockfile.rb
265
267
  - lib/nandi/migration.rb
@@ -273,6 +275,7 @@ files:
273
275
  - lib/nandi/timeout_policies/concurrent.rb
274
276
  - lib/nandi/validation.rb
275
277
  - lib/nandi/validation/add_column_validator.rb
278
+ - lib/nandi/validation/add_reference_validator.rb
276
279
  - lib/nandi/validation/each_validator.rb
277
280
  - lib/nandi/validation/failure_helpers.rb
278
281
  - lib/nandi/validation/remove_index_validator.rb
@@ -285,6 +288,7 @@ files:
285
288
  - lib/templates/nandi/renderers/active_record/instructions/add_column/show.rb.erb
286
289
  - lib/templates/nandi/renderers/active_record/instructions/add_foreign_key/show.rb.erb
287
290
  - lib/templates/nandi/renderers/active_record/instructions/add_index/show.rb.erb
291
+ - lib/templates/nandi/renderers/active_record/instructions/add_reference/show.rb.erb
288
292
  - lib/templates/nandi/renderers/active_record/instructions/change_column_default/show.rb.erb
289
293
  - lib/templates/nandi/renderers/active_record/instructions/create_table/show.rb.erb
290
294
  - lib/templates/nandi/renderers/active_record/instructions/drop_constraint/show.rb.erb
@@ -293,6 +297,7 @@ files:
293
297
  - lib/templates/nandi/renderers/active_record/instructions/remove_column/show.rb.erb
294
298
  - lib/templates/nandi/renderers/active_record/instructions/remove_index/show.rb.erb
295
299
  - lib/templates/nandi/renderers/active_record/instructions/remove_not_null_constraint/show.rb.erb
300
+ - lib/templates/nandi/renderers/active_record/instructions/remove_reference/show.rb.erb
296
301
  - lib/templates/nandi/renderers/active_record/instructions/validate_constraint/show.rb.erb
297
302
  homepage: https://github.com/gocardless/nandi
298
303
  licenses:
@@ -306,14 +311,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
306
311
  requirements:
307
312
  - - ">="
308
313
  - !ruby/object:Gem::Version
309
- version: '0'
314
+ version: 2.4.0
310
315
  required_rubygems_version: !ruby/object:Gem::Requirement
311
316
  requirements:
312
317
  - - ">="
313
318
  - !ruby/object:Gem::Version
314
319
  version: '0'
315
320
  requirements: []
316
- rubygems_version: 3.0.3
321
+ rubygems_version: 3.1.2
317
322
  signing_key:
318
323
  specification_version: 4
319
324
  summary: Fear-free migrations for PostgreSQL