activerecord-import 0.18.3 → 0.19.0
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 +4 -4
- data/CHANGELOG.md +14 -0
- data/gemfiles/5.1.gemfile +1 -1
- data/lib/activerecord-import/adapters/postgresql_adapter.rb +5 -1
- data/lib/activerecord-import/import.rb +19 -3
- data/lib/activerecord-import/version.rb +1 -1
- data/test/import_test.rb +10 -0
- data/test/support/postgresql/import_examples.rb +33 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a15b84eab5c3e37adc77106a0c55a8cb030d6d3
|
4
|
+
data.tar.gz: b2cab0765b2dcb2465dd6178a767836da1b61d65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c70a9f7ea0ac30697a9342d3243b459a38fc78048ee7287b4172da5353939fd4fbb73567a9ab7c79b7b0ef9e3a367b8ea9c0e6ec78c89050db36964735fc4782
|
7
|
+
data.tar.gz: 1193d03b7d5ddb8cab84110a2d34c57df9a5c6fca2d38c9967d64dd0e9573d7b3c85a88c3448b3f5a6270a6ddafc459083e5fecd2d50a26a79d7c7c50184ce3a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## Changes in 0.19.0
|
2
|
+
|
3
|
+
### New Features
|
4
|
+
|
5
|
+
* For PostgreSQL, add option to set WHERE condition in conflict_action. Thanks to
|
6
|
+
@Saidbek via \#423.
|
7
|
+
|
8
|
+
### Fixes
|
9
|
+
|
10
|
+
* Fix issue importing saved records with serialized fields. Thanks to
|
11
|
+
@Andreis13, @jkowens via \#425.
|
12
|
+
* Fix issue importing records that have columns defined with default values
|
13
|
+
that are functions or expressions. Thanks to @Andreis13, @jkowens via \#428.
|
14
|
+
|
1
15
|
## Changes in 0.18.3
|
2
16
|
|
3
17
|
### Fixes
|
data/gemfiles/5.1.gemfile
CHANGED
@@ -1 +1 @@
|
|
1
|
-
gem 'activerecord', '~> 5.1.0
|
1
|
+
gem 'activerecord', '~> 5.1.0'
|
@@ -87,10 +87,11 @@ module ActiveRecord::Import::PostgreSQLAdapter
|
|
87
87
|
arg = { columns: arg } if arg.is_a?( Array ) || arg.is_a?( String )
|
88
88
|
return unless arg.is_a?( Hash )
|
89
89
|
|
90
|
-
sql =
|
90
|
+
sql = ' ON CONFLICT '
|
91
91
|
conflict_target = sql_for_conflict_target( arg )
|
92
92
|
|
93
93
|
columns = arg.fetch( :columns, [] )
|
94
|
+
condition = arg[:condition]
|
94
95
|
if columns.respond_to?( :empty? ) && columns.empty?
|
95
96
|
return sql << "#{conflict_target}DO NOTHING"
|
96
97
|
end
|
@@ -110,6 +111,9 @@ module ActiveRecord::Import::PostgreSQLAdapter
|
|
110
111
|
else
|
111
112
|
raise ArgumentError, 'Expected :columns to be an Array or Hash'
|
112
113
|
end
|
114
|
+
|
115
|
+
sql << " WHERE #{condition}" if condition.present?
|
116
|
+
|
113
117
|
sql
|
114
118
|
end
|
115
119
|
|
@@ -350,6 +350,15 @@ class ActiveRecord::Base
|
|
350
350
|
#
|
351
351
|
# BlogPost.import columns, values, on_duplicate_key_update: { constraint_name: :blog_posts_pkey, columns: [ :date_modified ] }
|
352
352
|
#
|
353
|
+
# ====== :condition
|
354
|
+
#
|
355
|
+
# The :condition attribute optionally specifies a WHERE condition
|
356
|
+
# on :conflict_action. Only rows for which this expression returns true will be updated.
|
357
|
+
# Note that it's evaluated last, after a conflict has been identified as a candidate to update.
|
358
|
+
# Below is an example:
|
359
|
+
#
|
360
|
+
# BlogPost.import columns, values, on_duplicate_key_update: { conflict_target: [ :author_id ], condition: "blog_posts.title NOT LIKE '%sample%'", columns: [ :author_name ] }
|
361
|
+
|
353
362
|
# ====== :columns
|
354
363
|
#
|
355
364
|
# The :columns attribute can be either an Array or a Hash.
|
@@ -426,13 +435,20 @@ class ActiveRecord::Base
|
|
426
435
|
column_names.delete(primary_key)
|
427
436
|
end
|
428
437
|
|
429
|
-
stored_attrs = respond_to?(:stored_attributes) ? stored_attributes : {}
|
430
438
|
default_values = column_defaults
|
439
|
+
stored_attrs = respond_to?(:stored_attributes) ? stored_attributes : {}
|
440
|
+
serialized_attrs = if defined?(ActiveRecord::Type::Serialized)
|
441
|
+
attrs = column_names.select { |c| type_for_attribute(c.to_s).class == ActiveRecord::Type::Serialized }
|
442
|
+
Hash[attrs.map { |a| [a, nil] }]
|
443
|
+
else
|
444
|
+
serialized_attributes
|
445
|
+
end
|
431
446
|
|
432
447
|
array_of_attributes = models.map do |model|
|
433
448
|
column_names.map do |name|
|
434
|
-
|
435
|
-
|
449
|
+
if stored_attrs.key?(name.to_sym) ||
|
450
|
+
serialized_attrs.key?(name) ||
|
451
|
+
default_values.key?(name.to_s)
|
436
452
|
model.read_attribute(name.to_s)
|
437
453
|
else
|
438
454
|
model.read_attribute_before_type_cast(name.to_s)
|
data/test/import_test.rb
CHANGED
@@ -692,6 +692,16 @@ describe "#import" do
|
|
692
692
|
assert_equal(data.as_json, Widget.find_by_w_id(9).json_data)
|
693
693
|
end
|
694
694
|
|
695
|
+
it "imports serialized values from saved records" do
|
696
|
+
Widget.import [:w_id, :json_data], [[1, data]]
|
697
|
+
assert_equal data.as_json, Widget.last.json_data
|
698
|
+
|
699
|
+
w = Widget.last
|
700
|
+
w.w_id = 2
|
701
|
+
Widget.import([w])
|
702
|
+
assert_equal data.as_json, Widget.last.json_data
|
703
|
+
end
|
704
|
+
|
695
705
|
context "with a store" do
|
696
706
|
it "imports serialized attributes set using accessors" do
|
697
707
|
vendors = [Vendor.new(name: 'Vendor 1', color: 'blue')]
|
@@ -273,6 +273,39 @@ def should_support_postgresql_upsert_functionality
|
|
273
273
|
end
|
274
274
|
end
|
275
275
|
|
276
|
+
context 'with :condition' do
|
277
|
+
let(:columns) { %w( id device_id alarm_type status metadata) }
|
278
|
+
let(:values) { [[99, 17, 1, 1, 'foo']] }
|
279
|
+
let(:updated_values) { [[99, 17, 1, 1, 'bar']] }
|
280
|
+
|
281
|
+
macro(:perform_import) do |*opts|
|
282
|
+
Alarm.import(
|
283
|
+
columns,
|
284
|
+
updated_values,
|
285
|
+
opts.extract_options!.merge(
|
286
|
+
on_duplicate_key_update: {
|
287
|
+
conflict_target: [:id],
|
288
|
+
condition: "alarms.metadata NOT LIKE '%foo%'",
|
289
|
+
columns: [:metadata]
|
290
|
+
},
|
291
|
+
validate: false
|
292
|
+
)
|
293
|
+
)
|
294
|
+
end
|
295
|
+
|
296
|
+
macro(:updated_alarm) { Alarm.find(@alarm.id) }
|
297
|
+
|
298
|
+
setup do
|
299
|
+
Alarm.import columns, values, validate: false
|
300
|
+
@alarm = Alarm.find 99
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'should not update fields not matched' do
|
304
|
+
perform_import
|
305
|
+
assert_equal 'foo', updated_alarm.metadata
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
276
309
|
context "with :constraint_name" do
|
277
310
|
let(:columns) { %w( id title author_name author_email_address parent_id ) }
|
278
311
|
let(:values) { [[100, "Book", "John Doe", "john@doe.com", 17]] }
|
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: 0.
|
4
|
+
version: 0.19.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zach Dennis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|