activerecord-import 0.18.3 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
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