online_migrations 0.19.1 → 0.19.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
2
  SHA256:
3
- metadata.gz: 259343358d51032a296c3745f92aa0e7ab5fc8f2d5dc6cd124873876e523d525
4
- data.tar.gz: d07240d06faac048145ae8f54da1a947d197f9ff40bb2adf276625eb76bcafb5
3
+ metadata.gz: 4d8223e51d4016b3752a738ecbc04cc200c94ee44dd3d91a1be2aefbc74060a9
4
+ data.tar.gz: bbaa8a04c4b730ac33e1503c59782658f6810f9782b4f882ab2b19bd0e0402d2
5
5
  SHA512:
6
- metadata.gz: c67adbf061095fdcbb5fcaa5305f671d81cf434dc182bfe9e43d66dae41f87d24cf5a79bb4aca160a955c74dff20de5e217b20731fe022df1dece6246e0239c0
7
- data.tar.gz: 705397632e3afe3628776e854f74ff0ee70ada9d73d0d9e84c113289623d6240fc79b7823ca0dc05d3dab8dfd90c421c667b60ee394dbfb03c49afabd31ddc95
6
+ metadata.gz: 878031d1e81e5a069500e4c9c8f0d2bb9b9b60320e07ce101a7ae8680556a6a8114de4d0f6bf092340ec3651f9bbbb74fdc6e6453db39be3c22f6846b5a2ad94
7
+ data.tar.gz: 143a618f2d46a8a452c9f32ca87f44e47dffe5268bae00dcff008f54865cf272e20bb6aa4af7243cf642a195e64e9aed8269660f1658ebb3440bff12eeed37df
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## master (unreleased)
2
2
 
3
+ ## 0.19.3 (2024-08-09)
4
+
5
+ - Fix idempotency for `add_index`/`remove_index` for expression indexes
6
+
7
+ ## 0.19.2 (2024-07-09)
8
+
9
+ - Fix `add_reference_concurrently` to be idempotent when adding a foreign key
10
+ - Fix `enqueue_background_data_migration` to be idempotent
11
+
3
12
  ## 0.19.1 (2024-05-24)
4
13
 
5
14
  - Fix `add_index_in_background` to be idempotent
data/README.md CHANGED
@@ -169,7 +169,7 @@ Config-specific checks:
169
169
 
170
170
  - [changing the default value of a column](#changing-the-default-value-of-a-column)
171
171
 
172
- You can also add [custom checks](#custom-checks) or [disable specific checks](#disable-checks).
172
+ You can also add [custom checks](docs/configuring.md#custom-checks) or [disable specific checks](docs/configuring.md#disable-checks).
173
173
 
174
174
  ### Removing a column
175
175
 
@@ -544,7 +544,7 @@ The technique is built on top of database views, using the following steps:
544
544
  2. Create a VIEW using the old table name by pointing to the new table name
545
545
  3. Add a workaround for Active Record's schema cache
546
546
 
547
- For the previous example, to rename `name` column to `first_name` of the `users` table, we can run:
547
+ For the previous example, to rename `clients` table to `users`, we can run:
548
548
 
549
549
  ```sql
550
550
  BEGIN;
@@ -440,26 +440,22 @@ module OnlineMigrations
440
440
 
441
441
  migration_name = migration_name.name if migration_name.is_a?(Class)
442
442
 
443
- migration = Migration.new(
444
- migration_name: migration_name,
445
- arguments: arguments,
446
- **options
447
- )
448
-
449
- shards = Utils.shard_names(migration.migration_model)
450
- if shards.size > 1
451
- migration.children = shards.map do |shard|
452
- child = migration.dup
453
- child.shard = shard
454
- child
443
+ # Can't use `find_or_create_by` or hash syntax here, because it does not correctly work with json `arguments`.
444
+ existing_migration = Migration.find_by("migration_name = ? AND arguments = ? AND shard IS NULL", migration_name, arguments.to_json)
445
+ return existing_migration if existing_migration
446
+
447
+ Migration.create!(**options, migration_name: migration_name, arguments: arguments, shard: nil) do |migration|
448
+ shards = Utils.shard_names(migration.migration_model)
449
+ if shards.size > 1
450
+ migration.children = shards.map do |shard|
451
+ child = migration.dup
452
+ child.shard = shard
453
+ child
454
+ end
455
+
456
+ migration.composite = true
455
457
  end
456
-
457
- migration.composite = true
458
458
  end
459
-
460
- # This will save all the records using a transaction.
461
- migration.save!
462
- migration
463
459
  end
464
460
  end
465
461
  end
@@ -13,7 +13,7 @@ module OnlineMigrations
13
13
  # Runs one background migration job.
14
14
  def run_migration_job
15
15
  raise "Should not be called on a composite (with sharding) migration" if migration.composite?
16
- return if migration.cancelled?
16
+ return if migration.cancelled? || migration.succeeded?
17
17
 
18
18
  mark_as_running if migration.enqueued?
19
19
  migration_payload = notifications_payload(migration)
@@ -684,9 +684,17 @@ module OnlineMigrations
684
684
  def add_index(table_name, column_name, **options)
685
685
  __ensure_not_in_transaction! if options[:algorithm] == :concurrently
686
686
 
687
- # Rewrite this with `IndexDefinition#defined_for?` when Active Record >= 7.1 is supported.
688
- # See https://github.com/rails/rails/pull/45160.
689
- index = indexes(table_name).find { |i| __index_defined_for?(i, column_name, **options) }
687
+ index =
688
+ if column_name.is_a?(String) && column_name.match?(/\W/)
689
+ # Use only name to check if index exists, because it does not work for complex expressions.
690
+ index_name = (options[:name] || index_name(table_name, column_name)).to_s
691
+ indexes(table_name).find { |i| i.name == index_name }
692
+ else
693
+ # Rewrite this with `IndexDefinition#defined_for?` when Active Record >= 7.1 is supported.
694
+ # See https://github.com/rails/rails/pull/45160.
695
+ indexes(table_name).find { |i| __index_defined_for?(i, column_name, **options) }
696
+ end
697
+
690
698
  if index
691
699
  schema = __schema_for_table(table_name)
692
700
 
@@ -729,12 +737,22 @@ module OnlineMigrations
729
737
 
730
738
  __ensure_not_in_transaction! if options[:algorithm] == :concurrently
731
739
 
732
- if index_exists?(table_name, column_name, **options)
740
+ column = column_name || options[:column]
741
+ index_exists =
742
+ if column.is_a?(String) && column.match?(/\W/)
743
+ # Use only name to check if index exists, because it does not work for complex expressions.
744
+ index_name = options[:name] || index_name(table_name, column)
745
+ index_name_exists?(table_name, index_name)
746
+ else
747
+ index_exists?(table_name, column_name, **options)
748
+ end
749
+
750
+ if index_exists
733
751
  if OnlineMigrations.config.statement_timeout
734
752
  # "DROP INDEX CONCURRENTLY" requires a "SHARE UPDATE EXCLUSIVE" lock.
735
753
  # It only conflicts with constraint validations, other creating/removing indexes,
736
754
  # and some "ALTER TABLE"s.
737
- super(table_name, column_name, **options)
755
+ super
738
756
  else
739
757
  OnlineMigrations.deprecator.warn(<<~MSG)
740
758
  Running `remove_index` without a statement timeout is deprecated.
@@ -744,7 +762,7 @@ module OnlineMigrations
744
762
  MSG
745
763
 
746
764
  disable_statement_timeout do
747
- super(table_name, column_name, **options)
765
+ super
748
766
  end
749
767
  end
750
768
  else
@@ -773,7 +791,8 @@ module OnlineMigrations
773
791
  # @see https://edgeapi.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_foreign_key
774
792
  #
775
793
  def add_foreign_key(from_table, to_table, **options)
776
- if foreign_key_exists?(from_table, to_table, **options)
794
+ # Do not consider validation for idempotency.
795
+ if foreign_key_exists?(from_table, to_table, **options.except(:validate))
777
796
  message = +"Foreign key was not created because it already exists " \
778
797
  "(this can be due to an aborted migration or similar): from_table: #{from_table}, to_table: #{to_table}"
779
798
  message << ", #{options.inspect}" if options.any?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OnlineMigrations
4
- VERSION = "0.19.1"
4
+ VERSION = "0.19.3"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: online_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.1
4
+ version: 0.19.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - fatkodima
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-24 00:00:00.000000000 Z
11
+ date: 2024-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord