strong_migrations 0.2.2 → 0.2.3

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
- 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