online_migrations 0.19.1 → 0.19.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
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