strong_migrations 0.2.2 → 0.2.3

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
- SHA1:
3
- metadata.gz: d1d122ea065266614d32562e0692da6e53a44113
4
- data.tar.gz: bffe96798471bf21ab7edb47a81ff4b97891b707
2
+ SHA256:
3
+ metadata.gz: fe026b71dc38ab1cc40189ff8eb858baa45ec0778bd4dd640cff57349aa067ea
4
+ data.tar.gz: 28698d9bc1804389fc4e1fdb9e9a3ae9499cc490b15bda953f312fe434a6aa41
5
5
  SHA512:
6
- metadata.gz: 28c244787f1be158f9efa4f3151a93247b1e231b3e2613d03ce5b324b00649ea7118529af59a14a9643f923ae7529435557ab5e97ffeedd8a0b7f51b83297912
7
- data.tar.gz: 88d883bd199c79f143c73cfd54b1a921fbe24549b82c847793d0ea8a10544d46b8c699a1d6895d4d1ff3a1b5440bf6c61b380c2e8b119d975ee2868e07212b4c
6
+ metadata.gz: 3fe33582e8f6f4c0aced4f162704a9810e044e11e115ac1813892750474c118a33f0fb2ee19883d4dce98bfc6862786eaaf1c7862b4fd3398c2bb032010316fb
7
+ data.tar.gz: 0e5bcf7c1a42dcebe09a5f249fd2cb063549c1617d8a161ae915e882ab30e7f9a72b19b38407f5a526b59174cf04bcfa04c790888b7ce069c58c5cf7116faf00
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.2.3
2
+
3
+ - Added check for `change_column_null`
4
+ - Added support for alphabetize columns with Makara
5
+ - Fixed migration reversibility with `auto_analyze`
6
+
1
7
  ## 0.2.2
2
8
 
3
9
  - Friendlier output
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,45 @@
1
+ # Contributing
2
+
3
+ First, thanks for wanting to contribute. You’re awesome! :heart:
4
+
5
+ ## Questions
6
+
7
+ Use [Stack Overflow](https://stackoverflow.com/) with the tag `strong-migrations`.
8
+
9
+ ## Feature Requests
10
+
11
+ Create an issue. Start the title with `[Idea]`.
12
+
13
+ ## Issues
14
+
15
+ Think you’ve discovered an issue?
16
+
17
+ 1. Search existing issues to see if it’s been reported.
18
+ 2. Try the `master` branch to make sure it hasn’t been fixed.
19
+
20
+ ```rb
21
+ gem "strong_migrations", github: "ankane/strong_migrations"
22
+ ```
23
+
24
+ If the above steps don’t help, create an issue. Include:
25
+
26
+ - Detailed steps to reproduce
27
+ - Complete backtraces for exceptions
28
+
29
+ ## Pull Requests
30
+
31
+ Fork the project and create a pull request. A few tips:
32
+
33
+ - Keep changes to a minimum. If you have multiple features or fixes, submit multiple pull requests.
34
+ - Follow the existing style. The code should read like it’s written by a single person.
35
+ - Add one or more tests if possible. Make sure existing tests pass with:
36
+
37
+ ```sh
38
+ bundle exec rake test
39
+ ```
40
+
41
+ Feel free to open an issue to get feedback on your idea before spending too much time on it.
42
+
43
+ ---
44
+
45
+ This contributing guide is released under [CCO](https://creativecommons.org/publicdomain/zero/1.0/) (public domain). Use it for your own project without attribution.
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Bob Remeika and David Waller, 2015 Andrew Kane
1
+ Copyright (c) 2013 Bob Remeika and David Waller, 2015-2018 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -16,7 +16,7 @@ gem 'strong_migrations'
16
16
 
17
17
  ## How It Works
18
18
 
19
- Strong Migrations detects potentially dangerous operations in migrations, prevents them from running, and gives instructions on safer ways to do what you want.
19
+ Strong Migrations detects potentially dangerous operations in migrations, prevents them from running by default, and provides instructions on safer ways to do what you want.
20
20
 
21
21
  ```
22
22
  __ __ _____ _______ _
@@ -45,6 +45,7 @@ The following operations can cause downtime or errors:
45
45
  - adding a column with a non-null default value to an existing table
46
46
  - removing a column
47
47
  - changing the type of a column
48
+ - setting a `NOT NULL` constraint with a default value
48
49
  - renaming a column
49
50
  - renaming a table
50
51
  - adding an index non-concurrently (Postgres only)
@@ -75,6 +76,8 @@ class AddSomeColumnToUsers < ActiveRecord::Migration[5.1]
75
76
  end
76
77
  ```
77
78
 
79
+ Don’t backfill existing rows in this migration, as it can cause downtime. See the next section for how to do it safely.
80
+
78
81
  ### Backfilling data
79
82
 
80
83
  To backfill data, use the Rails console or a separate migration with `disable_ddl_transaction!`. Avoid backfilling in a transaction, especially one that alters a table. See [this great article](https://wework.github.io/data/2015/11/05/add-columns-with-default-values-to-large-tables-in-rails-postgres/) on why.
@@ -166,9 +169,9 @@ class AddSomeIndexToUsers < ActiveRecord::Migration[5.1]
166
169
  end
167
170
  ```
168
171
 
169
- If you forget `disable_ddl_transaction!`, the migration will fail.
172
+ If you forget `disable_ddl_transaction!`, the migration will fail. Also, note that indexes on new tables (those created in the same migration) don’t require this.
170
173
 
171
- Also, note that indexes on new tables (those created in the same migration) don’t require this.
174
+ Check out [this gem](https://github.com/ankane/gindex) to quickly generate index migrations without memorizing the syntax.
172
175
 
173
176
  ### Adding a json column (Postgres)
174
177
 
@@ -261,7 +264,7 @@ StrongMigrations.auto_analyze = true
261
264
 
262
265
  ## Lock Timeout (Postgres)
263
266
 
264
- It’s a good idea to set a lock timeout for the database user that runs migrations. This way, if migrations can’t acquire a lock in a timely manner, other statements won’t be stuck behind it.
267
+ It’s a good idea to set a lock timeout for the database user that runs migrations. This way, if migrations can’t acquire a lock in a timely manner, other statements won’t be stuck behind it. Here’s a great explanation of [how lock queues work](https://www.citusdata.com/blog/2018/02/15/when-postgresql-blocks/).
265
268
 
266
269
  ```sql
267
270
  ALTER ROLE myuser SET lock_timeout = '10s';
@@ -269,9 +272,13 @@ ALTER ROLE myuser SET lock_timeout = '10s';
269
272
 
270
273
  There’s also [a gem](https://github.com/gocardless/activerecord-safer_migrations) you can use for this.
271
274
 
275
+ ## Bigint Primary Keys (Postgres & MySQL)
276
+
277
+ Rails 5.1+ uses `bigint` for primary keys to keep you from running out of ids. To get this in earlier versions of Rails, check out [this gem](https://github.com/Shopify/rails-bigint-primarykey).
278
+
272
279
  ## Additional Reading
273
280
 
274
- - [Rails Migrations with No Downtime](http://pedro.herokuapp.com/past/2011/7/13/rails_migrations_with_no_downtime/)
281
+ - [Rails Migrations with No Downtime](https://pedro.herokuapp.com/past/2011/7/13/rails_migrations_with_no_downtime/)
275
282
  - [Safe Operations For High Volume PostgreSQL](https://www.braintreepayments.com/blog/safe-operations-for-high-volume-postgresql/)
276
283
 
277
284
  ## Credits
@@ -1,9 +1,10 @@
1
1
  require "active_support"
2
- require "strong_migrations/version"
2
+
3
3
  require "strong_migrations/database_tasks"
4
- require "strong_migrations/unsafe_migration"
5
4
  require "strong_migrations/migration"
6
5
  require "strong_migrations/railtie" if defined?(Rails)
6
+ require "strong_migrations/unsafe_migration"
7
+ require "strong_migrations/version"
7
8
 
8
9
  module StrongMigrations
9
10
  class << self
@@ -122,7 +123,14 @@ Otherwise, remove the option.",
122
123
  execute:
123
124
  "The strong_migrations gem does not support inspecting what happens inside an
124
125
  execute call, so cannot help you here. Please make really sure that what
125
- you're doing is safe before proceeding, then wrap it in a safety_assured { ... } block."
126
+ you're doing is safe before proceeding, then wrap it in a safety_assured { ... } block.",
127
+
128
+ change_column_null:
129
+ "The last argument replaces existing NULLs with another value.
130
+ This runs a single UPDATE query, which can cause downtime.
131
+ Backfill NULLs manually in batches instead.
132
+
133
+ More info: https://github.com/ankane/strong_migrations#backfilling-data"
126
134
  }
127
135
  end
128
136
 
@@ -0,0 +1,11 @@
1
+ module StrongMigrations
2
+ module AlphabetizeColumns
3
+ def columns(*args)
4
+ super.sort_by(&:name)
5
+ end
6
+
7
+ def extensions(*args)
8
+ super.sort
9
+ end
10
+ end
11
+ end
@@ -57,6 +57,7 @@ module StrongMigrations
57
57
  when :create_table
58
58
  options = args[1] || {}
59
59
  raise_error :create_table if options[:force]
60
+ (@new_tables ||= []) << args[0].to_s
60
61
  when :add_reference
61
62
  options = args[2] || {}
62
63
  index_value = options.fetch(:index, ActiveRecord::VERSION::MAJOR >= 5 ? true : false)
@@ -65,16 +66,18 @@ module StrongMigrations
65
66
  end
66
67
  when :execute
67
68
  raise_error :execute
69
+ when :change_column_null
70
+ null = args[2]
71
+ default = args[3]
72
+ if !null && !default.nil?
73
+ raise_error :change_column_null
74
+ end
68
75
  end
69
76
  end
70
77
 
71
- if method == :create_table
72
- (@new_tables ||= []) << args[0].to_s
73
- end
74
-
75
78
  result = super
76
79
 
77
- if StrongMigrations.auto_analyze && postgresql? && method == :add_index
80
+ if StrongMigrations.auto_analyze && @direction == :up && postgresql? && method == :add_index
78
81
  connection.execute "ANALYZE VERBOSE #{connection.quote_table_name(args[0])}"
79
82
  end
80
83
 
@@ -5,6 +5,10 @@ module StrongMigrations
5
5
  class Railtie < Rails::Railtie
6
6
  rake_tasks do
7
7
  load "tasks/strong_migrations.rake"
8
+
9
+ ["db:drop", "db:reset", "db:schema:load", "db:structure:load"].each do |t|
10
+ Rake::Task[t].enhance ["strong_migrations:safety_assured"]
11
+ end
8
12
  end
9
13
  end
10
14
  end
@@ -1,3 +1,3 @@
1
1
  module StrongMigrations
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.3"
3
3
  end
@@ -10,21 +10,11 @@ namespace :strong_migrations do
10
10
  $stderr.puts "Dumping schema"
11
11
  ActiveRecord::Base.logger.level = Logger::INFO
12
12
 
13
- class << ActiveRecord::Base.connection
14
- alias_method :old_columns, :columns unless instance_methods.include?("old_columns")
15
- alias_method :old_extensions, :extensions unless instance_methods.include?("old_extensions")
16
-
17
- def columns(*args)
18
- old_columns(*args).sort_by(&:name)
19
- end
20
-
21
- def extensions(*args)
22
- old_extensions(*args).sort
23
- end
13
+ require "strong_migrations/alphabetize_columns"
14
+ ActiveRecord::Base.connection.class.prepend StrongMigrations::AlphabetizeColumns
15
+ if ActiveRecord::ConnectionAdapters.const_defined?('PostGISAdapter')
16
+ ActiveRecord::ConnectionAdapters::PostGISAdapter.prepend StrongMigrations::AlphabetizeColumns
24
17
  end
18
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend StrongMigrations::AlphabetizeColumns
25
19
  end
26
20
  end
27
-
28
- ["db:drop", "db:reset", "db:schema:load", "db:structure:load"].each do |t|
29
- Rake::Task[t].enhance ["strong_migrations:safety_assured"]
30
- end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strong_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
+ - Andrew Kane
7
8
  - Bob Remeika
8
9
  - David Waller
9
- - Andrew Kane
10
10
  autorequire:
11
- bindir: exe
11
+ bindir: bin
12
12
  cert_chain: []
13
- date: 2018-02-14 00:00:00.000000000 Z
13
+ date: 2018-07-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -84,29 +84,27 @@ dependencies:
84
84
  version: '1'
85
85
  description:
86
86
  email:
87
- - bob.remeika@gmail.com
88
87
  - andrew@chartkick.com
88
+ - bob.remeika@gmail.com
89
89
  executables: []
90
90
  extensions: []
91
91
  extra_rdoc_files: []
92
92
  files:
93
- - ".gitignore"
94
- - ".travis.yml"
95
93
  - CHANGELOG.md
96
- - Gemfile
94
+ - CONTRIBUTING.md
97
95
  - LICENSE.txt
98
96
  - README.md
99
- - Rakefile
100
97
  - lib/strong_migrations.rb
98
+ - lib/strong_migrations/alphabetize_columns.rb
101
99
  - lib/strong_migrations/database_tasks.rb
102
100
  - lib/strong_migrations/migration.rb
103
101
  - lib/strong_migrations/railtie.rb
104
102
  - lib/strong_migrations/unsafe_migration.rb
105
103
  - lib/strong_migrations/version.rb
106
104
  - lib/tasks/strong_migrations.rake
107
- - strong_migrations.gemspec
108
105
  homepage: https://github.com/ankane/strong_migrations
109
- licenses: []
106
+ licenses:
107
+ - MIT
110
108
  metadata: {}
111
109
  post_install_message:
112
110
  rdoc_options: []
@@ -116,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
114
  requirements:
117
115
  - - ">="
118
116
  - !ruby/object:Gem::Version
119
- version: '0'
117
+ version: '2.2'
120
118
  required_rubygems_version: !ruby/object:Gem::Requirement
121
119
  requirements:
122
120
  - - ">="
@@ -124,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
122
  version: '0'
125
123
  requirements: []
126
124
  rubyforge_project:
127
- rubygems_version: 2.6.13
125
+ rubygems_version: 2.7.7
128
126
  signing_key:
129
127
  specification_version: 4
130
128
  summary: Catch unsafe migrations at dev time
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- *.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
data/.travis.yml DELETED
@@ -1,20 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.4.1
4
- gemfile:
5
- - Gemfile
6
- - test/gemfiles/activerecord50.gemfile
7
- - test/gemfiles/activerecord42.gemfile
8
- script: bundle exec rake test
9
- before_script:
10
- - psql -c 'create database strong_migrations_test;' -U postgres
11
- - mysql -e 'create database strong_migrations_test;'
12
- notifications:
13
- email:
14
- on_success: never
15
- on_failure: change
16
- matrix:
17
- include:
18
- - gemfile: test/gemfiles/mysql2.gemfile
19
- env: ADAPTER=mysql2
20
- rvm: 2.4.1
data/Gemfile DELETED
@@ -1,5 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem "activerecord", "~> 5.1.0"
data/Rakefile DELETED
@@ -1,11 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
8
- t.warning = false
9
- end
10
-
11
- task default: :test
@@ -1,26 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "strong_migrations/version"
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "strong_migrations"
8
- spec.version = StrongMigrations::VERSION
9
- spec.authors = ["Bob Remeika", "David Waller", "Andrew Kane"]
10
- spec.email = ["bob.remeika@gmail.com", "andrew@chartkick.com"]
11
-
12
- spec.summary = "Catch unsafe migrations at dev time"
13
- spec.homepage = "https://github.com/ankane/strong_migrations"
14
-
15
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
- spec.bindir = "exe"
17
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
- spec.require_paths = ["lib"]
19
-
20
- spec.add_dependency "activerecord", ">= 3.2.0"
21
-
22
- spec.add_development_dependency "bundler"
23
- spec.add_development_dependency "rake"
24
- spec.add_development_dependency "minitest"
25
- spec.add_development_dependency "pg", "< 1"
26
- end