strong_migrations 1.4.1 → 1.4.4

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: a296161cd1d5cdd070c94c34bd250feb2d62cb7b5274205007bab92e50dc7d0a
4
- data.tar.gz: e95730e625ed31bb3745c0c55fddf4aa2cd6d7d99607add097d23ae1181a8b50
3
+ metadata.gz: 7444023bd5f0829a289ebc9d222a28f041a4e3789224438f9fd6bffa01fa6668
4
+ data.tar.gz: feb5010616cc8ef6cf36088be7a67bb0d74272cde79d0e9a0a442272bfa92d99
5
5
  SHA512:
6
- metadata.gz: '03479a3996622262cad8eab0843f6fdd266e041d854ab49ced8dd334e6c9709556f6887f7708d1eeab87f98524bb558e813457f5f0cbb4c16323557353438680'
7
- data.tar.gz: 263a6238d3cc34d1211f7f6c6410248f8ee104e475f04f5e3687efb8602389ab26b12ec9155a6e782fc828e733af85b9315e9a282b5589d39f5891b46a5a83e6
6
+ metadata.gz: '0599a3fef628ec724471ef53b7ad7358831e6b638bdd0ca3b7cb79c1b416da6c044793ecca5475f5e602e8a7d1235ced3ff3fda526f31b9c4a56990c8531f9b4'
7
+ data.tar.gz: 6aac91ecb348c6a04c25511adf7df5d3e97823f6b9acdfbfd86bac50c4f5856f15fdcc271f00d0fc6f1e5d2cfdbaf3da5e056b1476aaf9b224e7df89b9737e01
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 1.4.4 (2023-03-08)
2
+
3
+ - Fixed `add_foreign_key` with `name` and `column` options with `safe_by_default`
4
+
5
+ ## 1.4.3 (2023-02-19)
6
+
7
+ - Fixed check for `change_column` to account for charset with MySQL and MariaDB
8
+
9
+ ## 1.4.2 (2023-01-29)
10
+
11
+ - Added `alphabetize_schema` option
12
+
1
13
  ## 1.4.1 (2023-01-05)
2
14
 
3
15
  - Added support for multiple databases to `target_version`
data/README.md CHANGED
@@ -224,7 +224,7 @@ And some in MySQL and MariaDB:
224
224
 
225
225
  Type | Safe Changes
226
226
  --- | ---
227
- `string` | Increasing `:limit` from under 255 up to 255, increasing `:limit` from over 255 to the max
227
+ `string` | Increasing `:limit` from under 63 up to 63, increasing `:limit` from over 63 to the max (the threshold can be different if using an encoding other than `utf8mb4` - for instance, it’s 85 for `utf8mb3` and 255 for `latin1`)
228
228
 
229
229
  #### Good
230
230
 
@@ -840,23 +840,18 @@ StrongMigrations.auto_analyze = true
840
840
 
841
841
  ## Faster Migrations
842
842
 
843
- Only dump the schema when adding a new migration. If you use Git, add to the end of your `Rakefile`:
843
+ Only dump the schema when adding a new migration. If you use Git, add to `config/environments/development.rb`:
844
844
 
845
845
  ```rb
846
- task :faster_migrations do
847
- ActiveRecord::Base.dump_schema_after_migration = Rails.env.development? &&
848
- `git status db/migrate/ --porcelain`.present?
849
- end
850
-
851
- task "db:migrate": "faster_migrations"
846
+ config.active_record.dump_schema_after_migration = `git status db/migrate/ --porcelain`.present?
852
847
  ```
853
848
 
854
849
  ## Schema Sanity
855
850
 
856
- Columns can flip order in `db/schema.rb` when you have multiple developers. One way to prevent this is to [alphabetize them](https://www.pgrs.net/2008/03/12/alphabetize-schema-rb-columns/). Add to the end of your `Rakefile`:
851
+ Columns can flip order in `db/schema.rb` when you have multiple developers. One way to prevent this is to [alphabetize them](https://www.pgrs.net/2008/03/12/alphabetize-schema-rb-columns/). Add to `config/initializers/strong_migrations.rb`:
857
852
 
858
853
  ```ruby
859
- task "db:schema:dump": "strong_migrations:alphabetize_columns"
854
+ StrongMigrations.alphabetize_schema = true
860
855
  ```
861
856
 
862
857
  ## Permissions
@@ -52,14 +52,31 @@ module StrongMigrations
52
52
 
53
53
  case type.to_s
54
54
  when "string"
55
- # https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html
56
- # https://mariadb.com/kb/en/innodb-online-ddl-operations-with-the-instant-alter-algorithm/#changing-the-data-type-of-a-column
57
- # increased limit, but doesn't change number of length bytes
58
- # 1-255 = 1 byte, 256-65532 = 2 bytes, 65533+ = too big for varchar
59
55
  limit = options[:limit] || 255
60
- safe = ["varchar"].include?(existing_type) &&
61
- limit >= existing_column.limit &&
62
- (limit <= 255 || existing_column.limit > 255)
56
+ if ["varchar"].include?(existing_type) && limit >= existing_column.limit
57
+ # https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html
58
+ # https://mariadb.com/kb/en/innodb-online-ddl-operations-with-the-instant-alter-algorithm/#changing-the-data-type-of-a-column
59
+ # increased limit, but doesn't change number of length bytes
60
+ # 1-255 = 1 byte, 256-65532 = 2 bytes, 65533+ = too big for varchar
61
+
62
+ # account for charset
63
+ # https://dev.mysql.com/doc/refman/8.0/en/charset-mysql.html
64
+ # https://mariadb.com/kb/en/supported-character-sets-and-collations/
65
+ sql = <<~SQL
66
+ SELECT cs.MAXLEN
67
+ FROM INFORMATION_SCHEMA.CHARACTER_SETS cs
68
+ INNER JOIN INFORMATION_SCHEMA.COLLATIONS c ON c.CHARACTER_SET_NAME = cs.CHARACTER_SET_NAME
69
+ INNER JOIN INFORMATION_SCHEMA.TABLES t ON t.TABLE_COLLATION = c.COLLATION_NAME
70
+ WHERE t.TABLE_SCHEMA = database() AND t.TABLE_NAME = #{connection.quote(table)}
71
+ SQL
72
+ row = connection.select_all(sql).first
73
+ if row
74
+ threshold = 255 / row["MAXLEN"]
75
+ safe = limit <= threshold || existing_column.limit > threshold
76
+ else
77
+ warn "[strong_migrations] Could not determine charset"
78
+ end
79
+ end
63
80
  end
64
81
 
65
82
  safe
@@ -48,10 +48,20 @@ module StrongMigrations
48
48
  dir.up do
49
49
  @migration.add_foreign_key(from_table, to_table, *args, **options.merge(validate: false))
50
50
  disable_transaction
51
- @migration.validate_foreign_key(from_table, to_table)
51
+ validate_options = options.slice(:column, :name)
52
+ if ActiveRecord::VERSION::MAJOR >= 6
53
+ @migration.validate_foreign_key(from_table, to_table, **validate_options)
54
+ else
55
+ @migration.validate_foreign_key(from_table, validate_options.any? ? validate_options : to_table)
56
+ end
52
57
  end
53
58
  dir.down do
54
- @migration.remove_foreign_key(from_table, to_table)
59
+ remove_options = options.slice(:column, :name)
60
+ if ActiveRecord::VERSION::MAJOR >= 6
61
+ @migration.remove_foreign_key(from_table, to_table, **remove_options)
62
+ else
63
+ @migration.remove_foreign_key(from_table, remove_options.any? ? remove_options : to_table)
64
+ end
55
65
  end
56
66
  end
57
67
  end
@@ -0,0 +1,21 @@
1
+ module StrongMigrations
2
+ module SchemaDumper
3
+ def initialize(connection, *args, **options)
4
+ return super unless StrongMigrations.alphabetize_schema
5
+
6
+ super(WrappedConnection.new(connection), *args, **options)
7
+ end
8
+ end
9
+
10
+ class WrappedConnection
11
+ delegate_missing_to :@connection
12
+
13
+ def initialize(connection)
14
+ @connection = connection
15
+ end
16
+
17
+ def columns(*args, **options)
18
+ @connection.columns(*args, **options).sort_by(&:name)
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,3 @@
1
1
  module StrongMigrations
2
- VERSION = "1.4.1"
2
+ VERSION = "1.4.4"
3
3
  end
@@ -2,22 +2,22 @@
2
2
  require "active_support"
3
3
 
4
4
  # adapters
5
- require "strong_migrations/adapters/abstract_adapter"
6
- require "strong_migrations/adapters/mysql_adapter"
7
- require "strong_migrations/adapters/mariadb_adapter"
8
- require "strong_migrations/adapters/postgresql_adapter"
5
+ require_relative "strong_migrations/adapters/abstract_adapter"
6
+ require_relative "strong_migrations/adapters/mysql_adapter"
7
+ require_relative "strong_migrations/adapters/mariadb_adapter"
8
+ require_relative "strong_migrations/adapters/postgresql_adapter"
9
9
 
10
10
  # modules
11
- require "strong_migrations/checks"
12
- require "strong_migrations/safe_methods"
13
- require "strong_migrations/checker"
14
- require "strong_migrations/database_tasks"
15
- require "strong_migrations/migration"
16
- require "strong_migrations/migrator"
17
- require "strong_migrations/version"
11
+ require_relative "strong_migrations/checks"
12
+ require_relative "strong_migrations/safe_methods"
13
+ require_relative "strong_migrations/checker"
14
+ require_relative "strong_migrations/database_tasks"
15
+ require_relative "strong_migrations/migration"
16
+ require_relative "strong_migrations/migrator"
17
+ require_relative "strong_migrations/version"
18
18
 
19
19
  # integrations
20
- require "strong_migrations/railtie" if defined?(Rails)
20
+ require_relative "strong_migrations/railtie" if defined?(Rails)
21
21
 
22
22
  module StrongMigrations
23
23
  class Error < StandardError; end
@@ -28,7 +28,8 @@ module StrongMigrations
28
28
  attr_accessor :auto_analyze, :start_after, :checks, :error_messages,
29
29
  :target_postgresql_version, :target_mysql_version, :target_mariadb_version,
30
30
  :enabled_checks, :lock_timeout, :statement_timeout, :check_down, :target_version,
31
- :safe_by_default, :target_sql_mode, :lock_timeout_retries, :lock_timeout_retry_delay
31
+ :safe_by_default, :target_sql_mode, :lock_timeout_retries, :lock_timeout_retry_delay,
32
+ :alphabetize_schema
32
33
  attr_writer :lock_timeout_limit
33
34
  end
34
35
  self.auto_analyze = false
@@ -38,6 +39,7 @@ module StrongMigrations
38
39
  self.checks = []
39
40
  self.safe_by_default = false
40
41
  self.check_down = false
42
+ self.alphabetize_schema = false
41
43
 
42
44
  # private
43
45
  def self.developer_env?
@@ -84,7 +86,7 @@ module StrongMigrations
84
86
  end
85
87
 
86
88
  # load error messages
87
- require "strong_migrations/error_messages"
89
+ require_relative "strong_migrations/error_messages"
88
90
 
89
91
  ActiveSupport.on_load(:active_record) do
90
92
  ActiveRecord::Migration.prepend(StrongMigrations::Migration)
@@ -93,4 +95,7 @@ ActiveSupport.on_load(:active_record) do
93
95
  if defined?(ActiveRecord::Tasks::DatabaseTasks)
94
96
  ActiveRecord::Tasks::DatabaseTasks.singleton_class.prepend(StrongMigrations::DatabaseTasks)
95
97
  end
98
+
99
+ require_relative "strong_migrations/schema_dumper"
100
+ ActiveRecord::SchemaDumper.prepend(StrongMigrations::SchemaDumper)
96
101
  end
@@ -4,11 +4,6 @@ namespace :strong_migrations do
4
4
  $stderr.puts "Dumping schema"
5
5
  ActiveRecord::Base.logger.level = Logger::INFO
6
6
 
7
- require "strong_migrations/alphabetize_columns"
8
- ActiveRecord::Base.connection.class.prepend StrongMigrations::AlphabetizeColumns
9
- if ActiveRecord::ConnectionAdapters.const_defined?('PostGISAdapter')
10
- ActiveRecord::ConnectionAdapters::PostGISAdapter.prepend StrongMigrations::AlphabetizeColumns
11
- end
12
- ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend StrongMigrations::AlphabetizeColumns
7
+ StrongMigrations.alphabetize_schema = true
13
8
  end
14
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strong_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-01-05 00:00:00.000000000 Z
13
+ date: 2023-03-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -45,7 +45,6 @@ files:
45
45
  - lib/strong_migrations/adapters/mariadb_adapter.rb
46
46
  - lib/strong_migrations/adapters/mysql_adapter.rb
47
47
  - lib/strong_migrations/adapters/postgresql_adapter.rb
48
- - lib/strong_migrations/alphabetize_columns.rb
49
48
  - lib/strong_migrations/checker.rb
50
49
  - lib/strong_migrations/checks.rb
51
50
  - lib/strong_migrations/database_tasks.rb
@@ -54,6 +53,7 @@ files:
54
53
  - lib/strong_migrations/migrator.rb
55
54
  - lib/strong_migrations/railtie.rb
56
55
  - lib/strong_migrations/safe_methods.rb
56
+ - lib/strong_migrations/schema_dumper.rb
57
57
  - lib/strong_migrations/version.rb
58
58
  - lib/tasks/strong_migrations.rake
59
59
  homepage: https://github.com/ankane/strong_migrations
@@ -75,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
75
  - !ruby/object:Gem::Version
76
76
  version: '0'
77
77
  requirements: []
78
- rubygems_version: 3.4.1
78
+ rubygems_version: 3.4.6
79
79
  signing_key:
80
80
  specification_version: 4
81
81
  summary: Catch unsafe migrations in development
@@ -1,11 +0,0 @@
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