activerecord-import 1.3.0 → 1.4.1

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.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yaml +39 -10
  3. data/.rubocop.yml +74 -8
  4. data/Brewfile +3 -1
  5. data/CHANGELOG.md +12 -0
  6. data/Gemfile +5 -7
  7. data/README.markdown +9 -8
  8. data/Rakefile +2 -0
  9. data/activerecord-import.gemspec +2 -1
  10. data/benchmarks/benchmark.rb +7 -1
  11. data/benchmarks/lib/base.rb +2 -0
  12. data/benchmarks/lib/cli_parser.rb +3 -1
  13. data/benchmarks/lib/float.rb +2 -0
  14. data/benchmarks/lib/mysql2_benchmark.rb +2 -0
  15. data/benchmarks/lib/output_to_csv.rb +2 -0
  16. data/benchmarks/lib/output_to_html.rb +4 -2
  17. data/benchmarks/models/test_innodb.rb +2 -0
  18. data/benchmarks/models/test_memory.rb +2 -0
  19. data/benchmarks/models/test_myisam.rb +2 -0
  20. data/benchmarks/schema/mysql2_schema.rb +2 -0
  21. data/gemfiles/4.2.gemfile +2 -0
  22. data/gemfiles/5.0.gemfile +2 -0
  23. data/gemfiles/5.1.gemfile +2 -0
  24. data/gemfiles/5.2.gemfile +2 -0
  25. data/gemfiles/6.0.gemfile +2 -0
  26. data/gemfiles/6.1.gemfile +2 -0
  27. data/gemfiles/7.0.gemfile +4 -1
  28. data/lib/activerecord-import/active_record/adapters/abstract_adapter.rb +2 -0
  29. data/lib/activerecord-import/active_record/adapters/jdbcmysql_adapter.rb +2 -0
  30. data/lib/activerecord-import/active_record/adapters/jdbcpostgresql_adapter.rb +2 -0
  31. data/lib/activerecord-import/active_record/adapters/jdbcsqlite3_adapter.rb +2 -0
  32. data/lib/activerecord-import/active_record/adapters/mysql2_adapter.rb +2 -0
  33. data/lib/activerecord-import/active_record/adapters/postgresql_adapter.rb +2 -0
  34. data/lib/activerecord-import/active_record/adapters/seamless_database_pool_adapter.rb +2 -0
  35. data/lib/activerecord-import/active_record/adapters/sqlite3_adapter.rb +2 -0
  36. data/lib/activerecord-import/adapters/abstract_adapter.rb +2 -0
  37. data/lib/activerecord-import/adapters/em_mysql2_adapter.rb +2 -0
  38. data/lib/activerecord-import/adapters/mysql2_adapter.rb +2 -0
  39. data/lib/activerecord-import/adapters/mysql_adapter.rb +3 -1
  40. data/lib/activerecord-import/adapters/postgresql_adapter.rb +41 -28
  41. data/lib/activerecord-import/adapters/sqlite3_adapter.rb +8 -6
  42. data/lib/activerecord-import/base.rb +3 -1
  43. data/lib/activerecord-import/import.rb +21 -10
  44. data/lib/activerecord-import/mysql2.rb +2 -0
  45. data/lib/activerecord-import/postgresql.rb +2 -0
  46. data/lib/activerecord-import/sqlite3.rb +2 -0
  47. data/lib/activerecord-import/synchronize.rb +2 -0
  48. data/lib/activerecord-import/value_sets_parser.rb +2 -0
  49. data/lib/activerecord-import/version.rb +3 -1
  50. data/lib/activerecord-import.rb +3 -1
  51. data/test/adapters/jdbcmysql.rb +2 -0
  52. data/test/adapters/jdbcpostgresql.rb +2 -0
  53. data/test/adapters/jdbcsqlite3.rb +2 -0
  54. data/test/adapters/makara_postgis.rb +2 -0
  55. data/test/adapters/mysql2.rb +2 -0
  56. data/test/adapters/mysql2_makara.rb +2 -0
  57. data/test/adapters/mysql2spatial.rb +2 -0
  58. data/test/adapters/postgis.rb +2 -0
  59. data/test/adapters/postgresql.rb +2 -0
  60. data/test/adapters/postgresql_makara.rb +2 -0
  61. data/test/adapters/seamless_database_pool.rb +2 -0
  62. data/test/adapters/spatialite.rb +2 -0
  63. data/test/adapters/sqlite3.rb +2 -0
  64. data/test/import_test.rb +26 -1
  65. data/test/jdbcmysql/import_test.rb +2 -0
  66. data/test/jdbcpostgresql/import_test.rb +2 -0
  67. data/test/jdbcsqlite3/import_test.rb +2 -0
  68. data/test/makara_postgis/import_test.rb +2 -0
  69. data/test/models/account.rb +2 -0
  70. data/test/models/alarm.rb +2 -0
  71. data/test/models/animal.rb +2 -0
  72. data/test/models/bike_maker.rb +2 -0
  73. data/test/models/book.rb +2 -0
  74. data/test/models/car.rb +2 -0
  75. data/test/models/card.rb +2 -0
  76. data/test/models/chapter.rb +2 -0
  77. data/test/models/customer.rb +2 -0
  78. data/test/models/deck.rb +2 -0
  79. data/test/models/dictionary.rb +2 -0
  80. data/test/models/discount.rb +2 -0
  81. data/test/models/end_note.rb +2 -0
  82. data/test/models/group.rb +2 -0
  83. data/test/models/order.rb +2 -0
  84. data/test/models/playing_card.rb +2 -0
  85. data/test/models/promotion.rb +2 -0
  86. data/test/models/question.rb +2 -0
  87. data/test/models/rule.rb +2 -0
  88. data/test/models/tag.rb +3 -0
  89. data/test/models/tag_alias.rb +5 -0
  90. data/test/models/topic.rb +2 -0
  91. data/test/models/user.rb +2 -0
  92. data/test/models/user_token.rb +2 -0
  93. data/test/models/vendor.rb +2 -0
  94. data/test/models/widget.rb +2 -0
  95. data/test/mysql2/import_test.rb +2 -0
  96. data/test/mysql2_makara/import_test.rb +2 -0
  97. data/test/mysqlspatial2/import_test.rb +2 -0
  98. data/test/postgis/import_test.rb +2 -0
  99. data/test/postgresql/import_test.rb +2 -0
  100. data/test/schema/generic_schema.rb +8 -0
  101. data/test/schema/jdbcpostgresql_schema.rb +2 -0
  102. data/test/schema/mysql2_schema.rb +2 -0
  103. data/test/schema/postgis_schema.rb +2 -0
  104. data/test/schema/postgresql_schema.rb +2 -0
  105. data/test/schema/sqlite3_schema.rb +2 -0
  106. data/test/schema/version.rb +2 -0
  107. data/test/sqlite3/import_test.rb +2 -0
  108. data/test/support/active_support/test_case_extensions.rb +2 -0
  109. data/test/support/assertions.rb +2 -0
  110. data/test/support/factories.rb +2 -0
  111. data/test/support/generate.rb +4 -2
  112. data/test/support/mysql/import_examples.rb +2 -1
  113. data/test/support/postgresql/import_examples.rb +41 -2
  114. data/test/support/shared_examples/on_duplicate_key_ignore.rb +2 -0
  115. data/test/support/shared_examples/on_duplicate_key_update.rb +2 -0
  116. data/test/support/shared_examples/recursive_import.rb +2 -0
  117. data/test/support/sqlite3/import_examples.rb +2 -1
  118. data/test/synchronize_test.rb +2 -0
  119. data/test/test_helper.rb +18 -2
  120. data/test/value_sets_bytes_parser_test.rb +2 -0
  121. data/test/value_sets_records_parser_test.rb +2 -0
  122. metadata +5 -3
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
4
 
3
5
  require File.expand_path(File.dirname(__FILE__) + '/../support/assertions')
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
4
  require File.expand_path(File.dirname(__FILE__) + '/../support/postgresql/import_examples')
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
4
  require File.expand_path(File.dirname(__FILE__) + '/../support/postgresql/import_examples')
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ActiveRecord::Schema.define do
2
4
  create_table :schema_info, force: :cascade do |t|
3
5
  t.integer :version, unique: true
@@ -204,6 +206,12 @@ ActiveRecord::Schema.define do
204
206
  PRIMARY KEY (tag_id, publisher_id)
205
207
  );
206
208
  ).split.join(' ').strip
209
+
210
+ create_table :tag_aliases, force: :cascade do |t|
211
+ t.integer :tag_id, null: false
212
+ t.integer :parent_id, null: false
213
+ t.string :alias, null: false
214
+ end
207
215
  end
208
216
 
209
217
  create_table :customers, force: :cascade do |t|
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/postgresql_schema')
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ActiveRecord::Schema.define do
2
4
  create_table :books, force: :cascade do |t|
3
5
  t.string :title, null: false
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/postgresql_schema')
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ActiveRecord::Schema.define do
2
4
  execute('CREATE extension IF NOT EXISTS "hstore";')
3
5
  execute('CREATE extension IF NOT EXISTS "pgcrypto";')
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ActiveRecord::Schema.define do
2
4
  create_table :alarms, force: true do |t|
3
5
  t.column :device_id, :integer, null: false
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class SchemaInfo < ActiveRecord::Base
2
4
  if respond_to?(:table_name=)
3
5
  self.table_name = 'schema_info'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
4
  require File.expand_path(File.dirname(__FILE__) + '/../support/sqlite3/import_examples')
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ActiveSupport::TestCase
2
4
  include ActiveRecord::TestFixtures
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ActiveSupport::TestCase
2
4
  module ImportAssertions
3
5
  def self.extended(klass)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  FactoryBot.define do
2
4
  sequence(:book_title) { |n| "Book #{n}" }
3
5
  sequence(:chapter_title) { |n| "Chapter #{n}" }
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ActiveSupport::TestCase
2
- def Build(*args) # rubocop:disable Style/MethodName
4
+ def Build(*args) # rubocop:disable Naming/MethodName
3
5
  n = args.shift if args.first.is_a?(Numeric)
4
6
  factory = args.shift
5
7
  factory_bot_args = args.shift || {}
@@ -13,7 +15,7 @@ class ActiveSupport::TestCase
13
15
  end
14
16
  end
15
17
 
16
- def Generate(*args) # rubocop:disable Style/MethodName
18
+ def Generate(*args) # rubocop:disable Naming/MethodName
17
19
  n = args.shift if args.first.is_a?(Numeric)
18
20
  factory = args.shift
19
21
  factory_bot_args = args.shift || {}
@@ -1,4 +1,5 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
+
2
3
  def should_support_mysql_import_functionality
3
4
  # Forcefully disable strict mode for this session.
4
5
  ActiveRecord::Base.connection.execute "set sql_mode='STRICT_ALL_TABLES'"
@@ -1,4 +1,5 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
+
2
3
  def should_support_postgresql_import_functionality
3
4
  should_support_recursive_import
4
5
 
@@ -102,6 +103,8 @@ def should_support_postgresql_import_functionality
102
103
  books.first.id.to_s
103
104
  end
104
105
  end
106
+ let(:true_returning_value) { ENV['AR_VERSION'].to_f >= 5.0 ? true : 't' }
107
+ let(:false_returning_value) { ENV['AR_VERSION'].to_f >= 5.0 ? false : 'f' }
105
108
 
106
109
  it "creates records" do
107
110
  assert_difference("Book.count", +1) { result }
@@ -150,6 +153,34 @@ def should_support_postgresql_import_functionality
150
153
  end
151
154
  end
152
155
 
156
+ context "when returning is raw sql" do
157
+ let(:result) { Book.import(books, returning: "title, (xmax = '0') AS inserted") }
158
+
159
+ setup { result }
160
+
161
+ it "returns ids" do
162
+ assert_equal [book_id], result.ids
163
+ end
164
+
165
+ it "returns specified columns" do
166
+ assert_equal [['It', true_returning_value]], result.results
167
+ end
168
+ end
169
+
170
+ context "when returning contains raw sql" do
171
+ let(:result) { Book.import(books, returning: [:title, "id, (xmax = '0') AS inserted"]) }
172
+
173
+ setup { result }
174
+
175
+ it "returns ids" do
176
+ assert_equal [book_id], result.ids
177
+ end
178
+
179
+ it "returns specified columns" do
180
+ assert_equal [['It', book_id, true_returning_value]], result.results
181
+ end
182
+ end
183
+
153
184
  context "setting model attributes" do
154
185
  let(:code) { 'abc' }
155
186
  let(:discount) { 0.10 }
@@ -179,6 +210,14 @@ def should_support_postgresql_import_functionality
179
210
  assert_equal updated_promotion.discount, discount
180
211
  end
181
212
  end
213
+
214
+ context 'returning raw sql' do
215
+ let(:returning_columns) { [:discount, "(xmax = '0') AS inserted"] }
216
+
217
+ it "sets custom model attributes" do
218
+ assert_equal updated_promotion.inserted, false_returning_value
219
+ end
220
+ end
182
221
  end
183
222
  end
184
223
  end
@@ -281,7 +320,7 @@ def should_support_postgresql_import_functionality
281
320
  end
282
321
 
283
322
  describe "with binary field" do
284
- let(:binary_value) { "\xE0'c\xB2\xB0\xB3Bh\\\xC2M\xB1m\\I\xC4r".force_encoding('ASCII-8BIT') }
323
+ let(:binary_value) { "\xE0'c\xB2\xB0\xB3Bh\\\xC2M\xB1m\\I\xC4r".dup.force_encoding('ASCII-8BIT') }
285
324
  it "imports the correct values for binary fields" do
286
325
  alarms = [Alarm.new(device_id: 1, alarm_type: 1, status: 1, secret_key: binary_value)]
287
326
  assert_difference "Alarm.count", +1 do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  def should_support_on_duplicate_key_ignore
2
4
  describe "#import" do
3
5
  extend ActiveSupport::TestCase::ImportAssertions
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  def should_support_basic_on_duplicate_key_update
2
4
  describe "#import" do
3
5
  extend ActiveSupport::TestCase::ImportAssertions
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  def should_support_recursive_import
2
4
  describe "importing objects with associations" do
3
5
  let(:new_topics) { Build(num_topics, :topic_with_book) }
@@ -1,4 +1,5 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
+
2
3
  def should_support_sqlite3_import_functionality
3
4
  if ActiveRecord::Base.connection.supports_on_duplicate_key_update?
4
5
  should_support_sqlite_upsert_functionality
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper', __FILE__)
2
4
 
3
5
  describe ".synchronize" do
data/test/test_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
  require 'rake'
3
5
  test_dir = Pathname.new File.dirname(__FILE__)
@@ -50,15 +52,29 @@ FileUtils.mkdir_p 'log'
50
52
  ActiveRecord::Base.logger = Logger.new("log/test.log")
51
53
  ActiveRecord::Base.logger.level = Logger::DEBUG
52
54
 
55
+ if ActiveRecord.respond_to?(:use_yaml_unsafe_load)
56
+ ActiveRecord.use_yaml_unsafe_load = true
57
+ elsif ActiveRecord::Base.respond_to?(:use_yaml_unsafe_load)
58
+ ActiveRecord::Base.use_yaml_unsafe_load = true
59
+ end
60
+
53
61
  if ENV['AR_VERSION'].to_f >= 6.0
54
- yaml_config = YAML.load_file(test_dir.join("database.yml"))[adapter]
62
+ yaml_config = if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.2.1')
63
+ YAML.safe_load_file(test_dir.join("database.yml"), aliases: true)[adapter]
64
+ else
65
+ YAML.load_file(test_dir.join("database.yml"))[adapter]
66
+ end
55
67
  config = ActiveRecord::DatabaseConfigurations::HashConfig.new("test", adapter, yaml_config)
56
68
  ActiveRecord::Base.configurations.configurations << config
57
69
  else
58
70
  ActiveRecord::Base.configurations["test"] = YAML.load_file(test_dir.join("database.yml"))[adapter]
59
71
  end
60
72
 
61
- ActiveRecord::Base.default_timezone = :utc
73
+ if ActiveRecord.respond_to?(:default_timezone)
74
+ ActiveRecord.default_timezone = :utc
75
+ else
76
+ ActiveRecord::Base.default_timezone = :utc
77
+ end
62
78
 
63
79
  require "activerecord-import"
64
80
  ActiveRecord::Base.establish_connection :test
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
4
 
3
5
  require 'activerecord-import/value_sets_parser'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
4
 
3
5
  require 'activerecord-import/value_sets_parser'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-import
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zach Dennis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-17 00:00:00.000000000 Z
11
+ date: 2022-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -138,6 +138,7 @@ files:
138
138
  - test/models/question.rb
139
139
  - test/models/rule.rb
140
140
  - test/models/tag.rb
141
+ - test/models/tag_alias.rb
141
142
  - test/models/topic.rb
142
143
  - test/models/user.rb
143
144
  - test/models/user_token.rb
@@ -189,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
190
  - !ruby/object:Gem::Version
190
191
  version: '0'
191
192
  requirements: []
192
- rubygems_version: 3.0.3
193
+ rubygems_version: 3.0.3.1
193
194
  signing_key:
194
195
  specification_version: 4
195
196
  summary: Bulk insert extension for ActiveRecord
@@ -234,6 +235,7 @@ test_files:
234
235
  - test/models/question.rb
235
236
  - test/models/rule.rb
236
237
  - test/models/tag.rb
238
+ - test/models/tag_alias.rb
237
239
  - test/models/topic.rb
238
240
  - test/models/user.rb
239
241
  - test/models/user_token.rb