Control: tags 1019609 + patch
Control: tags 1019609 + pending

Dear maintainer,

I've prepared an NMU for ruby-activerecord-import (versioned as 1.4.0-0.1)
and uploaded it to DELAYED/14. Please feel free to tell me if I should 
cancel it.

cu
Adrian
diff -Nru ruby-activerecord-import-1.2.0/activerecord-import.gemspec ruby-activerecord-import-1.4.0/activerecord-import.gemspec
--- ruby-activerecord-import-1.2.0/activerecord-import.gemspec	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/activerecord-import.gemspec	2022-05-06 10:10:54.000000000 +0300
@@ -16,8 +16,8 @@
   gem.require_paths = ["lib"]
   gem.version       = ActiveRecord::Import::VERSION
 
-  gem.required_ruby_version = ">= 2.0.0"
+  gem.required_ruby_version = ">= 2.4.0"
 
-  gem.add_runtime_dependency "activerecord", ">= 3.2"
+  gem.add_runtime_dependency "activerecord", ">= 4.2"
   gem.add_development_dependency "rake"
 end
diff -Nru ruby-activerecord-import-1.2.0/benchmarks/benchmark.rb ruby-activerecord-import-1.4.0/benchmarks/benchmark.rb
--- ruby-activerecord-import-1.2.0/benchmarks/benchmark.rb	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/benchmarks/benchmark.rb	2022-05-06 10:10:54.000000000 +0300
@@ -20,7 +20,11 @@
 ActiveRecord::Base.configurations["test"] = YAML.load_file(File.join(benchmark_dir, "../test/database.yml"))[options.adapter]
 ActiveRecord::Base.logger = Logger.new("log/test.log")
 ActiveRecord::Base.logger.level = Logger::DEBUG
-ActiveRecord::Base.default_timezone = :utc
+if ActiveRecord.respond_to?(:default_timezone)
+  ActiveRecord.default_timezone = :utc
+else
+  ActiveRecord::Base.default_timezone = :utc
+end
 
 require "activerecord-import"
 ActiveRecord::Base.establish_connection(:test)
diff -Nru ruby-activerecord-import-1.2.0/CHANGELOG.md ruby-activerecord-import-1.4.0/CHANGELOG.md
--- ruby-activerecord-import-1.2.0/CHANGELOG.md	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/CHANGELOG.md	2022-05-06 10:10:54.000000000 +0300
@@ -1,3 +1,22 @@
+## Changes in 1.4.0
+
+### New Features
+
+  * Enable compatibility with frozen string literals. Thanks to @desheikh via \##760.
+
+## Changes in 1.3.0
+
+### Fixes
+
+* Ensure correct timestamp values are returned for models after insert. Thanks to @kos1kov via \##756.
+* Restore database_version method to public scope. Thanks to @beauraF via \##753.
+
+### New Features
+
+* Add support for ActiveRecord 7.0. Thanks to @nickhammond, @ryanwood, @jkowens via \##749 and \##752.
+* Add support for compound foreign keys. Thanks to @Uladzimiro via \##750.
+* Add support for :recursive combined with on_duplicate_key_update: :all. Thanks to @deathwish via \##746.
+
 ## Changes in 1.2.0
 
 ### Fixes
diff -Nru ruby-activerecord-import-1.2.0/debian/changelog ruby-activerecord-import-1.4.0/debian/changelog
--- ruby-activerecord-import-1.2.0/debian/changelog	2021-11-21 21:51:35.000000000 +0200
+++ ruby-activerecord-import-1.4.0/debian/changelog	2022-10-07 00:54:00.000000000 +0300
@@ -1,3 +1,11 @@
+ruby-activerecord-import (1.4.0-0.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * New upstream release.
+    - Fixes FTBFS. (Closes: #1019609)
+
+ -- Adrian Bunk <b...@debian.org>  Fri, 07 Oct 2022 00:54:00 +0300
+
 ruby-activerecord-import (1.2.0-1) unstable; urgency=medium
 
   * Team upload.
diff -Nru ruby-activerecord-import-1.2.0/Gemfile ruby-activerecord-import-1.4.0/Gemfile
--- ruby-activerecord-import-1.2.0/Gemfile	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/Gemfile	2022-05-06 10:10:54.000000000 +0300
@@ -22,11 +22,12 @@
   gem "mysql2",                 "~> #{mysql2_version}"
   gem "pg",                     "~> #{pg_version}"
   gem "sqlite3",                "~> #{sqlite3_version}"
-  gem "seamless_database_pool", "~> 1.0.20"
+  # seamless_database_pool requires Ruby ~> 2.0
+  gem "seamless_database_pool", "~> 1.0.20" if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.0.0')
 end
 
 platforms :jruby do
-  gem 'jdbc-mysql', '< 8', require: false
+  gem "jdbc-mysql"
   gem "jdbc-postgres"
   gem "activerecord-jdbcsqlite3-adapter",    "~> 1.3"
   gem "activerecord-jdbcmysql-adapter",      "~> 1.3"
@@ -44,14 +45,9 @@
   gem "ruby-debug", "= 0.10.4"
 end
 
-platforms :mri_19 do
-  gem "debugger"
-end
-
 platforms :ruby do
   gem "pry-byebug"
   gem "pry", "~> 0.12.0"
-  gem "rb-readline"
 end
 
 if version >= 4.0
diff -Nru ruby-activerecord-import-1.2.0/gemfiles/3.2.gemfile ruby-activerecord-import-1.4.0/gemfiles/3.2.gemfile
--- ruby-activerecord-import-1.2.0/gemfiles/3.2.gemfile	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/gemfiles/3.2.gemfile	1970-01-01 02:00:00.000000000 +0200
@@ -1,2 +0,0 @@
-gem 'activerecord', '~> 3.2.0'
-gem 'composite_primary_keys', '~> 5.0'
diff -Nru ruby-activerecord-import-1.2.0/gemfiles/4.0.gemfile ruby-activerecord-import-1.4.0/gemfiles/4.0.gemfile
--- ruby-activerecord-import-1.2.0/gemfiles/4.0.gemfile	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/gemfiles/4.0.gemfile	1970-01-01 02:00:00.000000000 +0200
@@ -1,2 +0,0 @@
-gem 'activerecord', '~> 4.0.0'
-gem 'composite_primary_keys', '~> 6.0'
diff -Nru ruby-activerecord-import-1.2.0/gemfiles/4.1.gemfile ruby-activerecord-import-1.4.0/gemfiles/4.1.gemfile
--- ruby-activerecord-import-1.2.0/gemfiles/4.1.gemfile	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/gemfiles/4.1.gemfile	1970-01-01 02:00:00.000000000 +0200
@@ -1,2 +0,0 @@
-gem 'activerecord', '~> 4.1.0'
-gem 'composite_primary_keys', '~> 7.0'
diff -Nru ruby-activerecord-import-1.2.0/gemfiles/6.1.gemfile ruby-activerecord-import-1.4.0/gemfiles/6.1.gemfile
--- ruby-activerecord-import-1.2.0/gemfiles/6.1.gemfile	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/gemfiles/6.1.gemfile	2022-05-06 10:10:54.000000000 +0300
@@ -1 +1,2 @@
 gem 'activerecord', '~> 6.1.0'
+gem 'composite_primary_keys', '~> 13.0'
diff -Nru ruby-activerecord-import-1.2.0/gemfiles/7.0.gemfile ruby-activerecord-import-1.4.0/gemfiles/7.0.gemfile
--- ruby-activerecord-import-1.2.0/gemfiles/7.0.gemfile	1970-01-01 02:00:00.000000000 +0200
+++ ruby-activerecord-import-1.4.0/gemfiles/7.0.gemfile	2022-05-06 10:10:54.000000000 +0300
@@ -0,0 +1 @@
+gem 'activerecord', '~> 7.0.0'
diff -Nru ruby-activerecord-import-1.2.0/.github/workflows/test.yaml ruby-activerecord-import-1.4.0/.github/workflows/test.yaml
--- ruby-activerecord-import-1.2.0/.github/workflows/test.yaml	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/.github/workflows/test.yaml	2022-05-06 10:10:54.000000000 +0300
@@ -20,16 +20,37 @@
       fail-fast: false
       matrix:
         ruby:
-          - 2.6
+          - 3.1
         env:
+          - AR_VERSION: '7.0'
+            RUBYOPT: --enable-frozen-string-literal
           - AR_VERSION: 6.1
-          - AR_VERSION: 6.0
-          - AR_VERSION: 5.2
-          - AR_VERSION: 5.1
+            RUBYOPT: --enable-frozen-string-literal
         include:
+          - ruby: '3.0'
+            env:
+              AR_VERSION: '7.0'
+          - ruby: '3.0'
+            env:
+              AR_VERSION: 6.1
+          - ruby: 2.7
+            env:
+              AR_VERSION: '7.0'
+          - ruby: 2.7
+            env:
+              AR_VERSION: 6.1
+          - ruby: 2.7
+            env:
+              AR_VERSION: '6.0'
+          - ruby: 2.6
+            env:
+              AR_VERSION: 5.2
+          - ruby: 2.6
+            env:
+              AR_VERSION: 5.1
           - ruby: 2.4
             env:
-              AR_VERSION: 5.0
+              AR_VERSION: '5.0'
           - ruby: 2.4
             env:
               AR_VERSION: 4.2
@@ -42,9 +63,7 @@
       - uses: ruby/setup-ruby@v1
         with:
           ruby-version: ${{ matrix.ruby }}
-      - name: Setup Bundler 1.x for Ruby 2.3
-        if: ${{ matrix.ruby == '2.3' }}
-        run: echo "BUNDLER_VERSION=1.17.3" >> $GITHUB_ENV
+          bundler-cache: true
       - name: Set up databases
         run: |
           sudo /etc/init.d/mysql start
@@ -56,18 +75,33 @@
           cp test/github/database.yml test/database.yml
         env:
           PGPASSWORD: postgres
-      - name: Install dependencies
-        run : AR_VERSION=${{ env.AR_VERSION }} bundle install
-      - name: Run tests
+      - name: Run tests with mysql2
         run: |
           bundle exec rake test:mysql2
           bundle exec rake test:mysql2_makara
           bundle exec rake test:mysql2spatial
+      - name: Run tests with postgresql
+        run: |
           bundle exec rake test:postgis
           bundle exec rake test:postgresql
           bundle exec rake test:postgresql_makara
+      - name: Run tests with seamless_database_pool
+        run: |
           bundle exec rake test:seamless_database_pool
+        if: ${{ matrix.ruby < '3.0' }}
+      - name: Run tests with sqlite
+        run: |
           bundle exec rake test:spatialite
           bundle exec rake test:sqlite3
+  lint:
+    runs-on: ubuntu-latest
+    env:
+      AR_VERSION: '7.0'
+    steps:
+      - uses: actions/checkout@v2
+      - uses: ruby/setup-ruby@v1
+        with:
+          ruby-version: 2.7
+          bundler-cache: true
       - name: Run Rubocop
         run: bundle exec rubocop
diff -Nru ruby-activerecord-import-1.2.0/lib/activerecord-import/adapters/mysql_adapter.rb ruby-activerecord-import-1.4.0/lib/activerecord-import/adapters/mysql_adapter.rb
--- ruby-activerecord-import-1.2.0/lib/activerecord-import/adapters/mysql_adapter.rb	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/lib/activerecord-import/adapters/mysql_adapter.rb	2022-05-06 10:10:54.000000000 +0300
@@ -82,7 +82,7 @@
   # Returns a generated ON DUPLICATE KEY UPDATE statement given the passed
   # in +args+.
   def sql_for_on_duplicate_key_update( table_name, *args ) # :nodoc:
-    sql = ' ON DUPLICATE KEY UPDATE '
+    sql = ' ON DUPLICATE KEY UPDATE '.dup
     arg = args.first
     locking_column = args.last
     if arg.is_a?( Array )
diff -Nru ruby-activerecord-import-1.2.0/lib/activerecord-import/adapters/postgresql_adapter.rb ruby-activerecord-import-1.4.0/lib/activerecord-import/adapters/postgresql_adapter.rb
--- ruby-activerecord-import-1.2.0/lib/activerecord-import/adapters/postgresql_adapter.rb	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/lib/activerecord-import/adapters/postgresql_adapter.rb	2022-05-06 10:10:54.000000000 +0300
@@ -123,7 +123,7 @@
     arg = { columns: arg } if arg.is_a?( Array ) || arg.is_a?( String )
     return unless arg.is_a?( Hash )
 
-    sql = ' ON CONFLICT '
+    sql = ' ON CONFLICT '.dup
     conflict_target = sql_for_conflict_target( arg )
 
     columns = arg.fetch( :columns, [] )
@@ -179,9 +179,9 @@
     if constraint_name.present?
       "ON CONSTRAINT #{constraint_name} "
     elsif conflict_target.present?
-      '(' << Array( conflict_target ).reject( &:blank? ).join( ', ' ) << ') '.tap do |sql|
-        sql << "WHERE #{index_predicate} " if index_predicate
-      end
+      sql = '(' + Array( conflict_target ).reject( &:blank? ).join( ', ' ) + ') '
+      sql += "WHERE #{index_predicate} " if index_predicate
+      sql
     end
   end
 
@@ -203,8 +203,6 @@
     true
   end
 
-  private
-
   def database_version
     defined?(postgresql_version) ? postgresql_version : super
   end
diff -Nru ruby-activerecord-import-1.2.0/lib/activerecord-import/adapters/sqlite3_adapter.rb ruby-activerecord-import-1.4.0/lib/activerecord-import/adapters/sqlite3_adapter.rb
--- ruby-activerecord-import-1.2.0/lib/activerecord-import/adapters/sqlite3_adapter.rb	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/lib/activerecord-import/adapters/sqlite3_adapter.rb	2022-05-06 10:10:54.000000000 +0300
@@ -97,7 +97,7 @@
     arg = { columns: arg } if arg.is_a?( Array ) || arg.is_a?( String )
     return unless arg.is_a?( Hash )
 
-    sql = ' ON CONFLICT '
+    sql = ' ON CONFLICT '.dup
     conflict_target = sql_for_conflict_target( arg )
 
     columns = arg.fetch( :columns, [] )
@@ -150,9 +150,9 @@
     conflict_target = args[:conflict_target]
     index_predicate = args[:index_predicate]
     if conflict_target.present?
-      '(' << Array( conflict_target ).reject( &:blank? ).join( ', ' ) << ') '.tap do |sql|
-        sql << "WHERE #{index_predicate} " if index_predicate
-      end
+      sql = '(' + Array( conflict_target ).reject( &:blank? ).join( ', ' ) + ') '
+      sql += "WHERE #{index_predicate} " if index_predicate
+      sql
     end
   end
 
@@ -166,8 +166,6 @@
     exception.is_a?(ActiveRecord::StatementInvalid) && exception.to_s.include?('duplicate key')
   end
 
-  private
-
   def database_version
     defined?(sqlite_version) ? sqlite_version : super
   end
diff -Nru ruby-activerecord-import-1.2.0/lib/activerecord-import/import.rb ruby-activerecord-import-1.4.0/lib/activerecord-import/import.rb
--- ruby-activerecord-import-1.2.0/lib/activerecord-import/import.rb	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/lib/activerecord-import/import.rb	2022-05-06 10:10:54.000000000 +0300
@@ -34,7 +34,7 @@
       @validate_callbacks = klass._validate_callbacks.dup
 
       @validate_callbacks.each_with_index do |callback, i|
-        filter = callback.raw_filter
+        filter = callback.respond_to?(:raw_filter) ? callback.raw_filter : callback.filter
         next unless filter.class.name =~ /Validations::PresenceValidator/ ||
                     (!@options[:validate_uniqueness] &&
                      filter.is_a?(ActiveRecord::Validations::UniquenessValidator))
@@ -734,7 +734,10 @@
         set_attributes_and_mark_clean(models, return_obj, timestamps, options)
 
         # if there are auto-save associations on the models we imported that are new, import them as well
-        import_associations(models, options.dup.merge(validate: false)) if options[:recursive]
+        if options[:recursive]
+          options[:on_duplicate_key_update] = on_duplicate_key_update unless on_duplicate_key_update.nil?
+          import_associations(models, options.dup.merge(validate: false))
+        end
       end
 
       return_obj
@@ -854,7 +857,7 @@
           model.id = id
 
           timestamps.each do |attr, value|
-            model.send(attr + "=", value)
+            model.send(attr + "=", value) if model.send(attr).nil?
           end
         end
       end
@@ -908,15 +911,19 @@
       changed_columns = model.changed
       association_reflections = model.class.reflect_on_all_associations(:belongs_to)
       association_reflections.each do |association_reflection|
-        column_name = association_reflection.foreign_key
         next if association_reflection.options[:polymorphic]
-        next if changed_columns.include?(column_name)
-        association = model.association(association_reflection.name)
-        association = association.target
-        next if association.blank? || model.public_send(column_name).present?
 
-        association_primary_key = association_reflection.association_primary_key
-        model.public_send("#{column_name}=", association.send(association_primary_key))
+        column_names = Array(association_reflection.foreign_key).map(&:to_s)
+        column_names.each_with_index do |column_name, column_index|
+          next if changed_columns.include?(column_name)
+
+          association = model.association(association_reflection.name)
+          association = association.target
+          next if association.blank? || model.public_send(column_name).present?
+
+          association_primary_key = Array(association_reflection.association_primary_key)[column_index]
+          model.public_send("#{column_name}=", association.send(association_primary_key))
+        end
       end
     end
 
@@ -929,8 +936,9 @@
       associated_objects_by_class = {}
       models.each { |model| find_associated_objects_for_import(associated_objects_by_class, model) }
 
-      # :on_duplicate_key_update and :returning not supported for associations
-      options.delete(:on_duplicate_key_update)
+      # :on_duplicate_key_update only supported for all fields
+      options.delete(:on_duplicate_key_update) unless options[:on_duplicate_key_update] == :all
+      # :returning not supported for associations
       options.delete(:returning)
 
       associated_objects_by_class.each_value do |associations|
@@ -1029,7 +1037,12 @@
       end
 
       # use tz as set in ActiveRecord::Base
-      timestamp = ActiveRecord::Base.default_timezone == :utc ? Time.now.utc : Time.now
+      default_timezone = if ActiveRecord.respond_to?(:default_timezone)
+        ActiveRecord.default_timezone
+      else
+        ActiveRecord::Base.default_timezone
+      end
+      timestamp = default_timezone == :utc ? Time.now.utc : Time.now
 
       [:create, :update].each do |action|
         timestamp_columns[action].each do |column|
diff -Nru ruby-activerecord-import-1.2.0/lib/activerecord-import/synchronize.rb ruby-activerecord-import-1.4.0/lib/activerecord-import/synchronize.rb
--- ruby-activerecord-import-1.2.0/lib/activerecord-import/synchronize.rb	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/lib/activerecord-import/synchronize.rb	2022-05-06 10:10:54.000000000 +0300
@@ -39,7 +39,7 @@
 
         next unless matched_instance
 
-        instance.send :clear_association_cache
+        instance.instance_variable_set :@association_cache, {}
         instance.send :clear_aggregation_cache if instance.respond_to?(:clear_aggregation_cache, true)
         instance.instance_variable_set :@attributes, matched_instance.instance_variable_get(:@attributes)
 
diff -Nru ruby-activerecord-import-1.2.0/lib/activerecord-import/version.rb ruby-activerecord-import-1.4.0/lib/activerecord-import/version.rb
--- ruby-activerecord-import-1.2.0/lib/activerecord-import/version.rb	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/lib/activerecord-import/version.rb	2022-05-06 10:10:54.000000000 +0300
@@ -1,5 +1,5 @@
 module ActiveRecord
   module Import
-    VERSION = "1.2.0".freeze
+    VERSION = "1.4.0".freeze
   end
 end
diff -Nru ruby-activerecord-import-1.2.0/README.markdown ruby-activerecord-import-1.4.0/README.markdown
--- ruby-activerecord-import-1.2.0/README.markdown	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/README.markdown	2022-05-06 10:10:54.000000000 +0300
@@ -433,7 +433,8 @@
 
 However, it is also possible to set just `:created_at` in specific records. In this case despite using `timestamps: true`,  `:created_at` will be updated only in records where that field is `nil`. Same rule applies for record associations when enabling the option `recursive: true`.
 
-If you are using custom time zones, these will be respected when performing imports as well as long as `ActiveRecord::Base.default_timezone` is set, which for practically all Rails apps it is
+If you are using custom time zones, these will be respected when performing imports as well as long as `ActiveRecord::Base.default_timezone` is set, which for practically all Rails apps it is.
+NOTE: If you are using ActiveRecord 7.0 or later, please use `ActiveRecord.default_timezone` instead.
 
 ### Callbacks
 
@@ -572,7 +573,7 @@
 
 Activerecord-Import adds the `.import` method onto `ActiveRecord::Base`. There are other gems, such as `elasticsearch-rails`, that do the same thing. In conflicts such as this, there is an aliased method named `.bulk_import` that can be used interchangeably.
 
-If you are using the `apartment` gem, there is a weird triple interaction between that gem, `activerecord-import`, and `activerecord` involving caching of the `sequence_name` of a model. This can be worked around by explcitly setting this value within the model. For example:
+If you are using the `apartment` gem, there is a weird triple interaction between that gem, `activerecord-import`, and `activerecord` involving caching of the `sequence_name` of a model. This can be worked around by explicitly setting this value within the model. For example:
 
 ```ruby
 class Post < ActiveRecord::Base
@@ -615,13 +616,13 @@
 
 This is one example of how to run the tests:
 
-```ruby
+```bash
 rm Gemfile.lock
-AR_VERSION=4.2 bundle install
-AR_VERSION=4.2 bundle exec rake test:postgresql test:sqlite3 test:mysql2
+AR_VERSION=7.0 bundle install
+AR_VERSION=7.0 bundle exec rake test:postgresql test:sqlite3 test:mysql2
 ```
 
-Once you have pushed up your changes, you can find your CI results [here](https://travis-ci.org/zdennis/activerecord-import/).
+Once you have pushed up your changes, you can find your CI results [here](https://github.com/zdennis/activerecord-import/actions).
 
 ## Issue Triage [![Open Source Helpers](https://www.codetriage.com/zdennis/activerecord-import/badges/users.svg)](https://www.codetriage.com/zdennis/activerecord-import)
 
diff -Nru ruby-activerecord-import-1.2.0/test/import_test.rb ruby-activerecord-import-1.4.0/test/import_test.rb
--- ruby-activerecord-import-1.2.0/test/import_test.rb	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/test/import_test.rb	2022-05-06 10:10:54.000000000 +0300
@@ -555,7 +555,11 @@
     context "when the timestamps columns are present" do
       setup do
         @existing_book = Book.create(title: "Fell", author_name: "Curry", publisher: "Bayer", created_at: 2.years.ago.utc, created_on: 2.years.ago.utc, updated_at: 2.years.ago.utc, updated_on: 2.years.ago.utc)
-        ActiveRecord::Base.default_timezone = :utc
+        if ActiveRecord.respond_to?(:default_timezone)
+          ActiveRecord.default_timezone = :utc
+        else
+          ActiveRecord::Base.default_timezone = :utc
+        end
         Timecop.freeze(time) do
           assert_difference "Book.count", +2 do
             Book.import %w(title author_name publisher created_at created_on updated_at updated_on), [["LDAP", "Big Bird", "Del Rey", nil, nil, nil, nil], [@existing_book.title, @existing_book.author_name, @existing_book.publisher, @existing_book.created_at, @existing_book.created_on, @existing_book.updated_at, @existing_book.updated_on]]
diff -Nru ruby-activerecord-import-1.2.0/test/models/customer.rb ruby-activerecord-import-1.4.0/test/models/customer.rb
--- ruby-activerecord-import-1.2.0/test/models/customer.rb	1970-01-01 02:00:00.000000000 +0200
+++ ruby-activerecord-import-1.4.0/test/models/customer.rb	2022-05-06 10:10:54.000000000 +0300
@@ -0,0 +1,6 @@
+class Customer < ActiveRecord::Base
+  has_many :orders,
+    inverse_of: :customer,
+    primary_key: %i(account_id id),
+    foreign_key: %i(account_id customer_id)
+end
diff -Nru ruby-activerecord-import-1.2.0/test/models/order.rb ruby-activerecord-import-1.4.0/test/models/order.rb
--- ruby-activerecord-import-1.2.0/test/models/order.rb	1970-01-01 02:00:00.000000000 +0200
+++ ruby-activerecord-import-1.4.0/test/models/order.rb	2022-05-06 10:10:54.000000000 +0300
@@ -0,0 +1,6 @@
+class Order < ActiveRecord::Base
+  belongs_to :customer,
+    inverse_of: :orders,
+    primary_key: %i(account_id id),
+    foreign_key: %i(account_id customer_id)
+end
diff -Nru ruby-activerecord-import-1.2.0/test/schema/generic_schema.rb ruby-activerecord-import-1.4.0/test/schema/generic_schema.rb
--- ruby-activerecord-import-1.2.0/test/schema/generic_schema.rb	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/test/schema/generic_schema.rb	2022-05-06 10:10:54.000000000 +0300
@@ -205,4 +205,15 @@
       );
     ).split.join(' ').strip
   end
+
+  create_table :customers, force: :cascade do |t|
+    t.integer :account_id
+    t.string :name
+  end
+
+  create_table :orders, force: :cascade do |t|
+    t.integer :account_id
+    t.integer :customer_id
+    t.integer :amount
+  end
 end
diff -Nru ruby-activerecord-import-1.2.0/test/support/postgresql/import_examples.rb ruby-activerecord-import-1.4.0/test/support/postgresql/import_examples.rb
--- ruby-activerecord-import-1.2.0/test/support/postgresql/import_examples.rb	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/test/support/postgresql/import_examples.rb	2022-05-06 10:10:54.000000000 +0300
@@ -281,7 +281,7 @@
   end
 
   describe "with binary field" do
-    let(:binary_value) { "\xE0'c\xB2\xB0\xB3Bh\\\xC2M\xB1m\\I\xC4r".force_encoding('ASCII-8BIT') }
+    let(:binary_value) { "\xE0'c\xB2\xB0\xB3Bh\\\xC2M\xB1m\\I\xC4r".dup.force_encoding('ASCII-8BIT') }
     it "imports the correct values for binary fields" do
       alarms = [Alarm.new(device_id: 1, alarm_type: 1, status: 1, secret_key: binary_value)]
       assert_difference "Alarm.count", +1 do
@@ -290,6 +290,30 @@
       assert_equal(binary_value, Alarm.first.secret_key)
     end
   end
+
+  unless ENV["SKIP_COMPOSITE_PK"]
+    describe "with composite foreign keys" do
+      let(:account_id) { 555 }
+      let(:customer) { Customer.new(account_id: account_id, name: "foo") }
+      let(:order) { Order.new(account_id: account_id, amount: 100, customer: customer) }
+
+      it "imports and correctly maps foreign keys" do
+        assert_difference "Customer.count", +1 do
+          Customer.import [customer]
+        end
+
+        assert_difference "Order.count", +1 do
+          Order.import [order]
+        end
+
+        db_customer = Customer.last
+        db_order = Order.last
+
+        assert_equal db_customer.orders.last, db_order
+        assert_not_equal db_order.customer_id, nil
+      end
+    end
+  end
 end
 
 def should_support_postgresql_upsert_functionality
diff -Nru ruby-activerecord-import-1.2.0/test/support/shared_examples/recursive_import.rb ruby-activerecord-import-1.4.0/test/support/shared_examples/recursive_import.rb
--- ruby-activerecord-import-1.2.0/test/support/shared_examples/recursive_import.rb	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/test/support/shared_examples/recursive_import.rb	2022-05-06 10:10:54.000000000 +0300
@@ -176,7 +176,7 @@
       end
     end
 
-    # If adapter supports on_duplicate_key_update, it is only applied to top level models so that SQL with invalid
+    # If adapter supports on_duplicate_key_update and specific columns are specified, it is only applied to top level models so that SQL with invalid
     # columns, keys, etc isn't generated for child associations when doing recursive import
     if ActiveRecord::Base.connection.supports_on_duplicate_key_update?
       describe "on_duplicate_key_update" do
@@ -190,6 +190,26 @@
             end
           end
         end
+
+        context "when :all fields are updated" do
+          setup do
+            Topic.import new_topics, recursive: true
+          end
+
+          it "updates associated objects" do
+            new_author_name = 'Richard Bachman'
+            topic = new_topics.first
+            topic.books.each do |book|
+              book.author_name = new_author_name
+            end
+            assert_nothing_raised do
+              Topic.import new_topics, recursive: true, on_duplicate_key_update: :all
+            end
+            Topic.find(topic.id).books.each do |book|
+              assert_equal new_author_name, book.author_name
+            end
+          end
+        end
       end
     end
 
diff -Nru ruby-activerecord-import-1.2.0/test/test_helper.rb ruby-activerecord-import-1.4.0/test/test_helper.rb
--- ruby-activerecord-import-1.2.0/test/test_helper.rb	2021-08-22 17:59:37.000000000 +0300
+++ ruby-activerecord-import-1.4.0/test/test_helper.rb	2022-05-06 10:10:54.000000000 +0300
@@ -51,14 +51,22 @@
 ActiveRecord::Base.logger.level = Logger::DEBUG
 
 if ENV['AR_VERSION'].to_f >= 6.0
-  yaml_config = YAML.load_file(test_dir.join("database.yml"))[adapter]
+  yaml_config = if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.2.1')
+    YAML.safe_load_file(test_dir.join("database.yml"), aliases: true)[adapter]
+  else
+    YAML.load_file(test_dir.join("database.yml"))[adapter]
+  end
   config = ActiveRecord::DatabaseConfigurations::HashConfig.new("test", adapter, yaml_config)
   ActiveRecord::Base.configurations.configurations << config
 else
   ActiveRecord::Base.configurations["test"] = YAML.load_file(test_dir.join("database.yml"))[adapter]
 end
 
-ActiveRecord::Base.default_timezone = :utc
+if ActiveRecord.respond_to?(:default_timezone)
+  ActiveRecord.default_timezone = :utc
+else
+  ActiveRecord::Base.default_timezone = :utc
+end
 
 require "activerecord-import"
 ActiveRecord::Base.establish_connection :test

Reply via email to