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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 32bb7874255a2f1979d7fc370e46c9c614c362df
4
- data.tar.gz: 7b45f6b4f22e64c032d320b34fa0989af63fb4aa
3
+ metadata.gz: 9a15b84eab5c3e37adc77106a0c55a8cb030d6d3
4
+ data.tar.gz: b2cab0765b2dcb2465dd6178a767836da1b61d65
5
5
  SHA512:
6
- metadata.gz: fdba083a35bde877674eaadb6bccd5cb83d285370926ef8ca557f0fe3cef08912d011599513ef640f0e1f5bd3dcfd9d0bb0a6979040d08ae1424118035ef93b4
7
- data.tar.gz: 570dc7bb80545e93cb00114ddf2f09795b410b402e3ba5cd3c3023fc18e974b53d7fc0b78a684440707b7fc7d9163fba84ea8df077d0a7214d2b0eb0556563df
6
+ metadata.gz: c70a9f7ea0ac30697a9342d3243b459a38fc78048ee7287b4172da5353939fd4fbb73567a9ab7c79b7b0ef9e3a367b8ea9c0e6ec78c89050db36964735fc4782
7
+ data.tar.gz: 1193d03b7d5ddb8cab84110a2d34c57df9a5c6fca2d38c9967d64dd0e9573d7b3c85a88c3448b3f5a6270a6ddafc459083e5fecd2d50a26a79d7c7c50184ce3a
@@ -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
@@ -1 +1 @@
1
- gem 'activerecord', '~> 5.1.0.rc1'
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 = " ON CONFLICT "
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
- is_stored_attr = stored_attrs.any? && stored_attrs.key?(name.to_sym)
435
- if is_stored_attr || default_values[name].is_a?(Hash)
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)
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Import
3
- VERSION = "0.18.3".freeze
3
+ VERSION = "0.19.0".freeze
4
4
  end
5
5
  end
@@ -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.18.3
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-05-10 00:00:00.000000000 Z
11
+ date: 2017-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord