nandi 0.9.0 → 0.10.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 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